Implementing other statechart semantics

An Interpreter makes use of several private methods for its initialization and computations. These methods computes the transition(s) that should be processed, the resulting steps, etc. These methods can be overridden or combined easily to define other variants of the statechart semantics.

Interpreter._select_event() → typing.Union[sismic.model.events.Event, NoneType]

Return (and consume!) the next available event if any. This method prioritizes internal events over external ones.

Returns:An instance of Event or None if no event is available
Interpreter._select_transitions(event: sismic.model.events.Event = None) → typing.List[sismic.model.elements.Transition]

Return a list of transitions that can be triggered according to the given event, or eventless transition if event is None.

Parameters:event – event to consider
Returns:a list of Transition instances
Interpreter._filter_transitions(transitions: typing.List[sismic.model.elements.Transition]) → typing.List[sismic.model.elements.Transition]

Given a list of transitions, return a filtered list of transitions with respect to the inner-first/source-state semantic.

Parameters:transitions – a list of Transition instances
Returns:a list of Transition instances
Interpreter._sort_transitions(transitions: typing.List[sismic.model.elements.Transition]) → typing.List[sismic.model.elements.Transition]

Given a list of triggered transitions, return a list of transitions in an order that represents the order in which they have to be processed.

Parameters:transitions – a list of Transition instances
Returns:an ordered list of Transition instances
Raises:ExecutionError – In case of non-determinism (NonDeterminismError) or conflicting transitions (ConflictingTransitionsError).
Interpreter._create_steps(event: sismic.model.events.Event, transitions: typing.Iterable[sismic.model.elements.Transition]) → typing.List[sismic.model.steps.MicroStep]

Return a (possibly empty) list of micro steps. Each micro step corresponds to the process of a transition matching given event.

Parameters:
  • event – the event to consider, if any
  • transitions – the transitions that should be processed
Returns:

a list of micro steps.

Interpreter._create_stabilization_step(names: typing.Iterable[str]) → sismic.model.steps.MicroStep

Return a stabilization step, ie. a step that lead to a more stable situation for the current statechart. Stabilization means:

  • Enter the initial state of a compound state with no active child
  • Enter the memory of a history state
  • Enter the children of an orthogonal state with no active child
  • Exit active states if all “deepest” (leaves) states are final
Parameters:names – List of states to consider (usually, the active configuration)
Returns:A MicroStep instance or None if this statechart can not be more stabilized
Interpreter._apply_step(step: sismic.model.steps.MicroStep) → sismic.model.steps.MicroStep

Apply given MicroStep on this statechart

Parameters:stepMicroStep instance
Returns:a new MicroStep, completed with sent events

These methods are called directly (or not) by execute_once.

See also

Consider looking at the source of execute_once to understand how these methods are related and organized.

Example: Outer-first/source-state semantics

For example, in order to obtain an outer-first/source-state semantics (instead of the inner-first/source-state one that Sismic provides by default), one should subclass Interpreter and override _filter_transitions.

Example: Semantics where internal events have no priority

If you want to change the semantics of Sismic so that internal events no longer have priority over external events, it suffices to override the _select_event() method and to invert the order in which the internal and external events queues are visited.

Example: Custom way to deal with non-determinism

If you want to change the way the Sismic semantics deals with non-determinism, for example because it deviates from the semantics given by SCXML or Rhapsody (remember Statechart semantics), you can implement your own variant for dealing with non-determinism. The method _sort_transitions() is where the whole job is done:

  1. It looks for non-determinism in (non-parallel) transitions,
  2. It looks for conflicting transitions in parallel transitions,
  3. It sorts the kept transitions based on our semantic.

According to your needs, adapt the content of this method.