State machines#

The Swan language has the notion of a state machine, represented by the StateMachine class. A state machine is composed of:

  • states, represented by the State class;

  • transitions between states, represented by the Transition class;

  • forks, represented by the Fork class, which are used to split transitions into several branches.

The figure Fig. 9 shows the classes hierarchy and the relationships between these classes.

../../../_images/states_and_transitions.svg

Fig. 9 States and transition declarations#

Note

The Swan language has two syntaxes for defining transitions:

  • Inline transitions: defined directly within the state definition. This syntax is used to defined an automaton within a let section.

  • Separate transition declarations: defined outside the state, referencing the state by its ID. This syntax is used to define a state machine within a diagram, using a StateMachineBlock within a Diagrams.

The two notations are abstracted, and the Transition class represents both notations. The Transition.is_transition_decl property

indicates whether the transition is a separate declaration (is_transition_decl=True) or an inline transition.

In addition a transition can be:

  • between two states, which a direct transition;

  • a part of a transition starting from a state and going to fork, which can split into several branches.

The Transition class represents either a direct state-to-state transition or any part when there are forks.

State machine#

class ansys.scadeone.core.swan.StateMachine(lhs: EquationLHS | None = None, items: List[StateMachineItem] | None = None, lunum: Lunum | None = None, luid: Luid | None = None)#

Bases: DefByCase

State machine definition.

A state machine contains states and transition declarations defined as items.

Consider using StateMachine.states and StateMachine.transition_decls properties to get the list of states and transition declarations.

get_full_path() str#

Full path of the Swan construct.

This method is implemented by derived classes that correspond to a declaration at the module level (such as sensor, type, group, const, operator), or a module itself.

Returns:
str

Path within the owner and name of the Swan construct.

Raises:
ScadeOneException

If the method is not implemented for the current SwanItem type.

get_state(state_id: str | Identifier | Lunum | StateRef) State | None#

Retrieve a state object matching the given identifier or lunum.

Parameters:
state_idUnion[str, Identifier, Lunum, StateRef]

The identifier or lunum to match against the states. If a string is provided, it is treated as an identifier. If a StateRef is provided, identifier or lunum are used for matching (lunum has priority if both are set).

Returns:
State or None

The state object that matches the given identifier or lunum, or None if no match is found.

Raises:
ScadeOneException

If ident type is not supported.

static set_owner(owner: SwanItem | IModel | None, children: SwanItem | Iterable[SwanItem] | None) None#

Helper to set owner as the owner of each item in the Iterable items.

Parameters:
ownerSwanItem

Owner of the items.

childrenUnion[SwanItem, Iterable[SwanItem], None]

Items to set owner.

property all_transitions: List[Transition]#

Return all transitions, strong and weak, of all states.

property default_state: List[State]#

Return the default state, or None if no default state. The default state is marked with dedicated pragma.

property initial_state: List[State]#

Return the initial state, or None if no initial state. There should be only one initial state, but this is not checked is there are multiple initial states.

property is_protected: bool#

Tell if a construct item is syntactically protected with some markup and is stored as a string (without the markup).

property items: List[StateMachineItem]#

List of states and transition declarations in declaration order.

Consider using StateMachine.states and StateMachine.transition_decls properties to get the list of states and transition declarations.

property lhs: EquationLHS | None#

Left-hand side of the equation, may be None.

property luid: Luid | None#

Return luid or None if no luid.

property lunum: Lunum | None#

Return lunum or None if no lunum.

property model: IModel#

Return model containing the Swan item.

property module: ModuleBase | None#

Module containing the item.

Returns:

ModuleBase: module container, see ModuleBody and ModuleInterface or None if the object is itself a module.

property owner: SwanItem | IModel | None#

Owner of current Swan construct.

property pragmas: List[Pragma]#

Pragmas associated to this Def by case.

property states: List[State]#

Transitions and states of the state machine.

property transition_decls: List[Transition]#

List of transition declarations, defined in the automaton (not in a state).

States#

A state may have a body, as a scope and may have transitions as Transition objects. In that case, transitions belongs to the strong or weak lists.

class ansys.scadeone.core.swan.State(id: Identifier | None = None, lunum: Lunum | None = None, in_state_strong_transition_decls: List[Transition] | None = None, body: Scope | None = None, in_state_weak_transition_decls: List[Transition] | None = None, is_initial: bool = False, pragmas: List[Pragma] | None = None)#

Bases: StateMachineItem

State definition.

Note

Syntactically, state transitions can be defined either in the state declaration, or in the automaton as separate items. Transitions defined in the state declaration are stored within the state, using the State.in_state_strong_transition_decls and State.in_state_weak_transition_decls properties. These properties are used to preserve the original Swan description.

Consider using instead the State.strong_transitions and State.weak_transitions properties. They return the list of all strong and weak transitions, respectively. They combine the transitions defined in the state declaration, and the transitions defined in the automaton with this state as source.

Parameters:
idOptional[common.Identifier]

State identifier, None if not set.

lunumOptional[common.Lunum]

State lunum, None if not set.

in_state_strong_transition_declsOptional[List[Transition]]

