VDM-SL Case Study Learning Outcomes At the end of this lecture you should be able to: Analyse and...
-
Upload
rudolph-augustine-lawson -
Category
Documents
-
view
214 -
download
0
Transcript of VDM-SL Case Study Learning Outcomes At the end of this lecture you should be able to: Analyse and...
VDM-SL Case Study
Learning Outcomes
At the end of this lecture you should be able to:
• Analyse and informally specify a complete system using UML class diagrams;
• Develop a formal VDM specification from an informal UML specification.
• Rigorously interrogate a formal specification
The Requirements Definition
The software is expected to be able to do the following:
• create a new account;
• remove an existing account;
• record a deposit transaction;
• record a withdrawal transaction;
• update the personal details (name, address and so on) of a customer's account;
• change the overdraft limit associated with an account;
• produce a statement of transactions associated with an account;
• display the balance of an account;
• display the personal details of an account.
The UML specification
AccountSys
accounts : Account [*]
addAccount (AccNum, Details, Real)removeAccount (AccNum)deposit(AccNum, Date, Real)withdraw(AccNum, Date, Real)changeDetails(AccNum, Details)changeLimit(AccNum, Real)getAllTransactions(AccNum) : Transaction [*]getBalance(AccNum): RealgetAccount(AccNum) : AccountgetDetails(AccNum) : Details getLimit(AccNum): RealgetAllAccounts() : Account [*] contains(AccNum) : BooleanisEmpty() : BooleangetTotal() : Integer
Additional types: The Account type
Account
number: AccNumdetails : Detailsbalance: Reallimit : Realtransactions: Transaction [*]
Additional types: The Transaction type
Transaction
date: Datetype: TransactionTypeamount: Real
Additional types: The TransactionType type
<<enumeration>>TransactionType
withdrawaldeposit
Formally specifying the types in VDM-SL:
types
AccNum = TOKEN
Date = TOKEN
Details = TOKEN
TransactonType = < withdrawal >|< deposit >
Formally specifying the types in VDM-SL:
Transaction :: date : Date
amount : transactionType : TransactionType
inv mk-Transaction(-,a,-) a > 0
Formally specifying the types in VDM-SL:
Account :: number : AccNumdetails : Detailsbalance : limit : transactions : Transaction*
inv mk-Account(-,-,b,l,t) l ≥ 0
b ≥ -l
balanceOf(t) = b
limit is non-negative
balance within limit
balance matches transactions
Formally specifying the state in VDM-SL
state AccountSys of
accounts : m
inv mk-AccountSys(a) account numbers in domain also in range
AccountAccNum
init mk-AccountSys(a) a = { }
end
num dom a num = a(num).number
Auxiliary functions: balanceOf
balanceOf( transIn : Transactions* ) total :
pre true
post let dep = [ transIn(i).amount | i inds transIn
transIn(i).transactionType = <deposit> ]
in let withd = [ transIn(i).amount | i inds transIn
transIn(i).transactionType = <withdrawal> ]
in total = sum(dep) - sum(withd)
??
?
??
?
?
? ?
true
Auxiliary functions: sum
sum : *
sum(seqIn) if seqIn = [ ]
then 0
else hd seqIn + sum(tl seqIn)
Operation specifications: addAccount
addAccount( )
ext
pre
post
numberIn : AccNum, detailsIn : Details, limitIn :
m AccountAccNumwr
{numberIn mk-Account(numberIn, detailsIn, 0, limitIn, []}
accounts = accounts
numberIn dom accounts limitIn 0
accounts:
Operation specifications: removeAccount
removeAccount( )
ext
pre
post
numberIn : AccNum
m AccountAccNumwr
accounts = {numberIn } accounts
numberIn dom accounts
accounts:
Operation specifications: deposit
deposit( )
ext
pre
post
numberIn : AccNum, dateIn : Date, amountIn :
m AccountAccNumwr
let bal = ( (numberIn)).balance accounts
in let trans = ( (numberIn)).transactions accountsin let newTrans = mk-Transaction(dateIn, amountIn,< deposit>)
in accounts = † {numberIn accounts
accounts( (numberIn),
balance bal + amountIn, transactions trans ^ [newTrans])}
numberIn dom accounts amountIn > 0
accounts:
Operation specifications: withdraw
withdraw( )
ext
pre
post
numberIn : AccNum, dateIn : Date, amountIn :
m AccountAccNumwr
let bal = ( (numberIn)).balance accounts
in let trans = ( (numberIn)).transactions accountsin let newTrans = mk-Transaction(dateIn, amountIn,< withdrawal>)
in accounts = † {numberIn accounts
accounts( (numberIn),
balance bal - amountIn, transactions trans ^ [newTrans])}
numberIn dom accounts amountIn > 0
(accounts(numberIn)).balance - amountIn ≥ - (accounts(numberIn)).limit
accounts:
Operation specifications: changeDetails
changeDetails( )
ext
pre
post
numberIn : AccNum, detailsIn : Details
m AccountAccNumwr
accounts = † {numberIn
( (numberIn), details detailsIn)}
accounts
accounts
numberIn dom accounts
accounts:
Operation specifications: changeLimit
changeLimit( )
ext
pre
post
numberIn : AccNum, limitIn :
m AccountAccNumwr
accounts = † {numberIn
( (numberIn), limit limitIn)}
accounts
accounts
numberIn dom accounts limitIn 0
accounts(numberIn).balance - limitIn
accounts:
Operation specifications: getDetails
getDetails( )
ext
pre
post
numberIn : AccNum detailsOut : Details
m AccountAccNumrd
detailsOut = (accounts(numberIn)).details
numberIn dom accounts
accounts:
Operation specifications: getBalance
getBalance( )
ext
pre
post
numberIn : AccNum balanceOut :
m AccountAccNumrd
balanceOut = (accounts(numberIn)).balance
numberIn dom accounts
accounts:
Operation specifications: getLimit
getLimit( )
ext
pre
post
numberIn : AccNum limitOut :
m AccountAccNumrd
limitOut = (accounts(numberIn)).limit
numberIn dom accounts
accounts:
Operation specifications: getAllTransactions
getAllTransactions( )
ext
pre
post
numberIn : AccNum transactionsOut : Transaction*
m AccountAccNumrd
transactionsOut = (accounts(numberIn)).transactions
numberIn dom accounts
accounts:
Operation specifications: contains
contains( )
ext
pre
post
numberIn : AccNum query :
m AccountAccNumrd
query numberIn dom accounts
TRUE
accounts:
Operation specifications: isEmpty
isEmpty( )
ext
pre
post
query : m AccountAccNumrd
query accounts = { }
TRUE
accounts:
Operation specifications: getTotal
getTotal( )
ext
pre
post
totalOut :
m AccountAccNumrd
totalOut = card dom accounts
TRUE
accounts:
Rigorously checking specifications
One of the advantages of formal specifications is that they can ‘tested’ before an implementation is developed.
Informal Specification
Formal Specification
CODE CODETest
Test
“If I create a new account with an overdraft limit of £200, I will not be allowed to withdraw £300 until after more money has been deposited.”
Example
addAccount (AccNum, Details, Real)removeAccount (AccNum)deposit(AccNum, Date, Real)withdraw(AccNum, Date, Real)changeDetails(AccNum, Details)changeLimit(AccNum, Real)getAllTransactions(AccNum) : Transaction [*]getBalance(AccNum): RealgetAccount(AccNum) : AccountgetDetails(AccNum) : Details getLimit(AccNum): RealgetAllAccounts() : Account [*] contains(AccNum) : BooleanisEmpty() : BooleangetTotal() : Integer
“If I create a new account with an overdraft limit of £200, I will not be allowed to withdraw £300 until after more money has been deposited.”
Example
addAccount ( AccNum, Details , Real ) ;
withdraw( AccNum , Date , Real );
001 200
001 300
addAccount( )
ext
pre
post
numberIn : AccNum, detailsIn : Details, limitIn :
m AccountAccNumwr
{ numberIn mk-Account( numberIn , detailsIn , 0, limitIn , []}
accounts = accounts
numberIn dom accounts limitIn 0
accounts:
withdraw( )
ext
pre
numberIn : AccNum, dateIn : Date, amountIn :
m AccountAccNumwr
numberIn dom accounts amountIn > 0
(accounts(numberIn)).balance - amountIn ≥ - (accounts(numberIn)).limit
accounts:
001
001 001 200
001
001 001
300
300
200