SourceForge.net Logo

Structured State Machines.

Introduction.

Structured State Machines (SSM's) form the basis of PlanB. This page provides an overview of the concepts involved. If you are not familiar with SSM's and PlanB this is a good place to start, since everything else depends on it.

Finite state machines hav been around for quite some time and a fair amount of tinkering, rethinking, extending and so forth has been done. One of the major improvements was the concept of Hierarchical State Machines, of which SSM's are a specialisation.

Knowledge of HSM's and FSM's is therefore assumed. If you are not familiar with HSM's, there are good books around, especially the "UML userguide" deserves a mention in this respect. If you are not familiar with finite state machines, you should get educated on those, first.

Compound states.

The primary structural element in HSM's is the compound state. This is simply a state which is composed of a number of substates, which in turn may be other compound states having more substates, etc ad nauseam. The whole HSM can be imagined as a tree with compound states being the nodes and the traditional states being leaves.

The above implies that, in contrast to traditional FSM's, the HSM can be in more than one state at a time. In fact, if it is in some substate, you can be sure it is in the enclosing state aswell, which will be a substate to yet another enclosing state unless it is the root state of the entire HSM. So in fact most of the time a HSM will be in more than one state at a time. If not, your HSM degenerated into a simple flat FSM.

Since the HSM is in every state on the path from the current leaf state to the root state simultaneously, a stack much like the one used in more traditional (that is, sequential) programming envoronments. PlanB uses a special stack structure aptly called "The State Stack" to store the current states.

SSM's are very much like HSM's, but impose a number of rules, which are intended to satisfy the first word of the term and hence make HSM's more suitable for use as basic programming concept as opposed to the traditional sequential approach.

  1. Each compound state should have one and only one welldefined initial state.
  2. Each compound state should have at least one welldefined final. state.
  3. Transitions may occur only between states with the same enclosing. state.

In addition to that, there are a number of rules for transitions.

  1. Transitions are atomic, PlanB handles only one transtions at a time. This prevents many concurrency problems from occurring.
  2. Events are handled completely. This means that not only the transition resulting directly from an event is handled, but also all triggerless transitions resulting from it. This means the system is always in a well-defined state when an event is handled.

Gates.

Think of the gates at an airport, these are the gates 'control' passes through when trasitioning from one state to another. They belong to states and in fact make up a substantial part of their definition. At the time these gates are invoked, the state they belong to is guaranteed to be top-of-stack.

There are three:

Enter, passed just after a state is pushed or set onto the stack. All state parameters are on stack anc can be accessed. The state of wich the 'enter' gate is invoked is always at the top of the stack.
Leave, passed just before a state is removed from stack. The target state is known and no other transition can be scheduled. The state of wich the 'leave' gate is invoked is always at the top of the stack.
Abort, passed whenever an SSM is terminated externally, either by plan (see "Concurrent States, Racing and Joining", or "System, Kill") or by mishap (see "System, Error and exception handling").

No action is required (apart from defining them), PlanB makes sure they are called automatically in the proper sequence (leaf to root). In the absense of a defined gate, the default action will be taken. Right at the moment this is "do nothing" in the case of 'enter' and 'leave', and "try the leave-gate" in case of the abort-gate.

Transitions.

Transitions can be classified into a number of catagories, each having a different set of properties and effects.

Internal or drop transition.

This (basically) does nothing except signal the kernel that the event has been handled. It will therefore not be handled by an enclosing state, but the current state is unchanged and no gates are passed.

The 'Internal' in the first alias refers to the fact that in schema techniques which allow for it, this type is drawn on the inside of the state box. The external selftransition is a set-transition (see below) with the current ssm as target and will pass the enter and leave gates.

Set transition. Replaces the state at the top of the stack with the current state. Enter and leave gates are passed as required.
Push transition. The hallmark of a compound state. The current state remains on stack and the target state is pushed onto the stack to become the new top-state. Note that the leave bgate is not passed
Final or pop transition. The reverse of the push transition, this one pops the top state off the stack. An appropriate message (DONE or FAILED) should always be posted if this type of transition is scheduled.

These transitions provide the main functionality of SSM's and they are very flexible. The concept of push and pop transitions allows easy allocation and deallocation of stack frames carrying the state information and the push transition allows for other tricks, too (see "State arguments and locals" and "Exception states").

Triggerless transitions and compound states.

Triggerless transitions are implemented rather trivially by setting a target in the enter-gate using one of "set-transition" or "push-transition". A triggerless "pop-transition" is perfectly legal, too, but seems a bit pointless.

In much the same way, compound states can be implemented by simply doing a push-transition, either hardcoded in the enter-gate of some prefab compound state with a selector, passed as an argument, stored in some local variable or a global system wide store. As long as "push" gets a proper argument, the programmer can do what he feels is neccesary.

It is in fact the prime example of how the SSM abstraction allows very flexible coding. The triggerless transition, like the compound state follow from the abstraction, they are merely one way to realize it.

States

The central concept of SSM's, HSM's and FSM's of all kinds. A state, as far as SSM's in PlanB are concerned consist of a structure containing pointers to the gates defined above and a routine which actually handles the events (aptly called the event handler.

Initial state.

The initial state is no more than first state a compound state will enter. It is not special in any way and can be any state. The only place where it's specified is the argument of the "b_ssm_push()" primitive.

Final state.

In fact, these are not states at all. PlanB has two different flavours.

The effect of edging to these states is that the current stack frame is popped off the state stack and an event is sent to the enclosing state notifying it of the completion. The term 'state', therefore, is a bit metaphorical, since the ssm will never be in any real state called 'Done' or 'Failed'.