Copyright DB Netz AG, licensed under CC-BY SA 3.0 DE (see full text in CC-BY-SA-3.0-DE)
Method for definition of actions
Overview
Actions are a behavioural model to express workflows including processes, algorithms as well as simple and complex control logic. They consist itself of a sequence of subordinated actions (e.g. atomic low-level instructions like assignments, actions to catch events, calculations etc.) which are performed step by step. This includes control flow as flow-based behaviour as well as data flow if required. There are no states involved in the sense of states of state machines, but there can be states in the sense of continuous values can be generated by the actions output or used by the actions input. They correspond in graphical notation to functional flow diagrams, the activity diagram of SysML v1 or the action definition of SysML v2.
Chararacteristics
They are imperative in comparison to declarative alternatives like behavioural constraints. This means they are more a definition of "how" rather than of "what". but they can still define an appropiate level of solution-independent or more abstract behaviour (e.g. for interface layer functions).
- consumes all new or existing input and produces output based on the inputs
- can be active in one more states of a state machine (e.g. of a system, subsystem) and performed the whole time as long as the entity is in the state
- can change the state of a corresponding state machine with raising an event to it considering all inputs, outputs and other conditions
- can be performed by the structural entity and can also be the main behaviour of it as an alternative to a state machine
Types
The following basic two types of actions are considered.
- Continuously or permanently action: This could be a definition of an on-going monitoring, observation or transformation like checking permanently inputs and conditions to produce outputs. (e.g. data transformations, reaction to events, data streaming, continuous calculations). It itsself consists of single short actions which may be repeated over time. This is applicable to permanent functions (as services) which are always performing and contain child actions.
- Short single action: This could be an algorithm, calculation, a single or simple instruction or a sending / receiving an exchange item. This is applicable as well to transition effects of state machines or as an subordinated action to another parent action.
Applicability
Actions are suitable to be used for the following structural entities.
- Sub(system) functions (logical function, interface layer function with event-based parts),
- components (logical components and interface layer components - if state machine is not suitable),
- subsystems (as main behaviour if a state machine is not suitable)
Examples
This example for the function "Determine required position state for one point" (derive "left"/"right" from DPS group state) is simple since the overall action consists of (only) a decision with different outcomes (notated with if-else statement).
/* ALF 1.1 example */ /* output value could also be defined as an out parameter, here the return statement is used */ activity DetermineRequiredPositionStateForOnePoint (in dps1state : DPSState, in dps2state : DPSState) : PointPositionState { if (dps1state == DPSState::None && dps2state == DPSState::Full) { return PointPositionState::RightEndPosition; } else if (dps1state == DPSState::Full && dps2state == DPSState::None) { return PointPositionState::LeftEndPosition; } else { return PointPositionState::NotAllowed; } }
Further example "Authorise driveability state of DPSes of one DPS group" (grant/reject DPS group state change) with pseudo code. This is an imperative style and constrains the solution space (is already a kind of solution). Here a geometric intersection is considered (with "intersects()" as an operation on sets) which will most probably be heavily used (e.g. MOB not intersects another MOB, MP not intersects obstacles and so on).
bool authoriseDriveability(Point point, Position reqPosition) { if (point.currPosition == reqPosition) return true; // simplified foreach (MOB mob : managedMOBs) { if (mob.intersects(point)) return false; } foreach (MP mp : managedMPs) { if (mp.intersects(point)) return false; } return true; }