"System Validation" (Project Report) : Submitted To: Submitted by

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 11

“SYSTEM VALIDATION”

(PROJECT REPORT)

SUBMITTED TO: Dr. OSMAN HASSAAN


SUBMITTED BY: Muhammad Umair Ali (170824)
Muhammad Usman Ali (171190)
Hassaan Rauf (172518)

(MSEE-8-DSSP)
ATM model using NuSMV
NuSMV:

NuSMV is a re-implementation and extension of SMV (symbolic model verifier). It is an open source
model checking tool, the first model checker based on Binary decision diagrams (BDDs). It has been
designed to be an open architecture for model checking, which can be reliably used for the
verification of industrial designs, as a core for custom verification tools, and as a test for formal
verification techniques. It provides a language for describing the models, also directly checks the
validity of LTL (linear Temporal Logic).

NuSMV version 2 extends NuSMV with new model checking algorithms and techniques. It combines
classical BDD-based symbolic techniques with SAT based techniques. It also presents other new
features: for instance, it allows for a more powerful manipulation of multiple models; it can generate
flat models for the whole language.

ATM:
ATMs (Automatic Teller Machines) are the most commonly used banking technology. The main
operations of ATMs include balance and transaction enquiries, withdrawals, deposits and account
transfers. In our project, we have simplified the model, and reduced the types of transactions to just
withdrawal, PIN verification and balance maintaining for the sake of validation and in order to have a
smaller number of states.

Proposed Model of ATM


Modules:

The model will have three modules proposed for the model

1. Cardholder

2. ATM

3. Bank server

Cardholder will act as the input generator for ATM. ATM will process the inputs, and accordingly communicate
with Bank Server that will act as information source and make decisions. Individually, the communication
between the all three modules will happen with ATM acting as the channel and communicating with both bank
server and card holder through variables.
ATM:

ATM will give an option to login (through card and PIN insertion), perform a transaction (by
connecting card holder input with bank server) or stay idle.

ATM will be locked if wrong PIN is entered three times after card insertion

For both validation of PIN and transaction, ATM will ask bank server for verification.

Bank Server:

Bank server is the banking server at the back end of the ATM. After cardholder insert the card into the
ATM and enters the valid pin number. ATM send request to the banking server to link and details of
the account of the card holder. After the account verification server links backs to the ATM which
performs the transactions desired by the cardholder.

Bank server will have bank balances of all card holders.

It will wait until ATM requests some action. In case of a request, it will either tell the ATM whether its
valid or invalid.

In case of transactions (withdrawals), it


will check the past balance and if
transaction is possible it will perform
withdrawal and subtract the amount
withdrawn.

Encryption and channel noise is not


modeled in the research paper so it is not
considered

Flow Diagram:

Consider the image on the right. It


depicts a single path that the states can
take, although the details of variables
such as cardholder are not included.

After LOGOUT, the flow continues for as


long as the simulation runs, but only upto
that point is shown.
NuSMV Modelling:
MODULE card_holder (atm_state)

VAR
input: {IDLE,CARD_INSERT,PINi,TRANSACTION,LOGOUT};
cardholder : {0,1,2,3,4,5};
trans_amount : 0 .. 100;

ASSIGN
init(input) := IDLE;
init(cardholder) := 0;
init(trans_amount) := 0;

next(trans_amount) := case
(next(input) = TRANSACTION)&(input != TRANSACTION): 1 .. 100;
TRUE: trans_amount;
esac;

next(input) := case
(cardholder != 0)&(input = IDLE) & (atm_state = IDLE) : {IDLE,CARD_INSERT};
(cardholder != 0)&(input = IDLE) & (atm_state = CARD_INSRT) : {IDLE,PINi};
(cardholder != 0)&(input = IDLE) & (atm_state = LOGGED_IDLE) :
{IDLE,TRANSACTION,LOGOUT};
TRUE : IDLE;
esac;

next(cardholder) := case
(cardholder = 0) & (atm_state = IDLE) : {0,1,2,3,4,5};
(atm_state = LOGOUT) : 0;
(atm_state = LOCKED) : 0;
TRUE : cardholder;
esac;

LTLSPEC G((input = TRANSACTION) -> !F (input = LOGOUT))


FAIRNESS (input = IDLE)

MODULE atm (card_holder_input,input_amount,bank_response)


