.. include:: alias.rst .. _core_model: Intended |rcm| Semantics ======================== Every |rcm| state is executable. Execution denotes the evaluation of a state and referenced model elements as specified in the state's syntax. In order to execute a state, the sequence and how these model elements are to be evaluated have to be specified. Even though the execution process is primarily defined by state transitions describing the progress of a model, it also includes the coordinated invocation of specified actions, entry functions and exit functions. In the following paragraphs, execution semantics are described informally using prose and informal rules and sequences. This format can be ambigous. Thus, a formal semantics is defined in the next section. General ^^^^^^^ When a state is executed, the state to be executed is activated. In addition, the child state marked as *first*, its first child etc. are activated as well. Execution follows these general rules: * Evaluation happens top-down, conditions and thus transitions (e.g. on port activation) of 'upper' layers in the state hierarchy are considered first and may *preempt* evaluation of 'lower' levels. (structural priority) * If the entry function of a state has been executed, the state's exit function will always be executed when the state is deactivated. * Connections at ports are considered in sequence. The order is determined by a port priority value where smaller priorities are considered first. Port conditions are checked similar to the conditional or ``||``, where the first port evaluating to ``true`` wins and results possibly in a transition. All subsequent ports are then ignored even if they evaluate to ``true``. * Actions are stored in a sequence and are executed in order given their action condition evaluates to ``true``. In contrast to ports, all actions with a ``true`` condition are evaluated. * Links directly proxy the linked state but allow for different parameterization. Executing a link is identical to replacing the link with the linked state and using the parameter value of the linked state as default parameters. Multiple links to the same linked state do not share common execution state, in particular, they do not share parameters, variables and results. * Connections of states onto themselves are not supported and cannot transition. * Actions and connections are only evaluated once before services and/or aborted execution are considered, i.e. state machines have at least once the chance to react to something (unless their parent preempts them). * The core stores (top-level) state machines identified by names. * Only top-level state machines stored in the core can be linked to. * No link cycles are allowed, i.e. links that contain states that contain links to the original linked state are not allowed. In other words, recursion using links is not possible. * Barriers cannot be connected to barriers. State execution is separated in so called *macro* and *micro* steps. A *macro* step takes a snapshot of the current state of external inputs and progresses a given state and its children using micro steps until a complete state is reached, i.e. no further transitions are possible. To prevent endless loops without exiting a macro step, actions and connections can be executed/followed only once in a single macro step. Execution status ^^^^^^^^^^^^^^^^ Every node in the state machine hierarchy is always in one of four possible execution phases (also called status of the state in the following): ``Inactive``, ``Entering``, ``Active``, ``Exiting`` where the following terms are used to denote changes of the execution phase: * ``Inactive`` -> **activate** -> ``Entering`` * ``Entering`` -> **enter** -> ``Active`` * ``Active`` -> **deactivate** -> ``Exiting`` * ``Exiting`` -> **exit** -> ``Inactive`` Parameter Evaluation ^^^^^^^^^^^^^^^^^^^^ Parameters for a state are evaluated when the state is activated, i.e. when its status is set from ``Inactive`` to ``Entering``. Parameters are not re-evaluated again while the state is ``Entering``, ``Active`` or ``Exiting``. It must be noted that parameter expressions are not evaluated in the child context but in the parent context. Consider the following example: .. code-block:: lua foo: child("bar").result.x It defines how the parameter ``foo`` should be computed. Since the above expression is evaluated in the parent scope of the state for which the parameter is defined, ``child("bar")`` accesses a sibling named ``bar``. However, if the same expression is used in an action script or action condition expression, it denotes the child named ``bar``. Micro step rules ^^^^^^^^^^^^^^^^ Micro step evaluation is defined top-down in the state hierarchy, where 'upper' levels are considered before 'lower' levels. The first applicable micro step rule is then taken and results in a micro step, which starts again at the root of this execution's state hierarchy. #. Evaluate *port conditions*, and if one evaluates to ``true``, deactivate the state. #. For all *actions*: if the action's condition evaluates to ``true`` and it was not yet executed (in the current macro step), execute its function body. #. For all *connections*: transition all **ready** connections by deactivating the port of the connection's source and activating its destination (deactivation resets all port activations). A *port connection* is **ready** when: * Source state is ``Inactive`` * Source port is active * Destination is ``Inactive`` * No port of destination is active A *barrier connection* is **ready** when: * Source barrier is ``Active`` * Destination state is ``Inactive`` * No port of destination is active Furthermore, connections **into** and **out of** barriers need to be simultaneously ready in order to transition them. This means that a barrier is only activated when all incoming connections are ready, and is only deactivated when all outgoing connections are ready. #. If the state is still active, do micro steps in all child states (recursively) with *propagated* contexts. Examples ^^^^^^^^ To further clarify the syntax and execution semantics, an example |rcm| state machine is discussed in this section. The example consists of a graphical representation of the state machine at hand and a macro- and micro- level description of the execution semantics. Simple composite state `````````````````````` This example focuses on a composite state with actions and two children . The considered issues are whether execution of the first action does precede the transition from ``A`` to ``B`` or similarly if the second action is executed before or after ``B``'s entry function. .. note:: The port conditions of ``pA`` and ``pB`` are directly ``true``. .. _example_state: .. only:: html .. figure:: _static/example_state.png :width: 40% :align: center :target: _static/example_state.png Simple composite |rcm| state with actions and two children .. only:: latex .. figure:: _static/example_state.png :width: 40% :align: center Simple composite |rcm| state with actions and two children **Macro** On the macro-level, the ``Parent`` state machine will remain active, along with its child state ``B``. When transitioning into the state the following functions will get executed: #. | ``Parent`` entry #. | ``A`` entry #. | action ``1)`` of ``Parent`` #. | ``A`` exit #. | ``B`` entry #. | action ``2)`` of ``Parent`` #. | ``B`` exit #. | action ``2)`` of ``Parent`` (until execution gets stopped) **Micro** The example at hand can be discussed in more detail by examining the taken micro steps. Execution gets started by *activating* the root node, effectively setting ``Parent`` and its first node ``A`` on status ``Entering``. From there on, the following micro steps are taken: #. | Enter ``Parent``, execute its ``entry`` function, it is now ``Active`` #. | Enter ``A``, execute its ``entry`` function, it is now ``Active`` #. | No port or action of ``Parent`` evaluates to ``true``, | evaluate ports of ``A`` -> ``pA`` triggers, ``A`` is now ``Exiting`` #. | Action ``1)`` of ``Parent`` gets executed because its condition is ``true`` #. | No port or action of ``Parent`` evaluates to ``true``, | exit ``A``, execute its ``exit`` function, it is now ``Inactive`` #. | No port or action of ``Parent`` evaluates to ``true``, | transition into ``B``, activate it, it is now ``Entering`` #. | No port or action of ``Parent`` evaluates to ``true``, | evaluate ports of ``B`` -> ``pB`` triggers, ``B`` is now ``Exiting`` #. | Action ``2)`` of ``Parent`` gets executed because its condition is ``true`` #. | No port of ``Parent`` evaluates to ``true``, and action ``2)`` was already executed, | exit ``B``, execute its ``exit`` function, it is now ``Inactive`` No further micro steps can be taken (in this macro step) as the only condition which would evaluate to ``true`` was already executed. However, in **all** following macro steps, action ``2)`` of ``Parent`` will always be executed once because the ``pB`` remains triggered - until execution gets stopped.