moore - Moore State Models and Event Dispatch
This manpage describes the moore package which is a Tcl script extension that allows the specification and execution of Moore type state models.
The Moore type of state models associates actions with states and executes the action upon entry into a state. We define a state model to be the invariant definition of states, events and transitions. We define a state machine to be an instance of a state model that has an implicit state variable that holds its current state. All state machines behave independently of each other and all state machines that are instances of the same state model have the same set of states, events and transitions.
Once a state model is defined and a state machine is created, the package supplies commands to generate events to state machines. Events may be delivered asynchronously or synchronously. Asynchronous event delivery uses an internal queue and insures that each state action completes before any other transitions are dispatched. Asynchronous delivery uses the Tcl event loop. Asynchronous delivery can also be delayed, in effect requesting the event to be delivered at some time in the future. Delayed events can also be cancelled and the time remaining for a delayed event can be obtained.
Synchronous event delivery causes an immediate dispatch of the event with the transition and state action executed like any regular procedure. Therefore, state actions may not be completed and complicated, cyclic synchronous event generation can cause undesired results. However for simple isolated state machines, synchronous delivery avoids the need to enter the Tcl event loop.
The package uses an object oriented approach to defining state models and machines, i.e. state models and state machines are represented by commands that have subcommands for operations. We divide the command descriptions into four sections:
Commands that define state models and asynchronous event generation.
Commands that specify the details of a state model.
Commands that instantiate state machines.
Commands that provide for synchronous event reception.
The primary commands of the package are provided as an ensemble and are listed in this section. See the sections below for the other commands provided.
The model subcommand creates a command for a state model called name and records its specification. The return value is a fully qualified command name. If name is not fully qualified, then the command will be created in the current namespace. The definition is evaluated in a context where the MODEL DEFINITION COMMANDS described below are available. These commands are used to define the states, events and transitions of the state model. The returned command is an ensemble command with the subcommands listed below in the STATE MODEL COMMANDS section.
The generate subcommand arranges for the src state machine to deliver event to the target state machine. The - and -> arguments are syntactic sugar and are ignored. The event must be a defined event of the target state machine. When events are generated in a context outside of an executing state action, src should be supplied as the empty string. When the target state machine transitions to a new state, the optional paramN parameters are supplied as arguments to the new state. These arguments must match the number of arguments expected by the state action or a run-time error will be generated.
The delay subcommand arranges for the src state machine to deliver event to the target state machine time milliseconds in the future. The - and -> arguments are syntactic sugar and are ignored. There may be only one delayed event outstanding for a given src / target pair with the same event name. Any attempt to generate a duplicate delayed event results in the previous delayed event being silently cancelled and replaced by the later one at the specified time. Like most timing in Tcl, time represents the minimum number milliseconds that will elapse before the event is posted for delivery.
The cancel subcommand cancels the delivery of any event named, event, that is outstanding between src and target. The - and -> arguments are syntactic sugar and are ignored. Typically, the event is a delayed event generated by the delay command.
The remaining subcommand returns the number of milliseconds remaining before event is delivered from src to target. The - and -> arguments are syntactic sugar and are ignored. A return value of zero implies that no such delayed event was found.
The qwait subcommand dispatches all the events on the event queue. The block argument is a boolean which indicates whether or not the Tcl event loop is entered. By default, the event is entered. If block is false, then the event queue is dispatched without entering the event loop.
The definition argument to the ::moore model command is evaluated as a Tcl script. That script should invoke the following commands to define the properties of the state model. The order of invocation of these commands is arbitrary, i.e. it is not necessary to define all the States before the Transitions.
The State command defines a state of the model named, name. When an event is received by a state machine instance of this state model and the transition causes name state to be entered, then body is executed with the arguments given by args. The args is specified the same as the proc command and the State command is patterned after proc to show the close association of state action to transitioning into a state. When body is invoked, a hidden argument called self is defined and its value is set to the state machine command name for that instance. Execution of body during a transition occurs in the namespace in which the model command is defined. If final is present it is interpreted as a boolean to indicate whether or not the state is a final state. By default and if final is missing, then the state is not a final state and the instance continues to exist after the execution of the action. If final is true (in one of the many ways a boolean may be specified as true), then the state given by name is considered to be a final state. In this case and after body has been executed, then the state machine is destroyed automatically.
The Transition command specifies the transition that a state machine is to make when it is in currState and it receives the event named, event. Receiving event while in currState causes the state machine to transition to newState and to execute the state action associated with newState. The currState must be a state defined by invoking the State command. The newState must be a defined state or one of the special non-transitioning states named IG or CH. If newState is IG, then the event is ignored and no transition takes place. If newState is CH, then the event is deemed logically not to be able to happen and this is logged as an error. It is also a corrollary to the way Moore machine are defined that any event that is causes a transition into a given state must carry with it argument values that match the formal parameters of that state. Failure to do so will result in a run-time error.
Note that no separate command is provided to define event names. The set of events to which a state model responds is gathered from the mention of those event names in Transition command invocations.
The state transitions specified by the Transition command form a conceptual transition matrix. It is allowed to under-specify the matrix, i.e. the entire cross product of states and events does not have to be supplied in Transition command invocations. Any transition that is not specified by a Transition command will default to the value given to the DefaultTrans command. If there is no DefaultTrans command invocation in a state model definition, then the default transition is taken to be CH.
When a state machine is created, it can be optionally be placed in any of its states. If no initial state is supplied when the state machine is created, then it will be placed in the state state. If the state model definition does not include an invocation of InitialState then the first defined state is taken as the default initial state.
The following shows an example of a simple two-state state model. Note that state s2 contains an self directed event generation.
::moore model m1 { State s1 {a} { chan puts $a } Transition s1 - e1 -> s2 Transition s1 - e2 -> IG State s2 {a b} { chan puts "$a $b" ::moore generate $self - e2 -> $self $a } Transition s2 - e2 -> s1 }
The return value of ::moore model is an ensemble command that has the following subcommands.
The machine subcommand creates a state machine and places it in initialState. If initialState is missing, then the state machine is placed in the default initial state defined when the state model was specified. The return value is a fully qualified command name, based on name. If name is not fully qualified, then the returned command is created in the current namespace. Although the new state machine is placed in initialState, the action associated with initialState is not executed.
The following example creates a state machine, i1, from state model, m1, and places i1 initially in state s2.
m1 machine i1 s2
The instances command returns a list of state machine commands that have been created from the given model.
The states command returns a list of the state names for the given model.
The states command returns a list of the events names for the given model.
The dot subcommand returns a string which the representation of the directed graph of the state model in the syntax of dot(1) (see graphviz for detail on the dot program).
The dotfile subcommand invokes the dot subcommand and places the result into the file given by, filename.
The draw subcommand invokes the dot subcommand handing the output to dot(1) to render the state model graph in PostScript. Additional arguments to dot(1) may be present. By default dotargs is set to -Tps -o%s.ps -Gsize=7.5,10 to produce a letter sized, portrait layout of the graph. All occurrences of %s in the dotargs are replaced by the name of the state model.
The destroy subcommand deletes the state model and cleans up the internal resources used. N.B. deleting a state model by necessity also deletes all the state machine instances of that state model. Destroying a state model is rarely used.
The return value of invoking a model machine command is a state machine command ensemble that has the following subcomands.
The receive command performs a synchronous reception of event, transitioning the machine and executing the state action of the new state with the values given by the paramN arguments. This command may be invoked to accomplish the synchronous delivery of event with it parameters and is the same command executed internally when asynchronously delivered events are dispatched.
The force command forces a transition from the current state to the state given by state. Optional paramN parameters must be given to match the signature of state. This command is sometimes useful for error or reset processing.
The configure command queries and modifies state machine options. Each state machine implicitly has a dictionary of options that may set set or queried. If no option arguments are present, then the command returns a list of the available option keys. If a single option argument is present, then the command returns a dictionary consisting of the single key and its corresponding value. If one or more option value pairs are present, then the machine's option dictionary is set according the options and values supplied. In this case the command returns the empty string.
The cget command returns the value that corresponds to option from the machine's option dictionary.
The destroy subcommand deletes the instance of the state machine returning any resources in use.
The moore package uses ::logger::initNamespace to provide logging facilities. To trace the event dispatch and transition information for a particular state machine it is necessary to set the trace option on the machine to true (via the configure subcommand) and to set set the logging level to info. Any errors encountered in asynchronous event dispatch are reported at the error logging level.
Moore, States