List of strong transitions, None if not set. These are the transitions found in the state declaration. They are kept to preserve the original Swan description.

bodyOptional[scopes.Scope]

Body of the state as a Scope, None if not set. Note that syntactically, the body is a list of Section.

in_state_weak_transition_declsOptional[List[Transition]]

List of weak transitions, None if not set. These are the transitions that are found in the state declaration. They are kept to preserve the original Swan description.

is_initialbool

True if the state is the initial state.

get_full_path() str#

Full path of the Swan construct.

This method is implemented by derived classes that correspond to a declaration at the module level (such as sensor, type, group, const, operator), or a module itself.

Returns:
str

Path within the owner and name of the Swan construct.

Raises:
ScadeOneException

If the method is not implemented for the current SwanItem type.

get_targets() Set[State]#

Get direct target states of the state.

Returns:
set[State]

A set of target State objects.

static set_owner(owner: SwanItem | IModel | None, children: SwanItem | Iterable[SwanItem] | None) None#

Helper to set owner as the owner of each item in the Iterable items.

Parameters:
ownerSwanItem

Owner of the items.

childrenUnion[SwanItem, Iterable[SwanItem], None]

Items to set owner.

property body: Scope#

Body of state as a Scope.

property id: Identifier | None#

State ID.

property in_state_strong_transition_decls: List[Transition]#

List of strong transitions defined in the state declaration.

Consider using State.strong_transitions property to get the list of all strong transitions (defined in the state and/or defined in the automaton with this state as source).

property in_state_weak_transition_decls: List[Transition]#

List of weak transitions defined in the state declaration.

Consider using State.weak_transitions property to get the list of all weak transitions (defined in the state and/or defined in the automaton with this state as target).

property is_initial: bool#

True when state is initial.

property is_protected: bool#

Tell if a construct item is syntactically protected with some markup and is stored as a string (without the markup).

property model: IModel#

Return model containing the Swan item.

property module: ModuleBase | None#

Module containing the item.

Returns:

ModuleBase: module container, see ModuleBody and ModuleInterface or None if the object is itself a module.

property owner: SwanItem | IModel | None#

Owner of current Swan construct.

property pragmas: List[Pragma]#

List of pragmas.

property strong_transitions: List[Transition]#

List of strong transitions, sorted by priority. It combines:

  • transitions defined in the state declaration,

  • transitions declared outside of states with this state as source.

Note

Adding or removing transitions from this list does not change the state transitions. Use State.in_state_strong_transition_decls to modify the list of strong transitions defined within the state, or changes the automaton’s transitions for this state.

property weak_transitions: List[Transition]#

List of weak transitions, sorted by priority. It combines:

  • transitions defined in the state declaration,

  • transitions declared outside of states with this state as target.

Note

Adding or removing transitions from this list does not change the state transitions. Use State.in_state_weak_transition_decls to modify the list of weak transitions defined within the state, or changes the automaton’s transitions for this state.

Transitions#

A transition gathers the following information:

  • its priority,

  • whether it is a strong or weak transition;

  • a guard condition, represented by a common.Expression object;

  • an action, represented by a scopes.Scope object;

  • its target, which can be either a State or a Fork object.

  • if target is a state, whether it is a resume or restart transition (see Transition.is_resume).

The priority and the kind of transition (strong or weak) are defined for the whole transition, or for the start branch in case of a fork.

class ansys.scadeone.core.swan.Transition(priority: Literal | None, is_strong: bool, guard: Expression | None, action: Scope | None, target: StateRef | Fork, source: StateRef | None = None, is_resume: bool = False, pragmas: List[Pragma] | None = None)#

Bases: StateMachineItem

Transition definition between states or forks.

A transition can be between two states, or from a state to a fork, or from a fork to a state. The Transition class represents all these cases, including the case with a guard or not, a source state or not (for transition declarations), a priority or not, and a resume or restart type.

Parameters:
priorityOptional[Literal]

Transition priority, None if not set.

is_strongbool

True if the transition is strong, False if weak.

guardOptional[common.Expression]

Transition guard, None if not set.

actionOptional[scopes.Scope]

Transition action, None if not set.

targetUnion[StateRef, Fork]

Transition target, either a StateRef or a Fork.

sourceOptional[StateRef], optional

Transition source, None if not set (for transition declarations), by default None.

is_resumebool, optional

True if the transition is a resume transition, False if restart, by default False. Only applies to transitions to a state.

pragmasOptional[List[common.Pragma]], optional

List of pragmas associated with the transition, None if not set. Apply to the transition itself, either a state-to-state or state-to-fork transition, by default None.

get_full_path() str#

Full path of the Swan construct.

This method is implemented by derived classes that correspond to a declaration at the module level (such as sensor, type, group, const, operator), or a module itself.

Returns:
str

Path within the owner and name of the Swan construct.

Raises:
ScadeOneException

If the method is not implemented for the current SwanItem type.

static set_owner(owner: SwanItem | IModel | None, children: SwanItem | Iterable[SwanItem] | None) None#

Helper to set owner as the owner of each item in the Iterable items.

Parameters:
ownerSwanItem

Owner of the items.

