Statecharts, originally invented by David Harel, are a well-known visual modeling language for representing the executable behavior of complex reactive event-based systems. While several commercial tools exist for simulating statecharts and generating executable source code, these tools tend to be mostly commercial, or require the use of an integrated visual environment for using them.
As part of a research project conducted at the University of Mons, we have come up with a much more lightweight approach for defining, validating and executing statecharts, by proposing an open source API implemented in Python 3. This API, developed by Alexandre Decan, has been baptised Sismic, a recursive acronym for Sismic Interactive Statechart Model Interpreter and Checker.
The Sismic API is available through the Python package manager PyPI and can be easily installed using the pip installer. There is also an extensive online user manual. The source code is released under the GNU Lesser General Public Licence version 3.0 (LGPLv3), and is available through GitHub.Looking for a lightweight approach for defining, validating and executing statecharts? Use our open source API implemented in Python 3 Click To Tweet
Our 2018 research article A method for testing and validating executable statechart models published in the Software and Systems Modeling journal explains how to use Sismic for defining, validating and testing executable statecharts. It also includes the results of a controlled user study to evaluate the feasibility, usefulness and adequacy of the proposed techniques.
We have used Sismic in the classroom for teaching executable behavioural modeling to bachelor students. The tool is also being used successfully by several companies. Based on their feedback, we continue to improve Sismic with new features.
Core Sismic features
Some of the most prominent features of Sismic are the following:
- An easy textual way to define statecharts with the human-friendly YAML markup language
- Support for statechart visualization using PlantUML
- A statechart interpreter with a fully observable and controllable simulation engine
- The ability to easily integrate (and interact with) regular Python code
- Support for design by contract for statecharts, by expressing invariants, pre- and postconditions on states and transitions
- Support for expressing runtime behavioral properties over statecharts
- Support for behavior-driven development (BDD) using the Gherkin language
Sismic in action
To illustrate how to use Sismic, consider the following example of a microwave controller, whose visual rendering with PlantUML is shown below:
Here is a code fragment of the YAML description of this statechart:
name: door opened on entry: send('lamp_on') on exit: send('lamp_off') initial: opened without item states: - name: opened without item transitions: - event: door_closed target: closed without item - event: item_placed target: opened with item - name: opened with item transitions: - event: item_removed target: opened without item - event: door_closed target: closed with item
To execute this statechart directly from with a Python program, it suffices to use the proper API calls to the Sismic interpreter. Here is some example code:
from sismic.io import import_from_yaml from sismic.interpreter import Interpreter statechart = import_from_yaml(filepath='microwave.yaml') interpreter = Interpreter(statechart) interpreter.queue('door_opened') interpreter.execute() interpreter.queue('item_placed', 'door_closed') assert 'closed with item' in interpreter.configuration
Bertrand Meyer introduced the principles of Design by Contract (DbC) and popularised them through his Eiffel programming language. While DbC has gained some amount of acceptance at the programming level, there is hardly any support for it at the modeling level.
In Sismic, it is possible to define contracts as part of a statechart, expressed in terms of preconditions, postconditions and invariants over states and transitions. At runtime, the statechart interpreter will verify the conditions specified by the contracts. Here’s an example for the microwave statechart, showing how the contract of state “controller” is defined:
contract: - always: not sent('heating_on') or active('cooking mode') - always: timer >= 0 - always: 0 <= power <= MAXPOWER
Another key feature of Sismic is its support for monitoring properties at runtime. These properties are expressed as statecharts themselves. Such property statecharts can be used to express functional properties of the intended behaviour in terms of the events that are consumed or sent, or in terms of the states that are entered or exited by a statechart.
When a statechart is executed by Sismic, specific meta-events are created based on the events that are sent or consumed, the states that are entered of exited, etc. When the statechart being monitored is executed, the meta-events are propagated to all associated property statecharts. The property statecharts will look for property violations based on those meta-events, following a fail fast approach: they will report a failure as soon as the monitored behavior leads to a final state of the property statechart.
Here’s an example of a property statechart checking that microwaves are not emitted when the door is open:
Finally, Sismic provides support for Behavior-Driven Development (BDD). This agile development technique allows to express scenarios or test cases by domain experts in natural language. This allows designers to focus on the purpose of the model rather than the technical details. Here’s an example of a scenario describing that a microwave lamp must be on while cooking:
Scenario: Lamp is on while cooking Given I open the door And I place an item in the oven And I close the door And I press increase timer button 5 times When I press start button Then lamp turns on
This scenario can be automatically executed and checked by Sismic using the command-line utility sismic-bdd:
sismic-bdd microwave.yaml --features lighting.feature --steps steps.py
Of course, there is no magic involved. The mapping file (steps.py) need to be provided by the developer, but often this mapping is very straightforward.
To appreciate how Sismic works in practice, and to explore more of its internal workings, we invite you to install and play around with it, consult its online documentation, or even read its source code… We hope that this tool can be of use to you, and welcome any feedback!