LECTURE 11: Specifying Systems – State Diag’s & OCL Ivan Marsic Rutgers University Topics UML State Machine Diagrams – State Activities: Entry, Do, and Exit Activities – Composite States and Nested States – Concurrency UML Object Constraint Language (OCL) – OCL Syntax – OCL Constraints and Contracts 2 State Machine Diagram: Basic Notation States of Stock_i event Listing planned initial state trade initial-listing Traded transition indicated by bankruptcy, merger, acquisition, … Delisted terminal state indicated by These are not states: They are only labels that indicate the actual initial/terminal states 3 UML Diagrams Differ from FSMs Modularization of states Concurrent behaviors State activities 4 States of Stock_i trade Listing planned bankruptcy, merger, acquisition, … initial-listing Traded Delisted composite state Traded Listing planned Buy Hold Delisted Sell sub-states: (based on analyst recommendations) trade trade trade trade Buy trade Hold trade Sell trade 5 trade States of Stock_i trade IPO planned initial-listing bankruptcy, acquisition, merger, … Traded Delisted IPO = initial public offering Traded trade IPO planned initiallisting trade trade trade Buy trade Hold trade composite state nested state Sell bankruptcy, acquisition, merger, … Delisted trade trade 6 State Activities: Entry, Do, and Exit Activities States of a Trading Order completion transition view Pending submit InPreparation do: check_price & supply [buy] check_price & demand [sell] matched Executed Archived cancel, reject data entry trade “do” state activity Cancelled (order placed and waiting for the specified market conditions) 7 State Diagram for Controller [ Recall Section 2.7.4: Test Coverage and Code Coverage ] How state diagram motivates you to consider alternative usage scenarios and provides “crutches”: User leaves without succeeding or blocking invalid-key [numOfAttemps maxNumOfAttempts] / signal-failure invalid-key / signal-failure Accepting Locked invalid-key [numOfAttemps maxNumOfAttempts] / sound-alarm timer-expired / signal-reset, set numOfAttemps := 0 autoLockInterval -expired / valid-key / signal-success valid-key / signal-success, set numOfAttemps := 0 Blocked Unlocked Auto-locking feature not shown! Note how the object responds differently to the same event (invalid-key in Accepting state), depending on which events preceded it 8 State Diagram for Controller invalid-key [numOfAttemps maxNumOfAttempts] / signal-failure invalid-key / signal-failure Accepting Locked timer-expired / signal-reset, set numOfAttemps := 0 invalid-key [numOfAttemps maxNumOfAttempts] / sound-alarm entry: start timer do: countdown autoLockInterval -expired / valid-key / signal-success valid-key / signal-success Blocked Unlocked entry: start timer do: countdown Need “entry” and “do” state activities for countdown timers 9 State “Accepting” Refined Accepting timer-expired / signal-reset, set numOfAttemps := 0 invalid-key / signal-failure invalid-key / signal-failure One valid-key / signal-success invalid-key / signal-failure Two valid-key / signal-success invalid-key / sound-alarm MaxNumOfAttempts valid-key / signal-success Or, get rid of state “Accepting” and introduce state “Zero” … 10 Problem: States of a Hotel Room Problem: make-reservation / Reserved Vacant - but a guest may be occupying the room while it is reserved by a future guest!? - or the room may be vacant while reserved by a future guest!? arrive / depart / Occupied need a notion of time (“timing diagram”) 11 C make-reservation B make-reservation Problem: States of a Hotel Room Reserved by guest B Reserved by guest C Occupied C depart B depart C arrive B arrive A depart Vacant A arrive States Reserved Time [days] 12 C make-reservation B make-reservation Problem: States of a Hotel Room What if the guest is late? – “Holding” state? What if the room is overbooked? What when it is being cleaned? Reserved Reserved by guest B by guest C Reserved Issue: state transitions are weird—”Reserved” is a future state but transitioned to by a current event! What state? Occupied C depart B depart C arrive B arrive A depart A arrive Vacant Time [days] 13 C make-reservation B make-reservation Problem: States of a Hotel Room SOLUTION: Introduce a new object! Reserved by guest B Reserved Object: Reservation table free reserve Available Reserved by guest C Occupied Object: Room occupancy A depart current time A arrive Vacant Time [days] Objects send messages that change states 14 Problem: States of a Hotel Room We need two objects: One tracks room’s current state (occupancy) and the other its future state (reservation) Reserved Object 2: Reservation table Available Occupied Object 1: Room occupancy C depart current time B depart C arrive B arrive A depart A arrive Vacant Time [days] 15 OCL: Object Constraint Language OCL is used in UML diagrams to – write constraints in class diagrams – guard conditions in state and activity diagrams based on Boolean logic Boolean expressions (“OCL constraints”) used to state facts about elements of UML diagrams The implementation must ensure that the constraints always hold true 16 Basic OCL Types and Operations Type Values Operations Boolean true, false and, or, xor, not, implies, if-then-else Integer 1, 48, 3, 84967, … *, , , /, abs() Real 0.5, 3.14159265, 1.e+5 *, , , /, floor() String 'With more exploration comes more text.' concat(), size(), substring() 17 OCL: Types of Navigation (a) Local attribute Class_A – attribute1 – attribute2 – … (b) Directly related class Class_A (c) Indirectly related class Class_A * assocBA * assocBA * assocAB * assocAB Class_B Class_B * assocCB * assocBC Class_C Within Class_A: self.attribute2 Within Class_A: self.assocAB Within Class_A: self.assocAB.assocBC 18 Accessing Collections in OCL OCL Notation Meaning EXAMPLE OPERATIONS ON ALL OCL COLLECTIONS c->size() Returns the number of elements in the collection c. c->isEmpty() Returns true if c has no elements, false otherwise. c1->includesAll(c2) Returns true if every element of c2 is found in c1. c1->excludesAll(c2) Returns true if no element of c2 is found in c1. c->forAll(var | expr) Returns true if the Boolean expression expr true for all elements in c. As an element is being evaluated, it is bound to the variable var, which can be used in expr. This implements universal quantification . c->forAll(var1, var2 | expr) Same as above, except that expr is evaluated for every possible pair of elements from c, including the cases where the pair consists of the same element. c->exists(var | expr) Returns true if there exists at least one element in c for which expr is true. This implements existential quantification . c->isUnique(var | expr) Returns true if expr evaluates to a different value when applied to every element of c. c->select(expr) Returns a collection that contains only the elements of c for which expr is true. EXAMPLE OPERATIONS SPECIFIC TO OCL SETS s1->intersection(s2) Returns the set of the elements found in s1 and also in s2. s1->union(s2) Returns the set of the elements found either s1 or s2. s->excluding(x) Returns the set s without object x. EXAMPLE OPERATION SPECIFIC TO OCL SEQUENCES seq->first() Returns the object that is the first element in the sequence seq. 19 OCL Constraints and Contracts A contract specifies constraints on the class state that must be valid always or at certain times, such as before or after an operation is invoked Three types of constraints in OCL: invariants, preconditions, and postconditions An invariant must always evaluate to true for all instance objects of a class, regardless of what operation is invoked and in what order • applies to a class attribute A precondition is a predicate that is checked before an operation is executed • applies to a specific operation; used to validate input parameters A postcondition is a predicate that must be true after an operation is executed • also applies to a specific operation; describes how the object’s state was changed by an operation 20 Example Constraints (1) Invariant: the maximum allowed number of failed attempts at disarming the lock must be a positive integer – context Controller inv: self.getMaxNumOfAttempts() > 0 Precondition: to execute enterKey() the number of failed attempts must be less than the maximum allowed number – context Controller::enterKey(k : Key) : boolean pre: self.getNumOfAttempts() self.getMaxNumOfAttempts() 21 Example Constraints (2) The postconditions for enterKey() are – (Poc1) a failed attempt is recorded – (Poc2) if the number of failed attempts reached the maximum allowed, the system blocks and the alarm bell blurts – Reformulate (Poc1) to: (Poc1) if the key is not element of the set of valid keys, then the counter of failed attempts after exiting from enterKey() must be by one greater than before entering enterKey() context Controller::enterKey(k : Key) : Boolean -- postcondition (Poc1): post: let allValidKeys : Set = self.checker.validKeys() if allValidKeys.exists(vk | k = vk) then getNumOfAttempts() = getNumOfAttempts()@pre else getNumOfAttempts() = getNumOfAttempts()@pre + 1 -- postcondition (Poc2): post: getNumOfAttempts() >= getMaxNumOfAttempts() implies self.isBlocked() and self.alarmCtrl.isOn() 22 xUnit / JUnit assert_*_() Verification is usually done using the assert_*_() methods that define the expected state and raise errors if the actual state differs http://www.junit.org/ Examples: – assertTrue(4 == (2 * 2)); – assertEquals(expected, actual); – assertNull(Object object); – etc. 23 TLA+ Specification lock, unlock(invalid key) unlock(valid key) [closed, unlit] [open, lit] lock turnLightOff (?) unlock(valid key) [closed, lit] lock, unlock(invalid key) MAIN CONFUSION: What is this state diagram representing? The state of _what_ object? 24