1 / 33

Composite Objects

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

nirav
Download Presentation

Composite Objects

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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 : Type1 fieldname2 : Type2 :

  4. The Time Type Assume that a time value consists of an hour, minute and second value. We can define the following type: Time :: hour :  minute :  second :  This Time type can now be used like any other type in your specification 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) thisTime = mk-Time (someTime.hour, 0, 0)

  9. The surface of a disk consists of a collection of blocks tracks sector block

  10. The DiskScanner class DiskScanner damagedBlocks: Block [*] addBlock(Integer, Integer) removeBlock (Integer, Integer) isDamaged(Integer, Integer): Boolean getBadSectors(Integer): Integer [*]

  11. Analysing the Block type further A block consists of a track and a sector number. Block track: Integer sector: Integer

  12. Specifying the data model in VDM-SL types stateDiskScanner of damagedBlocks: initmk-DiskScanner (dB)  end Block : : track: sector:   Block-set dB = { }

  13. damagedBlocks =  { mk-Block (trackIn,sectorIn)} The addBlock operation addBlock ( ) ext pre post trackIn: , sectorIn:  wr damagedBlocks: Block-set mk-Block (trackIn,sectorIn) damagedBlocks

  14. damagedBlocks = \ { mk-Block (trackIn,sectorIn)} The removeBlock operation removeBlock ( ) ext pre post trackIn: , sectorIn:  wr damagedBlocks: Block-set mk-Block (trackIn,sectorIn) damagedBlocks

  15. The isDamaged operation isDamaged ( ) ext pre post trackIn: , sectorIn:  query:  rd damagedBlocks: Block-set TRUE  query mk-Block (trackIn,sectorIn) damagedBlocks

  16. The getBadSectors operation getBadSectors ( ) ext pre post trackIn:  list: -set rd damagedBlocks: Block-set TRUE bdamagedBlocks { |  } b.sector ? ? list = b.track= trackIn ?

  17. running terminated new ready blocked A process management system timeout admit terminate dispatch block wakeup

  18. The ProcessManagement class ProcessManagament running: String waiting: Process[*] admit(String) dispatch() timeOut() block() wakeUp(String) terminate()

  19. <<enumeration>> Status READY BLOCKED Process id: String status: Status Analysing the types A process consists of an id and status The status of a process is either ready or blocked.

  20. Specifying the types in VDM-SL types String = Char* Status = <READY> | <BLOCKED> : String Process :: id : Status status

  21. Specifying the state in VDM-SL stateProcessManagementof running waiting invmk-ProcessManagement (run, wait)  ( ) ( ) initmk-ProcessManagement (run, wait)  end : [String] : Process* i indswait wait(i).id = run  run = nil 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 run = nilwait = [ ]

  22. Specifying a findPos function findPos(qIn : Process*, idIn : String) pos :  prepelems qIn p.id = idIn post qIn(pos).id = idIn

  23. Specifying a findNext function qIn : Process* findNext() pre post pos :  pelems qIn p.status = <READY>  qIn(pos).status = <READY> i  {1,…,pos-1}qIn(i).status = <READY>

  24. Specifying a remove function remove(qIn : Process*, posIn : ) qOut : Process* preposIninds qIn post qOut = qIn(1,…, posIn-1) ^ qIn(posIn+1,…,len qIn)

  25. waiting = ^ [mk-Process(idIn, <READY>)] The admit operation admit( idIn: String) ext pre post waiting: Process* wr rd running: [String] (running = nilidIn running )  p elems waiting p.id idIn

  26. running = (findNext( )) .id waiting = remove( , findNext( )) The dispatch operation dispatch() ext pre post running: [String] wr wr waiting: Process* running = nil pelems waiting  p.status = <READY>

  27. waiting = ^ [mk-Process( , <READY>)] The timeOut operation timeOut() ext pre post wr running: [String] wr waiting: Process* running nil running = nil

  28. waiting = ^ [mk-Process( , <BLOCKED>)] The block operation block() ext pre post wr running: [String] wr waiting: Process* running nil running = nil

  29. waiting = † {findPos( , idIn)  mk-Process(idIn, <READY>)} The wakeUp operation wakeUp( idIn: String) ext pre post wr waiting: Process* waiting(findPos(waiting, idIn)).status = <BLOCKED>  idInelems waiting

  30. The terminate operation terminate() ext pre post running: [String] wr running nil running = nil

  31. 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 inexpression(name)

  32. postrunning = ( findNext( ) ).id waiting = remove( , findNext( )) post letnext = findNext( ) in running = ( next ) .id waiting = remove( , next) Re-writing postcondition of dispatch

  33. post waiting = † {findPos( , idIn)  mk-Process(idIn, <READY>)} post let pos = findPos( , idIn) in let wakeProcess = mk-Process(idIn, <READY>) in waiting = † {pos wakeProcess } Nested let…in clauses

More Related