VAR
req_type : {PINr,TRANSACTION,UNLOCKa,0};
ATM_state :
{RESET,PINa,LOGGED_IDLE,TRANSACTIONa,LOGOUT,IDLE,CARD_INSRT,LOCKED,DISP_ERR};
tries : {0,1,2,3};
withdraw_amount : 0 .. 100;

ASSIGN
init(ATM_state) := IDLE;
init(tries) := 0;
init(req_type) := 0;
init(withdraw_amount) := 0;

next(req_type) := case
(next(ATM_state) = PINa): PINr;
(next(ATM_state) = TRANSACTIONa): TRANSACTION;
(ATM_state = LOCKED): {UNLOCKa,0};
TRUE : 0;
esac;

next(tries) := case
(ATM_state = PINa)&(bank_response = INVALID)&(tries = 0) : 1;
(ATM_state = PINa)&(bank_response = INVALID)&(tries = 1) : 2;
(ATM_state = PINa)&(bank_response = INVALID)&(tries = 2) : 3;
(ATM_state = RESET)|(ATM_state = LOGOUT)|(ATM_state = IDLE) : 0;
TRUE : tries;
esac;

next(ATM_state) := case
(ATM_state = RESET): IDLE;
(ATM_state = LOGOUT): IDLE;
(ATM_state = DISP_ERR): IDLE;

(ATM_state = LOCKED)&(bank_response != UNLOCK): LOCKED;


(ATM_state = LOCKED)&(bank_response = UNLOCK): IDLE;

(ATM_state = IDLE)&(card_holder_input = CARD_INSERT) : CARD_INSRT;

(ATM_state = CARD_INSRT) & (tries = 3): LOCKED;


(ATM_state = CARD_INSRT) & (card_holder_input = PINi) : PINa;
(ATM_state = CARD_INSRT) : CARD_INSRT;

(ATM_state = PINa) & (bank_response = NULL) : ATM_state;


(ATM_state = PINa) & (bank_response = INVALID): CARD_INSRT;
(ATM_state = PINa) & (bank_response = VALID): LOGGED_IDLE;

(ATM_state = LOGGED_IDLE) & (card_holder_input != LOGOUT)&(card_holder_input !


= TRANSACTION): LOGGED_IDLE;
(ATM_state = LOGGED_IDLE) & (card_holder_input = TRANSACTION): TRANSACTIONa;
(ATM_state = LOGGED_IDLE) & (card_holder_input = LOGOUT): LOGOUT;

(ATM_state = TRANSACTIONa) & (bank_response = NULL) : ATM_state;


(ATM_state = TRANSACTIONa) & (bank_response = INVALID): DISP_ERR;
(ATM_state = TRANSACTIONa) & (bank_response = VALID): LOGGED_IDLE;
TRUE : ATM_state;
esac;

next(withdraw_amount) := case
(next(ATM_state) = TRANSACTIONa) & (ATM_state != TRANSACTIONa): input_amount;
(ATM_state = TRANSACTIONa) : withdraw_amount;
TRUE : 0;
esac;

LTLSPEC G((ATM_state = LOCKED) -> G (ATM_state = LOCKED))


LTLSPEC !G((ATM_state = LOCKED) -> G (ATM_state = LOCKED))

MODULE bank_server(request,amount,cardholder)
VAR
response: {VALID,INVALID,UNLOCK,NULL};
bank_balance_1 : 0 .. 100;
bank_balance_2 : 0 .. 100;
bank_balance_3 : 0 .. 100;
bank_balance_4 : 0 .. 100;
bank_balance_5 : 0 .. 100;

ASSIGN
init(response) := NULL;
init(bank_balance_1) := 70 .. 100;
init(bank_balance_2) := 30 .. 80;
init(bank_balance_3) := 10 .. 40;
init(bank_balance_4) := 90 .. 100;
init(bank_balance_5) := 50 .. 75;

next(response) := case
(request = PINr)&(response = NULL) : {INVALID,VALID};
(request = UNLOCKa)&(response = NULL) : {UNLOCK,NULL};
(request = TRANSACTION)&(bank_balance_1>amount)&(cardholder=1)&(response = NULL) :
VALID;
(request = TRANSACTION)&(bank_balance_2>amount)&(cardholder=2)&(response = NULL) :
VALID;
(request = TRANSACTION)&(bank_balance_3>amount)&(cardholder=3)&(response = NULL) :
VALID;
(request = TRANSACTION)&(bank_balance_4>amount)&(cardholder=4)&(response = NULL) :
VALID;
(request = TRANSACTION)&(bank_balance_5>amount)&(cardholder=5)&(response = NULL) :
VALID;

