Next: Using Guards, Previous: Actions, Up: Specifying Behaviour [Contents][Index]
State variables and guard expressions enable specification of protocols in a behaviour section. They specify the selection of one of multiple different actions. See Actions for an input event.
The state of an interface is composed of the values of all state variables.
The state diagram of an interface takes only the first variable declared into account.
State variable declarations can refer to public types (e.g. defined for use as event return values) or to private type declarations local to the ’behaviour’ section. Types can be boolean, integer with limited contiguous range or enumerated.
Guards are boolean expressions based on state variables. The statement behind the guard is selected when the expression evaluates to true. The keyword ’otherwise’ defines a catch-all guard which is true only when none of the other guard expressions in a list of guarded statements evaluates to true.
Declaring a state variable type based on an enum.
enum State {State1, State2};
Declaring a state variable based on the above type and initialising it:
State state = State.State1;
Declaring a guarded action statement
[state.State1] { action-statement ; }
Here the action statement will only be selected when guard [state.State1] evaluates to true.
See Actions, for how to declare action statements.
This example shows a simple state machine for a siren.
interface Siren { in void TurnOn(); in void TurnOff(); behaviour { enum State { SirenOff, SirenOn }; // type declaration State state = State.SirenOff; // variable declaration [state.SirenOff] // if the Siren is off, only allow to turn it on { on TurnOn: state = State.SirenOn; on TurnOff: illegal; } [state.SirenOn] // if the Siren is on, only allow to turn it off { on TurnOff: state = State.SirenOff; on TurnOn: illegal; } } }
This example shows an interface with two alternative styles to define the actions based on incoming events.
interface IPsm { in void connect(); in void disconnect(); out void connected(); out void error(); behaviour { enum ProtocolState {Disconnected, Connected}; // type declaration ProtocolState state = ProtocolState.Disconnected; // variable declaration bool isError = false; // variable declaration // Alternative 1: using guards based on e.g. state value inside the action statements on connect: { // Select action to be performed based on state variable values. [state.Disconnected && !isError] { // Action connected; // Output event state = ProtocolState.Connected; // Assign to state variable } [otherwise] { // Action error; // Output event isError = true; // Assign to state variable } }
interface IPsm { in void connect(); in void disconnect(); out void connected(); out void error(); behaviour { enum ProtocolState {Disconnected, Connected}; // type declaration ProtocolState state = ProtocolState.Disconnected; // variable declaration bool isError = false; // variable declaration // Alternative 2: using guards based on state variable outside the action statements { [state.Connected] { on disconnect: { [isError] { // Action isError = false; } [otherwise] { // Action state = ProtocolState.Disconnected; } } } [otherwise] { on disconnect: { error; isError = true; } } } } }
Next: Using Guards, Previous: Actions, Up: Specifying Behaviour [Contents][Index]