The behavior of a node is specified by a Deterministic Labelled Transition System (DLTS)
-
$S$ is the set, possibly infinite, of states that the node can be in -
$s_0 \in S$ is the initial state -
$I$ is the set, possibly infinite, of input events -
$O$ is the set, possibly infinite, of output messages -
$t: (S \times I) \to (S \times 2^O)$ is the transition function which is defined for all elements of$S \times I$ and it guarantees that for any$s \in S$ and$i \in I$ , it outputs a tuple$(s_d, M_O) = t(s, i)$ where$M_O$ is finite -
$E$ is the set, possibly infinite, of externally visible states -
$v: S \to E$ is the external view function which is defined for all elements of$S$
A node starts in state
An execution path
The external behavior
A mapping between a DLTS
In the context of this specification, a DLTS
$m_S(s_0^L) = s_0^H$ -
$\forall s_s^L, s_d^L \in S^L, i^L \in I^L, M_O^L \subseteq O^L: t^L(s_s^L, i^L) = (s_d^L, M_O^L) \implies t^H(m_S(s_s^L), m_I(i^L)) = (m_S(s_d^L), m_O(M_O^L))$ . $\forall e^L \in E^L : | \{ v^H(m_S(s^L)) : s^L \in S^L \land v^L(s^L) = e^L \} | = 1$
Intuitively, condition 1 states that the transition function
Condition 2 ensures that external states of
Given the requirements on
Such a relation ensures the following bisumulation conditions:
$\forall (s_s^L, i^L, s_s^H, i^H) \in R_I, s_d^L \in S^L, o^L \in O^L: t^L(s_s^L, i^L) = (s_d^L, o^L) \implies (\exists s_d^H \in S^H, o^H \in O^H: t^H(s_s^H, i^H) = (s_d^H, o^H) \land (s_d^L, o^L, s_d^H, o^H) \in R_O)$ $\forall (s_s^L, i^L, s_s^H, i^H) \in R_I, s_d^H \in S^H, o^H \in O^H: t^H(s_s^H, i^H) = (s_d^H, o^H) \implies (\exists s_d^L \in S^L, o^L \in O^L: t^L(s_s^L, i^L) = (s_d^L, o^L) \land (s_d^H, o^H, s_d^L, o^L) \in R_O)$
Given a mapping
According to the definition above, if a DLTS
The set of states, set of input events, set of output messages and transition function are all dependant on the function decorator @Event
.
All functions decorated by @Event
must have the same return type
and such a type must be a @dataclass(frozen=True)
with one field named state
and all other fields of type PSet
.
Let @Event
be applied to the function foo
below and let its return type be NewNodeStateAndMessagesToTx
.
@dataclass(frozen=True)
class NewNodeStateAndMessagesToTx:
state: NodeState
messages_type_1_to_tx: PSet[T1]
messages_type_2_to_tx: PSet[T2]
...
messages_type_n_to_tx: PSet[TN]
@Event
def foo(a_1: T1, a_2: T2, ..., a_k: TN, node_state: NodeState) -> NewNodeStateAndMessagesToTx:
...
The code above provides the following definitions.
The set state
of NewNodeStateAndMessagesToTx
, i.e. the domain of NodeState
.
The set PSet
in all of the fields of NewNodeStateAndMessagesToTx
except for the state
field.
Considering the code above, this corresponds to the union of the domain of they typesT1
, T2
, TN
.
Each @Event
annotation specifically defines a disjoint subset of the input events and the partial transition function dealing with such a subset of the input events.
A function like foo
in the code above defines:
- a subset of the input events
$I_{\texttt{foo}} := {\langle \texttt{foo}, a_1, a_2, \ldots, a_k \rangle : (a_1, a_2, \ldots, a_k) \in \texttt{T1} \times \texttt{T2} \times \cdots \times \texttt{TN} } \subseteq I$ .
- the partial transition function
$t_\texttt{foo}(s, a_1, a_2, \ldots, a_k) := (\texttt{foo}(a_1, a_2, \ldots, a_k, s)\texttt{.state}, \bigcup_{\texttt{f} \in (\mathit{fields}(\texttt{NodeState}) \setminus {\texttt{state}})} \texttt{foo}(a_1, a_2, \ldots, a_k, s)\texttt{.f} )$
where$\mathit{fields}(\texttt{NodeState})$ corresponds to the set of fields of the classNodeState
.
The set of input events @Event
.
The transition function is then defined as
The initial state @Init
.
Each function decorated by @View
defines a specific subset of the external state set and the partial external view function dealing with such a subset.
Specifically, take the following piece of code.
@View
def bar(node_state: NodeState) -> T1:
...
The code above defines:
- the subset of the external states
$E_\texttt{bar} := {\langle \texttt{bar}, a\rangle | a \in \texttt{T1}}$ - the partial view function
$v_\texttt{bar}(s) := \langle \texttt{bar}, \texttt{bar}(s) \rangle$
Let @View
.
The set of external states is then defined as
The external view function is defined as
The decorators @MapState
, @MapEvent
and @MapOutputMessage
are used to define the mapping
The decorator @MapState
is used to define the mapping between the lower-level spec states and the higher-level spec states.
@MapState
def foo(l_state: LowNodeState) -> HighNodeState:
...
The code above defines the state mapping function
The decorator @MapEvent
is used to define the partial event mapping between the lower-level spec input events and the higher-level spec input events.
@MapEvent
def low_event_name(a_1: LT1, a_2: LT2, ..., a_k: LTN) -> tuple[str, HT1, HT2, ..., HTN]:
...
The set of all functions decorated via @MapEvent
defines the input event mapping function as
The decorator @MapOutputMessage
is used to define the mapping between lower-level spec messages and higher-level spec messages.
@MapOutputMessage
def foo(l_out_message: LowOutputMessage1) -> HighOutputMessage1:
...
For any lower-level spec output message @MapOutputMessage
such that
Then the set of all functions decorated by @MapOutputMessage
defines the output message mapping fuction