(request = TRANSACTION)&(amount>bank_balance_1)&(cardholder=1)&(response = NULL) :


INVALID;
(request = TRANSACTION)&(amount>bank_balance_2)&(cardholder=2)&(response = NULL) :
INVALID;
(request = TRANSACTION)&(amount>bank_balance_3)&(cardholder=3)&(response = NULL) :
INVALID;
(request = TRANSACTION)&(amount>bank_balance_4)&(cardholder=4)&(response = NULL) :
INVALID;
(request = TRANSACTION)&(amount>bank_balance_5)&(cardholder=5)&(response = NULL) :
INVALID;
TRUE : NULL;
esac;

next(bank_balance_1) := case
(request = TRANSACTION)&(next(response)=VALID & (bank_balance_1 >
amount))&(cardholder=1) : bank_balance_1 - amount;
TRUE : bank_balance_1;
esac;

next(bank_balance_2) := case
(request = TRANSACTION)&(next(response)=VALID & (bank_balance_2 >
amount))&(cardholder=2) : bank_balance_2 - amount;
TRUE : bank_balance_2;
esac;

next(bank_balance_3) := case
(request = TRANSACTION)&(next(response)=VALID & (bank_balance_3 >
amount))&(cardholder=3) : bank_balance_3 - amount;
TRUE : bank_balance_3;
esac;

next(bank_balance_4) := case
(request = TRANSACTION)&(next(response)=VALID & (bank_balance_4 >
amount))&(cardholder=4) : bank_balance_4 - amount;
TRUE : bank_balance_4;
esac;

next(bank_balance_5) := case
(request = TRANSACTION)&(next(response)=VALID & (bank_balance_5 >
amount))&(cardholder=5) : bank_balance_5 - amount;
TRUE : bank_balance_5;
esac;

LTLSPEC G((request = TRANSACTION)&(cardholder=1)& (X response = VALID) ->


(bank_balance_1<amount));

MODULE main
VAR
running : boolean;
CH_inst: card_holder(atm_inst.ATM_state);
atm_inst: atm(CH_inst.input,CH_inst.trans_amount,bank_inst.response);
bank_inst:
bank_server(atm_inst.req_type,atm_inst.withdraw_amount,CH_inst.cardholder);
FAIRNESS running

LTLSPECS:

NuSMV gives an option to check given specifications by checking N depth/cycles of all states. When
states are too many, NuSMV can get stuck processing. In order to circumvent the problem, we can
check for inverse logic to get establish some level of validity. The following properties are therefore
constructed to output as false, while showing the counter examples for each property. In addition,
they that the inverse of the properties is therefore true.

 User will not logout at some point after a transaction

LTLSPEC G((input = TRANSACTION) -> !F (input = LOGOUT))

 ATM once locked, will always stay locked

LTLSPEC G((ATM_state = LOCKED) -> G (ATM_state = LOCKED))

 A valid transaction implies that amount withdrawn is greater than bank balance

LTLSPEC G((request = TRANSACTION)&(cardholder=1)& (X response = VALID) ->


(bank_balance_1<amount));

