Skip to content

Nested state machine

This nested state machine features multiple layers of conditional branching (Choice) and parallel execution (Fork), allowing complex workflows and transitions.

from perseus.state_machine.StateMachine import StateMachine
...
inner_choice = Choice(Path(("G", None)), Path(("H", ["h", "hh"])))
fork1 = Fork(Path(("E", None)), Path(("F", None), (inner_choice, None), ("I", None)))
outer_choice = Choice(
Path(("A", None)),
Path(("C", ["j"])),
Path(
("D", ["k"]),
(fork1, None),
),
)
inner_fork = Fork(Path(("M", None)), Path(("N", None)))
outer_fork = Fork(
Path(("K", None), (inner_fork, None), ("O", None)),
Path(("L", None)),
Path(("Z", None)),
)
s1 = StateMachine(
Path(
("A", None),
("B", ["-", "b"]),
(outer_choice, None),
("J", None),
(outer_fork, None),
("P", None),
),
)
s1.add_event(Event("A", "x")) # current states after event: ["A"]
s1.add_event(Event("A", "b")) # current states after event: ["B"]
s1.add_event(Event("B", "x")) # current states after event: ["A"]
s1.add_event(Event("A", "b")) # current states after event: ["B"]
s1.add_event(Event("B", "k")) # current states after event: ["D"]
s1.add_event(Event("D", "k")) # current states after event: ["E", "F"]
s1.add_event(Event("E", "k")) # current states after event: ["F"]
s1.add_event(Event("F", "hh")) # current states after event: ["H"]
s1.add_event(Event("H", None)) # current states after event: ["I"]
s1.add_event(Event("I", None)) # current states after event: ["J"]
s1.add_event(Event("J", None)) # current states after event: ["K", "L", "Z"]
s1.add_event(Event("Z", None)) # current states after event: ["K", "L"]
s1.add_event(Event("K", None)) # current states after event: ["L", "M", "N"]
s1.add_event(Event("M", None)) # current states after event: ["L", "M"]
s1.add_event(Event("L", None)) # current states after event: ["N"]
s1.add_event(Event("N", None)) # current states after event: ["O"]
s1.add_event(Event("O", None)) # current states after event: ["P"]
  • The root path starts at A, moves through B, then an outer_choice, followed by J, then an outer_fork and ends at P.
  • outer_choice branches into three paths:
    • A (default unconditioned path)
    • C if the Event value j occurs
    • D if the Event value k occurs, follwed by the fork fork1
  • fork1 splits into two parallel paths:
    • E
    • F, follwed by an inner_choice, then I
  • inner_choice selects between:
    • G (the default)
    • H if the Event value h or hh occurs
  • outer_fork splits into three parallel branches:
    • K, followed by an inner_fork, then O
    • L
    • Z
  • inner_fork splits the K oath further into parallel M and N states