Here's the transcript:
This is my 5th in a series of extended videos about diagrams in the UML and SysML graphical languages. In this I’m going to cover state machine diagrams and it’s a natural follow on from my previous videos about class diagrams and composite structure diagrams.
Whereas Composite Structure and Class Diagrams are types of structure diagram in UML, state machine diagrams are a type of behavior diagram, and there is a relationship between the two, in that classifiers shown on a structure diagram may have behavior that is described using a state machine. SysML inherits all its state machine syntax directly from UML without modification, hence state machine diagrams also apply to Blocks, a stereotyped class in SysML.
It probably doesn’t take a genius to know what type of behavior state machine diagrams show, however it’s worth reviewing what we mean by state-based behavior and some of the history here, not least because Rhapsody has had a part to play in it. If you google David Harel and Rhapsody then you’ll probably find this paper. If you google History and David Harel then you may find this. At the very least this paper will teach you that nothing is new and if you build something with strong foundations then it will last. It will also help us to understand why Rhapsody’s state machines are the way they are and how they might differ from other UML/SysML tools, as while they both had the same father, they have grown up with different pressures. Some things like the mapping to generate readable C++ code that executes on embedded targets is not part of the UML or SysML standard.
So let’s have a quick look at some of those fundamentals. In this example I’m going to model the emergency response of the UK government to COVID-19 as a Harel statechart. I'll use this to cover the syntax for triggered and guard-based transitions, OR, nested and orthogonal regions, and time events. The thing that I like about Harel-based statecharts is that the notation is that it’s a small language with clearly defined rules. The adage that don’t need something complex to describe something complex applies.
You need to draw a state machine for a classifier. I can’t right click a package and create one, rather it needs to be an element such as a class or block. Note that the term used by Rhapsody for the diagram is Statechart, rather than State Machine Diagram. I’m going to build the model completely from scratch and I’m building this example by reading a newspaper article written by the Independent newspaper on the 4 phases of UK governments response to the COVID-19 virus outbreak.
The first state in the Government response is called a Containment phase. In the Containment phase you rapidly identify anyone who has the virus and quickly get them to a specialist infectious disease unit where they can be quarantined to prevent the virus spreading. At the same time, you identify anybody they’ve been in contact with and isolate them.
The fundamental goal here is to stop the disease from spreading. Here we can see the basic syntax of an event-based transition. The event we react to is shown before the forward slash, and the action or actions performed as a result of taking the transition are shown after the slash. The action I’ve put here is actually assumed to be the invocation of an operation, hence I need to create the operation, under the class, if I want the state-machine to execute.
To do this I’ll just copy the text I typed and create a new element in the browser by pasting in a name that matches it. The statechart has the same scope as the class that owns it. This means that we can also create attributes for the class and use them in the action and guard fields of transitions. What I’ll do is to add an attribute to keep a track of the number of infections. I can then use this attribute in the action field of the transition, and I’ll get it to increment in value each time a new infection is detected.
The second phase of the Government’s response is called the Delay phase and starts when the virus has taken root in the UK and is freely spreading. This is where the government shifts to delaying the epidemic. The shift to the Delay phase occurs when the number of infections exceeds a particular threshold and we could show this will a guard-based transition. Firstly, I’ll create a constant to represent the threshold and set it to an arbitrary value for illustration purposes. The purpose of the delay phase is to reduce the number of people who become severely ill at the same time to prevent it from overwhelming the NHS - which does not have enough critical care beds for everyone who may need them.
A guard is a Boolean condition that evaluates to true or false and is shown in square brackets. In this case this is a null-triggered transition which has no event. This will be tested on entry to the owning state, hence it’s important that transition that changes the number of infections exits and re-enters here, as it will cause the number of infections to be tested each time the attribute changes. The delay strategy is designed to soften that peak of epidemic. When this transition occurs the government will postpone or cancel large events and it will close schools.
This allows me to illustrate a key aspect of Harel state machine notation, which is that and that states are persistent conditions of existence where the system reacts to certain events or stimulus, and actions are performed on transitions rather than in the states. Rhapsody has an Intellivisor feature that can be used to auto-populate a correct name by starting to type something and pressing the Ctrl plus Space key.
For a state machine like this where there is more than one state to be valid, I need to say which state the classifier will start in. I must do this using a default transition. State machines in Rhapsody are fully executable, so what I’m going to do is to drop a couple of panel widgets on to the diagram. One that will allow me to inject an event. What I’ll do is bind this to the identify infections event that is stimulating the state machine. The panel widgets here are related to the panel diagram which is licensed by the tools and utilities add-on currently. I’ll also add another another widget that will allow me to inspect values of attributes, and bind this to the number of infections attribute owned by the Government Response class. I’m then going to build and run the state machine, so I’ll get Rhapsody to create an executable with an instance of the class running inside it.
Rhapsody actually generates the C++ for this statemachine and then invokes the compiler to build and link it with something called the object execution framework. The object execution framework handles additional capabilities such as threading, timers, and the queues associated with asynchronous events sent between reactive classes.
Once you run something then you immediately spot issues. We can also see here that the number of infections attribute was not initialised and, if I look at the animated statechart, I can start to see what happens when I interact with it. For example, w’re not reacting to the identification of infections when in the Delay phase, because we did not put this event as an outgoing transition in the Delay state so let’s stop the execution and make some corrections to the model. Firstly, by initialising the number of infections to zero and then getting the Delay state to react to the same event and in the same way as the containment state.
This allows me to illustrate a key part of the syntax which is nested states. If I have two or more states that react to the same events in the same way then I can put them inside of a parent state and draw the common transitions from that. Note that if I exit and re-enter the parent state here, then the state machine will re-take the default transition and re-enter the Containment state. This is not something that I want to happen and therefore I need to make a further change to the model to correct this.
Conveniently, this allows me to illustrate another syntax called a reaction in state. A reaction in state is used where we want a classifier to react to an event, without exiting and re-entering. In Rhapsody this can be entered in the Feature’s dialog of the state. Once we’ve done this, we can toggle the display of it on the diagram by clicking the icon in the top-right of the states graphical element. Before building and running, I’m just going to create a sequence diagram with the classifier as a lifeline and also the system border. I’ll then choose Close all but this and run again.
An animated sequence diagram like this allows us to visualise a linear view of the state of the classifier over time and how it reacts to events. As we go over the threshold therefore we can see that the government response moves from the Containment to the Delay phase. Once in the delay state we cannot return. It’s what is essentially a dead state. However, it does give me an opportunity to demonstrate two further aspects of state machine syntax, parallel or orthogonal states, and time events.
We can draw a parallel or orthogonal state using an AND line, so I’ll firstly resize the owning state and then draw an AND line from the top line to the bottom. In that I’ll put a Monitoring state and then show that over a certain period of time, people will recover (peopleRecover). Notice that this is a time event. In UML the syntax for this would be the word after and then the brackets, whereas Rhapsody using the keyword tm. In the brackets is the time interval that you want to set the timer for in milliseconds.
I’m implemented the decrementing of the number of infections using an operation. While I could access the attribute directly on a transition, two benefits of an operation are that they can be reused and also that it will be visible on an animating sequence. Note that the action syntax I’m using here is the C++ syntax. Rhapsody also has a abstract action language syntax but the C++ syntax is much more widely known and hence I just use that. Let’s put the return transition in. Which occurs if the number of infections is less than or equal to the delay threshold. When writing guard-based transitions you need to make sure that they don’t overlap with incoming transitions.
I’ll also expand the two states to the third, more serious phase, which the UK government has called the Mitigate phase. This is the final phase of the government’s strategy and is effectively triggered once the disease is widespread and unable to be stopped or even slowed. At that stage, the emphasis will shift to saving as many lives as possible and maintaining public order and the continuation of public services. I’ll add an attribute called the mitigate threshold and set this to be an arbitrary value for the purposes of simulation, like the transition from the Containment to the Delay state, I’ll add a guard-based transition that will cause the response to transition into the Mitigate phase if the higher threshold value is exceeded.
It's at this stage that we would see some of the most extreme measures be taken by the government to try and keep the country going. Hospitals will cancel operations and in extreme cases doctors will be forced to ration care to those most likely to benefit. The British Army could be deployed onto the streets, and the government could enforce work from home to prevent movement of people.
When using operations as actions it’s often easier to enter them first in the browser, and then use Rhapsody’s Intellivisor feature to auto-populate. As well as speeding up model creation, this reduces the chance of typos. Note that I’m adding semi-colon here as this text is going to put directly into the C++ that is generated.
This gives us a much more complete model. We now have 3 clear phases of the government response modeled, together with guard, time and event-based transitions that are occurred. The state machine therefore starts to get a bit more interesting when we execute it. At this stage, let’s run the statechart again.
With the introduction of a time element we can now see a more continuous form of behavioral model in addition to the reactive behavior that comes from injecting events. We can see the impact of the class reacting to external events, and changing state as a result. We can also see the impact of time events in an orthogonal region causing guard based transitions to be taken in the main region.
This brings us to a 4th phase of the government response, which is called Research. The research phase is a wonderful example of an orthogonal region. It’s something that runs concurrently in parallel to the states that we’ve already identified. Again, I can draw another parallel region by adding an AND line. In this parallel or orthogonal region I might define a simple OR state machine with a Research state that has two nested states.
The research phase might be categorized by a period where we look for drugs followed by a period where we deploy the drugs. It may be that we cannot find a vaccine, however, deployment of drugs may reduce the severity and prevalence of infections, and therefore act to reduce the overall number of infections.
I’ll model this by adding a time event that acts to reduce the number of infected people. I’ll put a slightly smaller time interval and re-use the people recover operation that I created earlier. Before running, I’ll just add a button to stimulate the drugs found event. The easiest way to do this in Rhapsody is to copy and paste an existing button, as it’ll pick up the existing display options and bound element, which is then easy to change.
Let’s do a final run then, to see how the state machine behaves. The great thing about state machines when you execute them is that they come alive. Watching how a clock move is a lot different to viewing a static picture of one.
Of course, these different regions do have an influence on each other. If we can delay the spread of the virus for longer then this gives more opportunity to develop a cure or ways of lessening the impact on vulnerable people in society. There are of course other elements to consider, however this concludes the demonstration. In this we covered event, guard and time-based transitions, as well as or, parallel and nested states.
For me, the key thing about state machines is the succinct and intuitive nature of their syntax. and power of the notional to express quick powerful behavioural constructs that are quite commonly described. They also quickly come alive when you have the ability to run them and interact with them, hence are fundamentally designed for modeling reactive event based behaviour..
My name is Fraser Chadburn and I specialist in tool-based training and consulting in IBM products and, in particular, in setting up Rhapsody using domain-specific profiles. Using Java automation I can simplify and speed up modeling tasks so that users can focus on creative and fun systems and software engineering. If you do have any questions then feel free to contact me.