FSM: Process Description

Describe Processes with Hierarchical Finite State Machines (HFSM)

Formalism of Hierarchical Finite State Machines (FSMs) allows to describe the behavior of dynamic systems as a set of states and transitions between them, triggered by events.

Key elements in this model are:

The next sections of this document describe individual notions in more details.

States

States represent the possible phases within a process or lifecycle stages. In StateWalker, states are hierarchical – transitions between sub-states are defined only in their direct parent state.

All states have exactly the same structure as their parents and children with the following three fields:

The formal definition for the format of states and transitions can be found in this document: TypeScript / JSON Schema – formal process definitions.

State Examples

The example below illustrates how to describe the behavior of an old telephone with an integrated fax machine:

- key: Telephone
  transitions:
  - ["", "*", "Off"]
  - ["Off", "switch", "On"]
  - ["On", "switch", "Off"]
  - ["*", "unplug", ""]
  states:
  - key: On
    transitions:
    - ["", "*", "Waiting"]
    - ["Waiting", "signal", "Ringing"]
    - ["Ringing", "hangUp", "Talking"]
    - ["Talking", "hangOut", "Waiting"]
    - ["Ringing", "timeout", "FaxReceiving"]
    - ["FaxReceiving", "done", "Waiting"]
Textual process description

This FSM models a telephone system that begins in the “Off” state and can be switched on to enter the “On” state, which contains a complete sub-workflow for handling calls and fax operations. The top-level behavior is straightforward: the telephone can be switched between Off and On states, and from any state it can be unplugged, which terminates the entire system by transitioning to an empty state.

When the telephone is switched on, it enters a hierarchical state system that begins in the “Waiting” mode, representing the idle state where the phone is ready to receive incoming calls. Upon receiving a signal, the system transitions to “Ringing” to indicate an incoming call. At this point, the system has two possible paths: if someone answers the call by triggering the “hangUp” event, the telephone moves to the “Talking” state for active conversation, and when the conversation ends with a “hangOut” event, it returns to the waiting state to be ready for the next call.

The system also demonstrates intelligent call handling through an automated fax detection mechanism. If the ringing phone is not answered within a certain timeframe, indicated by the “timeout” event, the system automatically assumes the incoming call is a fax transmission and transitions to the “FaxReceiving” state. Once the fax transmission is complete, marked by the “done” event, the telephone returns to its waiting state, ready to handle the next incoming call or fax. This design reflects the common behavior of older telephone systems that included built-in fax machines capable of automatically detecting and handling fax transmissions without user intervention.


Transitions

Transitions define the conditions under which the FSM moves from one state to another. Each transition specifies:

Configuration for transitions contains triples of string keys:
SourceStateKey -eventKey-> TargetStateKey

Note: it is important to highlight that transitions are possible only between direct sub-states of the parent state.

Syntax:

transitions:
  - ["Start", "begin", "Processing"]
  - ["Processing", "complete", "Completed"]

Special cases:

Transitions: Events

Events are the triggers that cause transitions between states.

Example:

transitions:
  - ["Start", "initialize", "Processing"]
  - ["Processing", "error", "ErrorState"]

Transitions: Initial State

The initial state is where the FSM begins its execution. It is specified using an empty source state ("") in a transition.

Example:

transitions:
  - ["", "", "InitialState"]

Transitions: Termination State

A transition to an empty state ("") explicitly defines exit condition for the current state:

Examples:

Exit from the EditingReview substates on done event:

transitions: 
  - ["EditingReview", "done", ""]

Exit from all substates on exit event:

transitions: 
  - ["*", "exit", ""]

Here we are using a wildcard mask ("*") to match all substate.

Wildcards

Wildcards ("*") for states and events simplify transitions definitions.

transitions:
  - ["*", "error", "HandleError"]
  - ["*", "reset", "Start"]

Example of a transition to occur on any event:

transitions:
  - ["ErrorState", "*", "Completed"]