Transcript Slide 1

Sequences
At the end of this lecture you should be able to:
•
provide a definition of a VDM sequence;
•
utilize and interpret sequence notation;
•
make appropriate use of the VDM sequence operators;
•
define a sequence by comprehension;
•
identify situations in which a sequence is an appropriate
data type;
•
write VDM specifications using the sequence type.
Introduction
A sequence is an ordered collection of objects;
In a sequence, repetitions are significant.
Examples
The queue of patients waiting for a doctor.
Planes circling an airport.
Notation
A sequence is specified by enclosing its members in square
brackets;
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
[ a, d, f ]  [ a, f, d ]
[ ]
Retrieving items from the sequence
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
s(3) =
f
queue(4) = winston
s(10) =
undefined
Sequence operators
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
len operator:
Returns the length of a sequence
len s = 7
len queue = 5
Sequence operators
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
elems operator:
elems s =
Returns a set that contains all
the members of the sequence
{ a, d, f, c }
elems queue = {michael, varinder, elizabeth, winston, judith}
Sequence operators
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
inds operator :
Returns a set of all the indices
of the sequence
inds s = {1, 2, 3, 4, 5, 6, 7 }
inds queue = {1, 2, 3, 4, 5}
inds [] =
{}
Sequence operators
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
head (hd) operator :
hd s =
a
hd queue = michael
hd [] =
undefined
Returns the first element in
the sequence
Sequence operators
s = [ a, d, f, a, d, d, c ]
queue = [ michael, varinder, elizabeth, winston, judith ]
tail (tl) operator :
tl s =
[d, f, a, d, d, c ]
tl queue =
tl [] =
Returns a sequence containing
all but the first element
[varinder, elizabeth, winston, judith ]
undefined
tl [a] = [ ]
Sequence operators
first = [ w, e, r, w ]
second = [ t, w, q ]
concatenation operator ( ^ ) operator:
operates on two sequences, and returns a sequence that consists
of the two sequences joined together
first ^ second =
[ w, e, r, w, t, w, q ]
second ^ first =
[t, w, q, w, e, r, w ]
first ^ [ ] =
[ w, e, r, w ]
Sequence operators
the override operator (†)
Takes a sequence and gives us a new sequence with a
particular element of the old sequence overridden by a new
element
[a, c, d, e] † {1  z} =
[z, c, d, e]
[a, c, d, e] † {2  x, 4  y} = [a, x, d, y]
[a, c, d, e] † {7  g} =
undefined
Sequence operators
subsequence operator
allow us to extract a part of a sequence between
two indices
s = [ a, d, f, a, d, d, c ]
s(2, ... , 5) = [d, f, a, d]
s(2, ... , 2) = [d]
s(1, ... ,0) = [ ]
s(2, ... , 13) = undefined
s(8, ... , 7) = [ ]
Sequence by comprehension
[ expression(a) | a  SomeSet  test (a) ]
[ a | a  {1,…,10}  is-odd(a)]
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
s1 = [2, 3, 4, 7, 9, 11, 6, 7, 8, 14, 39, 45, 3]
s2 = [ s1(i) | i  inds s1  s1(i) > 10]
[11, 14, 39, 45]
Using the sequence type in VDM-SL
To declare a variable to be of type sequence we place an asterisk
after the name of the type contained within the sequence.
seq : *
convoy : SpaceCraft *
Specifying a stack
Stack
stack : Element[*]
push(Element)
pop() : Element
isEmpty(): Boolean
Specifying the state of the stack
types
Element = TOKEN
state Stack of
stack : Element*
init mk-Stack(s)  s = [ ]
end
stack
stack
The push operation
push( itemIn : Element )
ext
pre
wr stack : Element*
TRUE
post stack = [itemIn] ^ stack
stack
stack
The pop operation
pop( ) itemRemoved : Element
ext
pre
wr stack : Element*
stack  [ ]
post stack = tl stack  itemRemoved = hd stack
stack
stack
The isEmpty operation
isEmpty( ) query : 
ext
pre
rd stack : Element*
TRUE
post query  stack = [ ]
Re-thinking the Airport system
In the new system, when an aircraft approaches the airport
it is placed in a queue, and must circle the airport until a
runway becomes available;
Only aircraft that have permission to land are allowed to
circle;
The circling aircraft are landed on a first-come-first served
basis.
Re-specifying the state
types
Aircraft = TOKEN
state Airport2 of
permission: Aircraft-set
landed: Aircraft-set
circling: Aircraft*
inv mk-Airport2(p,l,c)  ?
init mk-Airport2 (p, l, c)  p = { }  l = { }  c = [ ]
end
The new invariant
inv mk-Airport2(p,l,c) 
1. Landed planes must
lhave
 permission
p
2. Circling planes must
 elems
c p
have permission
3. Circling planes can
 elems
cl=
not be landed
{}
4. All circling planes are
 isUnique(c)
unique
isUnique(seqIn : Aircraft*) query : 
pre
true
post query   i1 ,i2  inds seqIn  i1  i2  seqIn(i1)  seqIn(i2)
Re-specifying the operations
The following operations access only the permission and landed
components, and do not therefore need to be changed:
•
•
•
•
•
•
givePermission
recordTakeOff
numberWaiting
atAirport
getPermission
getLanded
The meaning of recordLanding will change in the new specification;
Two new operations are required
• getCircling
• allowToCircle
allowToCircle operation
allowToCircle ( craftIn : Aircraft )
ext wr circling : Aircraft*
rd permission : Aircraft-set
pre
rd landed : Aircraft-set
craftIn  permission
 craftIn  elems circling
 craftIn  landed
post
circling = circling ^ [craftIn]
The modified recordLanding operation
recordLanding( )
ext
wr circling : Aircraft*
wr landed : Aircraft-set
pre
circling  [ ]
post
landed = landed  {hd circling }
 circling = tl circling
Some useful functions to use with sequences
A function that returns the last element in a sequence:
last( sequenceIn : Element* ) elementOut : Element
pre
sequenceIn  [ ]
post elementOut = sequenceIn(len sequenceIn)
Some useful functions to use with sequences
A function that returns the sequence with the last element
removed.
allButLast( sequenceIn : Element* ) sequenceOut : Element*
pre
sequenceIn  [ ]
post sequenceOut = sequenceIn(1, ..., (len sequenceIn - 1))
Some useful functions to use with sequences
A find function
Returns the index of a particular element;
Assuming elements are unique:
find( sequenceIn : Element*, element : Element ) position : 
pre
element  elems sequencIn
post sequenceIn(position) = element
Some useful functions to use with sequences
A find function
Returns the index of a particular element;
Assuming elements are not unique:
find( sequenceIn : Element*, element : Element ) position : 
pre
element  elems sequencIn
post sequenceIn(position) = element
 i  inds sequenceIn  sequenceIn(i) = element position  i