The following are the outputs from counter-examples that are generated from above when check to a
max depth of 30.
NuSMV > check_ltlspec_bmc -k 30 -l *
-- no counterexample found with bound 0
-- no counterexample found with bound 1
-- no counterexample found with bound 2
-- no counterexample found with bound 3
-- no counterexample found with bound 4
-- no counterexample found with bound 5
-- no counterexample found with bound 6
-- no counterexample found with bound 7
-- no counterexample found with bound 8
-- no counterexample found with bound 9
-- no counterexample found with bound 10
-- no counterexample found with bound 11
-- no counterexample found with bound 12
-- no counterexample found with bound 13
-- no counterexample found with bound 14
-- specification G (input = TRANSACTION -> !( F input = LOGOUT)) IN CH_inst is false
-- as demonstrated by the following execution sequence
Trace Description: BMC Counterexample
Trace Type: Counterexample
-> State: 1.1 <-
running = FALSE
CH_inst.input = IDLE
CH_inst.cardholder = 0
CH_inst.trans_amount = 0
atm_inst.req_type = 0
atm_inst.ATM_state = IDLE
atm_inst.tries = 0
atm_inst.withdraw_amount = 0
bank_inst.response = NULL
bank_inst.bank_balance_1 = 100
bank_inst.bank_balance_2 = 66
bank_inst.bank_balance_3 = 22
bank_inst.bank_balance_4 = 96
bank_inst.bank_balance_5 = 70
-> State: 1.2 <-
CH_inst.cardholder = 2
-> State: 1.3 <-
CH_inst.input = CARD_INSERT
-> State: 1.4 <-
CH_inst.input = IDLE
atm_inst.ATM_state = CARD_INSRT
-> State: 1.5 <-
CH_inst.input = PINi
-> State: 1.6 <-
CH_inst.input = IDLE
atm_inst.req_type = PINr
atm_inst.ATM_state = PINa
-> State: 1.7 <-
bank_inst.response = VALID
-> State: 1.8 <-
atm_inst.req_type = 0
atm_inst.ATM_state = LOGGED_IDLE
bank_inst.response = NULL
-> State: 1.9 <-
CH_inst.input = TRANSACTION
CH_inst.trans_amount = 2
-> State: 1.10 <-
CH_inst.input = IDLE
atm_inst.req_type = TRANSACTION
atm_inst.ATM_state = TRANSACTIONa
atm_inst.withdraw_amount = 2
-> State: 1.11 <-
bank_inst.response = VALID
bank_inst.bank_balance_2 = 64
-> State: 1.12 <-
atm_inst.req_type = 0
atm_inst.ATM_state = LOGGED_IDLE
bank_inst.response = NULL
-> State: 1.13 <-
CH_inst.input = LOGOUT
atm_inst.withdraw_amount = 0
-> State: 1.14 <-
CH_inst.input = IDLE
atm_inst.ATM_state = LOGOUT
-- Loop starts here
-> State: 1.15 <-
running = TRUE
CH_inst.cardholder = 0
atm_inst.ATM_state = IDLE
-> State: 1.16 <-
-- no counterexample found with bound 0
-- no counterexample found with bound 1
-- no counterexample found with bound 2
-- no counterexample found with bound 3
-- no counterexample found with bound 4
-- no counterexample found with bound 5
-- no counterexample found with bound 6
-- no counterexample found with bound 7
-- no counterexample found with bound 8
-- no counterexample found with bound 9
-- no counterexample found with bound 10
-- no counterexample found with bound 11
-- no counterexample found with bound 12
-- no counterexample found with bound 13
-- no counterexample found with bound 14
-- no counterexample found with bound 15
-- no counterexample found with bound 16
-- no counterexample found with bound 17
-- no counterexample found with bound 18
-- no counterexample found with bound 19
-- specification G (ATM_state = LOCKED -> G ATM_state = LOCKED) IN atm_inst is false
-- as demonstrated by the following execution sequence
Trace Description: BMC Counterexample
Trace Type: Counterexample
-- Loop starts here
-> State: 2.1 <-
running = FALSE
CH_inst.input = IDLE
CH_inst.cardholder = 0
CH_inst.trans_amount = 0
atm_inst.req_type = 0
atm_inst.ATM_state = IDLE
atm_inst.tries = 0
atm_inst.withdraw_amount = 0
bank_inst.response = NULL
bank_inst.bank_balance_1 = 96
bank_inst.bank_balance_2 = 64
bank_inst.bank_balance_3 = 32
bank_inst.bank_balance_4 = 96
bank_inst.bank_balance_5 = 64
-> State: 2.2 <-
CH_inst.cardholder = 2
-> State: 2.3 <-
CH_inst.input = CARD_INSERT
-> State: 2.4 <-
CH_inst.input = IDLE
atm_inst.ATM_state = CARD_INSRT
-> State: 2.5 <-
CH_inst.input = PINi
-> State: 2.6 <-
CH_inst.input = IDLE
atm_inst.req_type = PINr
atm_inst.ATM_state = PINa
-> State: 2.7 <-
bank_inst.response = INVALID
-> State: 2.8 <-
atm_inst.req_type = 0
atm_inst.ATM_state = CARD_INSRT
atm_inst.tries = 1
bank_inst.response = NULL
-> State: 2.9 <-
CH_inst.input = PINi
-> State: 2.10 <-
CH_inst.input = IDLE
atm_inst.req_type = PINr
atm_inst.ATM_state = PINa
-> State: 2.11 <-
bank_inst.response = INVALID
-> State: 2.12 <-
atm_inst.req_type = 0
atm_inst.ATM_state = CARD_INSRT
atm_inst.tries = 2
bank_inst.response = NULL
-> State: 2.13 <-
CH_inst.input = PINi
-> State: 2.14 <-
CH_inst.input = IDLE
atm_inst.req_type = PINr
atm_inst.ATM_state = PINa
-> State: 2.15 <-
bank_inst.response = INVALID
-> State: 2.16 <-
atm_inst.req_type = 0
atm_inst.ATM_state = CARD_INSRT
atm_inst.tries = 3
bank_inst.response = NULL
-> State: 2.17 <-
CH_inst.input = PINi
atm_inst.ATM_state = LOCKED
-> State: 2.18 <-
CH_inst.input = IDLE
CH_inst.cardholder = 0
atm_inst.req_type = UNLOCKa
-> State: 2.19 <-
bank_inst.response = UNLOCK
-> State: 2.20 <-
running = TRUE
atm_inst.ATM_state = IDLE
bank_inst.response = NULL
-> State: 2.21 <-
running = FALSE
atm_inst.req_type = 0
atm_inst.tries = 0
-- no counterexample found with bound 0
-- specification !( G (ATM_state = LOCKED -> G ATM_state = LOCKED)) IN atm_inst is false
-- as demonstrated by the following execution sequence
Trace Description: BMC Counterexample
Trace Type: Counterexample
-- Loop starts here
-> State: 3.1 <-
running = TRUE
CH_inst.input = IDLE
CH_inst.cardholder = 0
CH_inst.trans_amount = 0
atm_inst.req_type = 0
atm_inst.ATM_state = IDLE
atm_inst.tries = 0
atm_inst.withdraw_amount = 0
bank_inst.response = NULL
bank_inst.bank_balance_1 = 80
bank_inst.bank_balance_2 = 40
bank_inst.bank_balance_3 = 40
bank_inst.bank_balance_4 = 96
bank_inst.bank_balance_5 = 56
-> State: 3.2 <-
-- no counterexample found with bound 0
-- no counterexample found with bound 1
-- no counterexample found with bound 2
-- no counterexample found with bound 3
-- no counterexample found with bound 4
-- no counterexample found with bound 5
-- no counterexample found with bound 6
-- no counterexample found with bound 7
-- no counterexample found with bound 8
-- no counterexample found with bound 9
-- no counterexample found with bound 10
-- no counterexample found with bound 11
-- no counterexample found with bound 12
-- specification G (((request = TRANSACTION & cardholder = 1) & X response = VALID) ->
bank_balance_1 < amount) IN bank_inst is false
-- as demonstrated by the following execution sequence
Trace Description: BMC Counterexample
Trace Type: Counterexample
-> State: 4.1 <-
running = FALSE
CH_inst.input = IDLE
CH_inst.cardholder = 0
CH_inst.trans_amount = 0
atm_inst.req_type = 0
atm_inst.ATM_state = IDLE
atm_inst.tries = 0
atm_inst.withdraw_amount = 0
bank_inst.response = NULL
bank_inst.bank_balance_1 = 80
bank_inst.bank_balance_2 = 64
bank_inst.bank_balance_3 = 13
bank_inst.bank_balance_4 = 96
bank_inst.bank_balance_5 = 64
-> State: 4.2 <-
CH_inst.cardholder = 1
-> State: 4.3 <-
CH_inst.input = CARD_INSERT
-> State: 4.4 <-
CH_inst.input = IDLE
atm_inst.ATM_state = CARD_INSRT
-> State: 4.5 <-
CH_inst.input = PINi
-> State: 4.6 <-
CH_inst.input = IDLE
atm_inst.req_type = PINr
atm_inst.ATM_state = PINa
-> State: 4.7 <-
bank_inst.response = VALID
-> State: 4.8 <-
atm_inst.req_type = 0
atm_inst.ATM_state = LOGGED_IDLE
bank_inst.response = NULL
-> State: 4.9 <-
CH_inst.input = TRANSACTION
CH_inst.trans_amount = 8
-> State: 4.10 <-
CH_inst.input = IDLE
atm_inst.req_type = TRANSACTION
atm_inst.ATM_state = TRANSACTIONa
atm_inst.withdraw_amount = 8
-> State: 4.11 <-
bank_inst.response = VALID
bank_inst.bank_balance_1 = 72
-> State: 4.12 <-
atm_inst.req_type = 0
atm_inst.ATM_state = LOGGED_IDLE
bank_inst.response = NULL
-- Loop starts here
-> State: 4.13 <-
running = TRUE
atm_inst.withdraw_amount = 0
-> State: 4.14 <-

You might also like