childrenUnion[SwanItem, Iterable[SwanItem], None]

Items to set owner.

static sort_key(transition: Transition) int | float#

Key function to sort transitions by priority, with None as lowest priority. This key can be used in sort() or sorted() functions.

property action: Scope | None#

Transition action or None.

property guard: Expression | None#

Transition guard or None. Apply to transition start, or to else branch of a fork.

property head: State | Fork#

Transition target, either a State or a Fork.

Raises:
ScadeOneException

If the target is a StateRef and the actual State cannot be found.

property is_guarded: bool#

Check whether the transition has a guard.

property is_protected: bool#

Tell if a construct item is syntactically protected with some markup and is stored as a string (without the markup).

property is_resume: bool#

True when the transition is a resume transition, False when restart.

property is_strong: bool#

True when the transition is strong, False when weak.

property is_transition_decl: bool#

True when the transition is a source (whole state-to-state transition, or state-to-fork transition).

property model: IModel#

Return model containing the Swan item.

property module: ModuleBase | None#

Module containing the item.

Returns:

ModuleBase: module container, see ModuleBody and ModuleInterface or None if the object is itself a module.

property owner: SwanItem | IModel | None#

Owner of current Swan construct.

property pragmas: List[Pragma]#

List of pragmas.

property priority: Literal | None#

Transition priority or None.

property source: StateRef | None#

Transition source, either a StateRef (transition declaration), or None. Consider using Transition.tail property to get the actual source.

property tail: State | Fork#

Transition source, either a State or a Fork.

property target: StateRef | Fork#

Transition target, either a StateRef, or a Fork. Consider using Transition.head property to get the actual target.

Reference to states#

Transitions reference their source and target states using StateRef objects as internal information to defined start and end states. The actual state can be accessed using the Transition.head and Transition.tail properties, which resolve the references.

class ansys.scadeone.core.swan.StateRef(id: Identifier | None = None, lunum: Lunum | None = None)#

Bases: SwanItem

Reference to a state in a state machine.

This class is used to reference a state in a state machine, either by its identifier or its lunum. It also includes a flag to indicate whether the state should be resumed or restarted.

Parameters:
idOptional[common.Identifier]

The identifier of the state. Default is None.

lunumOptional[common.Lunum]

The lunum of the state. Default is None.

Raises:
ScadeOneException

If both id and lunum are None, or if both are provided.

get_full_path() str#

Full path of the Swan construct.

This method is implemented by derived classes that correspond to a declaration at the module level (such as sensor, type, group, const, operator), or a module itself.

Returns:
str

Path within the owner and name of the Swan construct.

Raises:
ScadeOneException

If the method is not implemented for the current SwanItem type.

static set_owner(owner: SwanItem | IModel | None, children: SwanItem | Iterable[SwanItem] | None) None#

Helper to set owner as the owner of each item in the Iterable items.

Parameters:
ownerSwanItem

Owner of the items.

childrenUnion[SwanItem, Iterable[SwanItem], None]

Items to set owner.

property id: Identifier | None#

State identifier, or None if lunum is used.

property is_protected: bool#

Tell if a construct item is syntactically protected with some markup and is stored as a string (without the markup).

property lunum: Lunum | None#

State lunum, or None if identifier is used.

property model: IModel#

Return model containing the Swan item.

property module: ModuleBase | None#

Module containing the item.

Returns:

ModuleBase: module container, see ModuleBody and ModuleInterface or None if the object is itself a module.

property owner: SwanItem | IModel | None#

Owner of current Swan construct.

Forks#

Forks are transitions that split into several branches. Each branch is represented by a Transition object, and the fork itself is represented by a Fork object.

class ansys.scadeone.core.swan.Fork(transitions: List[Transition])#

Bases: SwanItem

Base class for fork-related classes. Transitions are ordered by priority, with the first transition having the highest priority.

If the latest transition has None guard, it is the else branch.

get_full_path() str#

Full path of the Swan construct.

This method is implemented by derived classes that correspond to a declaration at the module level (such as sensor, type, group, const, operator), or a module itself.

Returns:
str

Path within the owner and name of the Swan construct.

Raises:
ScadeOneException

If the method is not implemented for the current SwanItem type.

static set_owner(owner: SwanItem | IModel | None, children: SwanItem | Iterable[SwanItem] | None) None#

Helper to set owner as the owner of each item in the Iterable items.

Parameters:
ownerSwanItem

Owner of the items.

childrenUnion[SwanItem, Iterable[SwanItem], None]

Items to set owner.

property from_transition: Transition#

Return the transition owning this fork.

property is_protected: bool#

Tell if a construct item is syntactically protected with some markup and is stored as a string (without the markup).

property model: IModel#

Return model containing the Swan item.

property module: ModuleBase | None#

Module containing the item.

Returns:

ModuleBase: module container, see ModuleBody and ModuleInterface or None if the object is itself a module.

property owner: SwanItem | IModel | None#

Owner of current Swan construct.

property transitions: List[Transition]#

List of transitions, sorted by priority.

Note

A new list is returned, modifying it does not change the state. Use self._transitions to modify the internal list.