Upload
madeleine-ferguson
View
218
Download
3
Embed Size (px)
Citation preview
ECSE 6780- Software Engineering 1I
- 1 -HO 5
© HY 2012
Lecture 5
Formal Methods
Isn’t this really getting old?
ECSE 6780- Software Engineering 1I
- 2 -HO 5
© HY 2012
Lecture 5
Inheritance in Object Z
Before we discuss deferred refinement, we will look at the specification of a small system containing inheritance and some other system specification aspects we have not yet seen.
We will develop a small set of object structures culminating in the specification of an abstract generic stack.
ECSE 6780- Software Engineering 1I
- 3 -HO 5
© HY 2012
Lecture 5
Inheritance in Object Z
Take a simple object structure such as a stack. We should, by now, be able to
specify one using Object Z fairly
easily.
Stack [T]|max : Nitems: seq T
INITitems =< >
# items ≤ max
(items)item?: T
Push
#items < maxitems’ = <item?>^items
(items)item!: T
Pop
items ≠ < >items = <item!>^items’
Note: the operation “Top” and the history invariant have been omitted.
ECSE 6780- Software Engineering 1I
- 4 -HO 5
© HY 2012
Lecture 5
items: seq T index : N1
INIT
# items ≤ max items≠ < > index dom items
(index)n?: N1
SetIndex
(items,index)item?: T
Push
Inheritance in Object ZIndexedStack [T]
n? dom itemsindex’ = n?
#items < max items =<item!>^items’items≠ < > index’=index+1
Now let us define an “IndexedStack”.This is a stack with a curser.
|max : N
items =< >could be written with a “;” instead of “”, or on two different lines
“pop” and “top” can also be similarly written and are omitted as is the history invariant.
ECSE 6780- Software Engineering 1I
- 5 -HO 5
© HY 2012
Lecture 5
Inheritance in Object ZOr, we could do the following: index : N1
INIT
items≠ < > index dom items
(index)n?: N1
SetIndex
(index)Push
n? dom itemsindex’ = n?
items ≠ < > index’=index+1
Stack[T]
items =< >
IndexedStack [T]
ECSE 6780- Software Engineering 1I
- 6 -HO 5
© HY 2012
Lecture 5
Inheritance in Object Z
Here is an example of a “DoublePushStack”.
This is possible but inadvisable from a
software engineering principles of good
design perspective, as this is an example of
“Specification” inheritance (not
“generalization”
(items)item? :T
Push
#items < max-1items’ = <item?,item?>^items
Stack[T] redef PushDoublePushStack[T]
ECSE 6780- Software Engineering 1I
- 7 -HO 5
© HY 2012
Lecture 5
Deferred refinement was the second approach to refinement that we had set out to examine.
You will recall that in direct refinement the specification is refined into their corresponding program design in a single step; as we saw with the library example so far.
In deferred refinement, the first refinement cycle will result in a new – more explicit – specification, which is then further refined and so on, resulting in a related and provably consequent sequence of documents finally yielding an implementable design.
Deferred Refinement
ECSE 6780- Software Engineering 1I
- 8 -HO 5
© HY 2012
Lecture 5
Deferred RefinementA database check-pointing system
A database, in the most generic, is defined as a function from addresses to pages of data. We shall use this definition to commence our work.
We introduce ADDR and PAGE as types. They may be classes developed or to be developed elsewhere or basic types (probably the former). [ADDR, PAGE]
We define DATABASE as the abbreviation for all the functions from ADDR to PAGE.
DATABASE ==ADDR PAGE
ECSE 6780- Software Engineering 1I
- 9 -HO 5
© HY 2012
Lecture 5
Deferred RefinementLet us compose a system that, from the user’s viewpoint, has two versions of the database. The state space will be something like:
CheckSysworking: DATABASEbackup : DATABASE
This says that the two observations working and backup may be any databases at all and need not be related in any way. Of course we will build some relationship between them later.
Most operations affect only the working database. For example:
ECSE 6780- Software Engineering 1I
- 10 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
Ξ CheckSys
p! = working(a?)
a?: ADDRp! : PAGE
Access
This operation takes an address a? as input and produces as its output p! the page stored at that address. Neither version of the database changes.
ECSE 6780- Software Engineering 1I
- 11 -HO 5
© HY 2012
Lecture 5
CheckSys
working’= working {a? p?}backup’ = backup
Update
Deferred Refinement
It is also possible to update the working database with a new page:
a?: ADDRp? : PAGE
€
⊕
Note:Now the two versions are no longer identical – if they were at all
ECSE 6780- Software Engineering 1I
- 12 -HO 5
© HY 2012
Lecture 5
CheckSys
working’= workingbackup’ = working
CheckPointWe can “Synch” the two database copies. This is a Check Point
CheckSys
working’= backupbackup’ = backup
We can also restore the working database to its state at the last check point.
Restore
Deferred Refinement
ECSE 6780- Software Engineering 1I
- 13 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
This completes the specification! Now we commence the refinement process.
At first we might want to keep two copies of the database, so implementing the specification directly.
Experience however tells us that copying the entire database is a very expensive operation particularly if check points are taken frequently.
A better idea might be to keep one complete copy and a “delta”, a record of changes since the creation of this master copy.
ECSE 6780- Software Engineering 1I
- 14 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
The master copy is thus only a single database now:Master
master: DATABASE
The record changes made since last checkpoint is a partial function from addresses to pages: it is partial because not every page will have been updated since last checkpoint.
Changeschanges: ADDR PAGE
The concrete state space is described by putting these two parts together:
ECSE 6780- Software Engineering 1I
- 15 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
CheckSys1MasterChanges
How does this concrete state space mirror our original work?
Basically, the master database is what we described as the backup and the working database is master changes, the result of updating the master copy with the recorded changes. Let us record this in a schema:
€
⊕
ECSE 6780- Software Engineering 1I
- 16 -HO 5
© HY 2012
Lecture 5
CheckSysChecksys1
backup = masterworking= master changes
Link
€
⊕
Deferred Refinement
To remind you, the notation:
means that a function (in this case working) agrees with master everywhere except in the domain of changes, where it agrees with changes.
master changes
€
⊕
ECSE 6780- Software Engineering 1I
- 17 -HO 5
© HY 2012
Lecture 5
Deferred RefinementNow let us attempt to implement some operations:
Accessing a page at address a? should return a page from the working copy according to:
working (a?)= (master changes)(a?)
€
⊕
Recall that working is a function, and from Link we had:
working = master changes
€
⊕
So from here to a valid specification is a small step.
ECSE 6780- Software Engineering 1I
- 18 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
Ξ CheckSys1a?: ADDRp! : PAGE
Access1
p!= (master changes)(a?)
€
⊕
But we can do a little better: if a? dom changes, then:
And if a? dom changes, then
(master changes)(a?) = changes(a?)
€
⊕
(master changes)(a?) = master(a?)
€
⊕
ECSE 6780- Software Engineering 1I
- 19 -HO 5
© HY 2012
Lecture 5
Deferred RefinementSo we now know that we have a conditional: If there are no changes, we return the master, if there are changes, we update the master and then return it.
Ξ CheckSys1a?: ADDRp! : PAGEr! : REPORT
Access2
(a? dom changes p!= changes(a?) r! = ok) (a? dom changes p!= master(a?) r! = not_present)
ECSE 6780- Software Engineering 1I
- 20 -HO 5
© HY 2012
Lecture 5
Ξ CheckSys1a?: ADDRp! : PAGEr!: REPORT
Access2
((a? dom changes) ((p!= changes(a?) r! = ok)) ((a? dom changes) ((p!= master(a?) r! = not_present))
We could of course write the specification slightly differently as:
The second specification is closer to an implementation, the first closer to the logic we need to prove the correctness of our derivations later in the process. Either one would be fine.
Deferred Refinement
ECSE 6780- Software Engineering 1I
- 21 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
Ξ CheckSys1a?: ADDRp! : PAGE
Access2
GetChanges == ((((a? dom changes)) ((p!= changes)(a?)) (r! = ok )) (r! = not_present))
Observing the symmetry, we could write:
ReadMaster == ((r! = not_present) ( p!=master(a?)))
r :== REPORT
ECSE 6780- Software Engineering 1I
- 22 -HO 5
© HY 2012
Lecture 5
Deferred RefinementNow we can implement:
procedure Access(a:ADDR; p:PAGE); var r:REPORTbegin GetChange(a,p,r); if r != ok then ReadMaster(a,p);end;
Of course we now need to write GetChanges and ReadMaster, but we basically have them.
ECSE 6780- Software Engineering 1I
- 23 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
Ξ Changes
(((a? dom changes)) ( ((p!= changes)(a?)) (r! = ok )) (r! = not_present))
GetChanges
a?: ADDRp! : PAGEr!: REPORT
Directly from slide 18;
ECSE 6780- Software Engineering 1I
- 24 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
ReadMaster is simply:
Ξ Mastera?: ADDRp! : PAGE
ReadMaster
p!= master(a?)
procedure ReadMaster(a: ADDR; p: PAGE);begin p := master(a);end;
ECSE 6780- Software Engineering 1I
- 25 -HO 5
© HY 2012
Lecture 5
Deferred RefinementFor Update, we need backup’ = backup, so
master’ = backup’ = backup = master, and
working’= working {a? p?}; so we want:
Luckily, (f g) h =f (g h) So, if we let changes’ = changes {a? p?}, then:
€
⊕master’ changes’ =
€
⊕ (master changes) {a? p?}
€
⊕
€
⊕
€
⊕
€
⊕
€
⊕
€
⊕
€
⊕working’= working {a? p?} [from Update] =
€
⊕(master changes) {a? p?} [from Link]
€
⊕
€
⊕ = master (changes {a? p?}) [associativity] = master changes’ [from Update1]
€
⊕
€
⊕
€
⊕
ECSE 6780- Software Engineering 1I
- 26 -HO 5
© HY 2012
Lecture 5
Deferred RefinementSo, update1 must be:
CheckSys1
changes’= changes {a? p!}master’ = master
Update1
a?: ADDRp! : PAGE
€
⊕
Implementation left as exercise
ECSE 6780- Software Engineering 1I
- 27 -HO 5
© HY 2012
Lecture 5
Deferred RefinementSimilarly and without proof (left as an exercise);
CheckSys1
master’ = master changes changes’=
CheckPoint1
€
⊕
We can of course implement this in two functions, one perhaps called WritetoMaster(changes) and one as ResettoNull(changes)
ECSE 6780- Software Engineering 1I
- 28 -HO 5
© HY 2012
Lecture 5
Deferred RefinementWhat about the Restore function? Let us recall its specification:
CheckSys
working’= backupbackup’ = backup
Restore
We want backup’=backup; so we need master’ = master; so as in Update1, again we want:
This time, because working’ = backup and changes’ must be null,
master’ changes’ =master’
€
⊕
ECSE 6780- Software Engineering 1I
- 29 -HO 5
© HY 2012
Lecture 5
Deferred RefinementThe condition is as before:
CheckSys1
master’ = master changes’=
Restore1
We can establish this by a simple call to ResettoNull(changes)
The next phase of the development (next refinement iteration) would commence in order to decide on the concrete implementation of WritetoMaster(changes); ResettoNull(changes); GetChanges(a,p,r); etc.One set of these operate on the master part, another on changes
ECSE 6780- Software Engineering 1I
- 30 -HO 5
© HY 2012
Lecture 5
Deferred Refinement
These could form two independent modules developed independently, perhaps even by different teams.
The next iteration would require selection of data and object structures to represent the various operations, perhaps for instance for master, we choose an array, or maybe a linked list of pages stored on secondary storage, and changes may be a hash table held in main memory. Of course these accesses need to be written.
They are not as hard as they seem.