W3C

State Chart XML (SCXML): State Machine Notation for Control Abstraction 1.0

W3C Working Draft 5 July 2005

This version:
http://www.w3.org/TR/2005/WD-scxml-20050705/
Latest version:
http://www.w3.org/TR/scxml/
Previous version:
This is the first version.
Editors:
RJ Auburn, Voxeo
Jim Barnett, Aspect Communications
Michael Bodell, Tellme Networks
T.V. Raman, IBM

Abstract

This document describes SCXML, or the "State Chart eXtensible Markup Language". SCXML provides a generic state-machine based execution environment based on CCXML and Harel State Tables.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is the first Public Working Draft of SCXML for review by W3C Members and other interested parties, and has been developed by the Voice Browser Working Group (W3C Members only) as part of the W3C Voice Browser Activity.

SCXML is a candidate for the control language within VoiceXML 3.0 (currently under development by the Voice Browser working group), CCXML 2.0 (anticipated development in 2006 by the Voice Browser working group), and the multimodal authoring language (under development by the Multimodal Interaction working group).

Comments for this specification are welcomed to www-voice@w3.org (archives).

This document was produced under the 5 February 2004 W3C Patent Policy. The Working Group maintains a public list of patent disclosures relevant to this document; that page also includes instructions for disclosing [and excluding] a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) with respect to this specification should disclose the information in accordance with section 6 of the W3C Patent Policy.

Per section 4 of the W3C Patent Policy, Working Group participants have 150 days from the title page date of this document to exclude essential claims from the W3C RF licensing requirements with respect to this document series. Exclusions are with respect to the exclusion reference document, defined by the W3C Patent Policy to be the latest version of a document in this series that is published no later than 90 days after the title page date of this document.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

Table of Contents

1 Terminology
2 Overview
3 Basic State Notation
    3.1 SCXML
        3.1.1 Properties
    3.2 STATE
        3.2.1 Properties
    3.3 TRANSITION
        3.3.1 Properties
    3.4 PARALLEL
        3.4.1 Properties
4 Pseudo-States
    4.1 INITIAL
        4.1.1 Properties
    4.2 HISTORY
        4.2.1 Properties
    4.3 JOIN
        4.3.1 Properties
    4.4 SYNCH
        4.4.1 Properties
5 Executable Content
    5.1 Variables and Expressions
        5.1.1 <assign> and <var>
            5.1.1.1 Overview
            5.1.1.2 <var> Attribute Details
            5.1.1.3 <assign> Attribute Details
    5.2 Event Control
        5.2.1 <send>
            5.2.1.1 Overview
            5.2.1.2 Attribute Details
        5.2.2 <cancel>
            5.2.2.1 Overview
            5.2.2.2 Attribute Details
    5.3 Flow Control Elements
        5.3.1 <if>
            5.3.1.1 Overview
            5.3.1.2 Attribute Details
        5.3.2 <elseif>
            5.3.2.1 Overview
            5.3.2.2 Attribute Details
        5.3.3 <else>
            5.3.3.1 Overview
            5.3.3.2 Attribute Details
    5.4 Debugging Elements
        5.4.1 <log>
            5.4.1.1 Overview
            5.4.1.2 Attribute Details
6 Conditional Expressions
    6.1 Special Predicates
        6.1.1 In
            6.1.1.1 Overview
            6.1.1.2 Attribute Details
7 Related Work

Appendices

A Open Issues
    A.1 Empty Event Property of Transition
    A.2 Scoping Rules for ID
    A.3 State Templates
    A.4 XML Content in Send
    A.5 junction, choice, fork, and join
    A.6 Automatic Logging
B Schema
C CCXML to SCXML Conversion
D Examples
    D.1 Language Overview
E An Overview of Harel State Table Notation and Semantics
    E.1 A Simple State Machine
    E.2 Executing Actions On Entering And Exiting
    E.3 Complex States
    E.4 Parallel States
    E.5 Concurrency And Event Queues
    E.6 Synchronizing And Concurrency
    E.7 Sync Explained
    E.8 Microwave Oven
F References


1 Terminology

[Definition: The key words must, must not, required, shall, shall not, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [IETF RFC 2119].]

The terms base URI and relative URI are used in this specification as they are defined in [IETF RFC 2396].

2 Overview

This document outlines a state machine notation that combines concepts from CCXML and Harel State Tables. It is intended to be a general-purpose state machine language that can be used in multiple contexts, including VoiceXML 3.0, CCXML 2.0, and the MultiModal Interaction framework. CCXML [W3C CCXML 1.0] is an event-based state machine language designed to support call control features in Voice Applications (specifically including VoiceXML but not limited to it). The CCXML 1.0 specification defines both a state machine and event handing syntax and a standardized set of call control elements. Harel State Tables are a state machine notation that are part of UML [UML 1.5]. They offer a clean and well-thought out semantics for sophisticated constructs such as a parallel states. They have been defined as a graphical specification language, however, and hence do not have an XML representation. The goal of this document is to combine Harel semantics with an XML syntax that is a logical extension of CCXML's state and event notation. For an overview of the UML notation and a brief outline of its semantics, see E An Overview of Harel State Table Notation and Semantics, below.

For simplicity's sake, the language definitions below refer to the 'properties' of elements, without specifying whether said properties are attributes or children. The markup samples at the end of the document make specific decisions about what is an attribute and what is a child element, but we may revise these decisions as refine the definitions.

For concreteness sake, we use ECMAScript as the language for data elements, but the complete language definition will permit other languages such as XPath to be used as well.

3 Basic State Notation

3.1 SCXML

Top-level root element. Carries version information etc. We may decide that we don't need a special root element, particularly since the purpose of this notation is to be embedded in other languages, such as VoiceXML 3.0.

3.1.1 Properties

  • initialstate Identifies the top-level state for the document .

  • xmlns

  • version

3.2 STATE

Holds the representation of a state machine.

3.2.1 Properties

  • id Identifier for this state.

  • src Optional URL of a file containing the definition of this state. Any definitions within the body of the state element override those in the external file.

  • final Boolean property indicating whether this is a final state or not. Default value is false . Final states may not have substates or outgoing transitions. When a final state is entered, a completion event "parentID.done" is generated, where "parentID" is the id of this state's parent state.

  • onentry Optional property holding executable content to be run upon entering this state.

  • onexit Optional property holding executable content to be run when exiting this state.

  • transition Defines an outgoing transition from this state. May occur 0 or more times.

  • state Defines a sequential substate of the parent state. May occur 0 or more times. Incompatible with the parallel property.

  • initial A child which identifies initial state for state machines that have substates. This child is required if and only if the machine has one or more state children.

  • history A child which represents the descendant state that the parent state was in the last time the system transitioned from the parent. A transition with this state as its target is in fact a transition to one of the other descendant states of the parent. May occur 0 or more times.

  • parallel Defines a set of parallel substates. May occur 0 or 1 times. Incompatible with the state property.

3.3 TRANSITION

Transition rules are triggered by events and conditionalized via guard-conditions. The optional property target specifies the destination of the transition, which may be a state or a parallel region. If the target property on a transition is omitted, then taking the transition has the effect of leaving the machine in the same state after invoking any executable content that is supplied via the actions property. Such a transition is equivalent to an 'event' handler in HST notation. Note that this is different from a transition whose target is its source state. In the latter case, the state is exited and reentered, triggering execution of its onentry and onexit executable content.

The target property may specify the destination by id or in-line. In the latter case, the in-lined state is private to the transition in the sense that no other transition may take it as a target. This convention allows an in-lined state to be used as a form of scratch state which is visible only locally.

3.3.1 Properties

  • event Property that specifies the trigger for this transition. We have not determined if it is optional. Wildcarded event names are supported.

  • cond Optional guard condition. If it is present, the transition is taken only if the guard condition evaluates to true.

  • target Optional property that specifies the new state or parallel element to transition to. May be specified by reference or in-line. May occur multiple times, but if more than one instance is present, all must specify descendants of the same parallel element. target may not co-occur with exit)

  • exit Used as a shorthand for defining a transition to an empty final state. (Exclusive with target) As an example the following two transitions are the same:

  • <transition>
      <exit/>
     </transition>
                
    <transition>
     <target>
      <state final="true"/>
     </target>
    </transition>
    
  • actions Immediate children of transition other than those listed above are executable content that is run after the onexit handler for this state and before the onentry handler in the target state.

3.4 PARALLEL

Wrapper element to encapsulate parallel state machines. The parallel element has onenter and onexit properties analogous state. In addition, the parallel element holds a set of state elements that execute in parallel and join at the onexit handler of element parallel. In particular, when all of the parallel substates reach a final state, a completion event "ID.done" is generated, where "ID" is the id of the parallel element. Either the parallel element or one of its ancestors can trigger a transition off this event, at which time the onexit handler of the element will be executed.

For the parallel element to be useful, each of its state substates must itself be a complex state, i.e., one with either state or parallel children. When the state machine enters the parent parallel element, it simultaneously enters each child state. Transitions wihthin the individual child elements operate normally, but there may not be transitions between the child elements since that would violate the semantics of parallelism. However any of the child elements may take a transition outside the parallel element. When this happens, the parallel element and all of its child elements are exited and the corresponding onexit handlers are executed. The handlers for the child elements execute first, in no determinate order, followed by that for the parent parallel element, followed by an action expression in the transition element, and then the onentry handlers in the target state.

3.4.1 Properties

  • id

  • onentry

  • onexit

  • state Defines a parallel substate region. May occur 1 or more times.

4 Pseudo-States

The following elements are called 'pseudo-states' because they do not have the full properties of states (for example they lack onentry and onexit handlers) and do not map to states in the underlying semantics of the language. However, they can be used like states in many places. In particular, they can often be the target of transition. They are a notational shorthand allowing the simple statement of some sophisticated control constructs.

4.1 INITIAL

This element represents the default initial state for a complex state with sequential substates. Suppose state S1 has child states S11, S12, and S13. if the system is in S1, it must also be in one (and only one) of S11, S12, or S13. A transition in a distinct stateS2 may take S11, S12, or S13 as its target, but it may also simply specify the parent S1. In that case, the initial child of S1 specifies which of S11, S12, or S13 the system should transition to.

4.1.1 Properties

  • id Identifier for this pseudo-state

  • src Optional URL of a file containing the definition of this pseudo-state. Any definitions within the body of the initial element override those in the external file.

  • transition A conditionless transition (i.e., one without a cond or event property). Such a transition is always enabled and will be taken as soon as the state is entered. The target of the transition must be a descendant of the parent state of initial. if stateS1 has an initialchild with a transition with target S12, there is no semantic difference between a transition that takes S1 as its target and one that takes S1's initial child as a target and one that takes S12 as its target. The result in all three cases is that the system enters both S1 and S12 as an atomic action, executing the onentry handlers of first S1 and then S12.

4.2 HISTORY

The history pseudo-state allows for 'pause and resume' control flow. Whenever a complex state is exited, its history pseudo-state, if present, records the state configuration at exit. Later a transition taking the history state as its target allows the state to pick up where it left off.

4.2.1 Properties

  • id Identifier for this pseudo-state

  • src Optional URL of a file containing the definition of this pseudo-state. Any definitions within the body of the initial element override those in the external file.

  • type. Legal values are 'shallow' and 'deep', with default value 'shallow'. if the value is 'shallow' then this state records only the immediate children of the parent state. In this case a transition with the historypseudo-state as its target will end up in the immediate child state that the parent was in the last time it was exited. On the other hand, if this property is set to 'deep', the history pseudo-state will remember nested states. In this case a transition with the history pseudo-state as its target will end up in the mostly deeply nested descendant state the parent was in the last time it was exited.

  • transition A conditionless transition (i.e., one without a cond or event property). Such a transition is always enabled and may be taken as soon as the state is entered. This transition represents the default history state and indicates the state to transition to if the parent state has never been entered before. if type is 'shallow', then the target of this transition must be an immediate child of the parent state. Otherwise it can be any descendant state.

4.3 JOIN

The join pseudo-state provides barrier logic allowing the synchronization of defined threads of control. For a discussion of its semantics see E An Overview of Harel State Table Notation and Semantics.

4.3.1 Properties

  • id An identifier for this pseudo-state.

  • transition. May occur one or more times. May not contain an event. At least one instance must not contain cond guard condition. Note: All incoming transitions must be unconditional.

4.4 SYNCH

The sync state is actually a normal state, not a pseudo-state, but it is included here because of its close association with the join pseudo-state. For a discussion of its semantics see E An Overview of Harel State Table Notation and Semantics.

4.4.1 Properties

  • id Identifier for this state.

  • transition. Must occur once or more and not have either cond or event properties. The target must be a join pseudo-state.

  • bound. An integer which can be used to turn the sync state into a semaphore. Default value: unlimited.

5 Executable Content

Executable Content consists of actions that are performed when the selected handler is executed. In general, such content must be able to set variables, raise events, and invoke functionality in the underlying platform. On the other hand, Executable Content may not cause transitions or any form of change of state, except indirectly, by raising events that are then caught by transitions. There are a variety of possible forms for Executable Content, particularly since the capabilities of the underlying platform vary across implementations. The content presented here is closely based on that in CCXML. This is partly for reasons of backward compatibility, but also because CCXML's executable content is quite flexible, consisting of Flow Control Elements, Event Control Elements or Custom Action Elements.

Flow Control Elements are used to control the flow of execution within Executable Content.

Event Control Elements are used to control how and when events are sent from SCXML.

Custom Acton Elements can be defined in other specifications/namespaces and are responsible for performing actions on behalf of custom components. Logically Custom Acton Elements can be thoughts of a collection of actions and handlers to perform specific tasks. An example of this is a CCXML <accept> element that is a Custom Acton Element:

<transition event="ccxml:connection.alerting" name="evt">
  <ccxml:accept connectionid="evt.connectionid"/>
</transition>

This could be written using a <send> element using the following syntax:

<transition event="ccxml:connection.alerting" name="evt">
  <var name="connectionid" expr="evt.connectionid"/>
  <send targettype="ccxml" event="ccxml:accept" namelist="connectionid"/>
</transition>

A more complicated example might be a CCXML <createcall> where you are both providing variables and getting values back that using only the <send> syntax would be more complex as it would need to be broken over several steps. For example:

<onentry>
  <ccxml:createcall dest="'tel:+18315552020'" connectionid="myConnectionID"/> 
</onentry>

Would need to be modeled in two steps using <send> as you would need to do something like the following:

<onentry>
  <var name="dest" expr="'tel:+18315552020'"/>
  <send targettype="ccxml" event="ccxml:createcall" namelist="dest"/>
</onentry>
<transition event="ccxml:createcall.success" name="evt">
  <var name="connectionid" expr="evt.connectionid"/>
</transition>

The exact mappings between Custom Action Elements and <send> actions are to be defined in the individual Custom Action Element specifications.

5.1 Variables and Expressions

5.1.1 <assign> and <var>

5.1.1.1 Overview

Variables are declared using the <var> element and are initialized with the results of evaluating the optional expr attribute as an expression. If the expr attribute is not present in the <var> declaration, the variable is initialized to undefined. The values of variables may be subsequently changed with <assign>.

Variables are declared explicitly by <var> :

<var name="sessionid" />
<var name="currentstate" expr="'initial'" />

Variables can be assigned new values using <assign> :

<assign name="currentstate" expr="'cleanup'" />

The implementation MUST evaluate the expression contained in the expr attribute of <assign>, and assign the results to the variable referenced in the name attribute.

5.1.1.2 <var> Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
name true Variable name none Valid Variable name Indicates the name of the variable.
expr false Expression none Valid Expression Indicates the new value of the variable. This is the initial value.
5.1.1.3 <assign> Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
name true Left Hand Side Expression none Variable An left hand side expression evaluating to a previously defined variable. The value of the attribute will receive the result of the expr attribute.
expr true Expression none Valid Expression Indicates the new value of the variable.

5.2 Event Control

5.2.1 <send>

5.2.1.1 Overview

<send> is used to send messages containing events or other information directly to another SCXML Interpreter, other external systems using an Event I/O Processor or to raise events in the current SCXML session.

The event target of <send/> is specified using the target and targettype attributes. These attributes control how the platform should dispatch the event to its final destination.

The target attribute specifies the unique identifier of the event target that the Event I/O Processor should send the event to. This can be the value of a SCXML Session ID to another SCXML session. In the case where you are using some other Event I/O Processor this attribute should be able to describe how to connect to the event destination (For example a SIP URL for SIP-INFO messages or a HTTP URL for Web Services). If no target attribute is specified the default target is the current SCXML session. If the value of the target attribute is not supported, invalid or unreachable by the Event I/O Processor the Platform MUST throw a error.send.targetunavailable event.

The targettype attribute controls what Event I/O Processor the event should be sent to. The default value of this attribute is 'ssxml'. If the event targettype specified is not supported the platform MUST throw a error.send.targettypeinvalid event.

A platform must support the following values for the targettype attribute:

Value Details
scxml SCXML Session Event Processor.

Platforms may support other types of Event I/O Processors, for example: Web-services, SIP or basic HTTP GET. However, platforms SHOULD name the Event I/O Processor beginning with "x-" to signify that they are platform dependent.

<send> also specifies the content of the message to be sent. <send> may specify message content in one of two ways (the following mechanisms are mutually exclusive):

  • event attribute with an OPTIONAL namelist

    • The event attribute specifies an expression that returns the name of the event.

    • The namelist attribute specifies a space separated list of variables to be included with the message.

    <var name="target" expr="'tel:+18005551212'"/>
    <var name="content" expr="'http://www.example.com/mycontent.txt'"/>
    <send target="target" targettype="'x-messaging'" event="'fax.SEND'" namelist="content"/>
    


  • xmlns attribute with explicit content inline XML content specifying the message to sent the xmlns:<namespace> defines a namespace for the inline content

    <send target="'csta://csta-server.example.com/'"
          targettype="'x-csta'"
          xmlns:csta="http://www.ecma.ch/standards/ecma-323/csta">
          <csta:MakeCall>
            <csta:callingDevice>22343</callingDevice>
            <csta:calledDirectoryNumber>18005551212</csta:calledDirectoryNumber>
          </csta:MakeCall>
    </send>
    


If an explicit namespace is provided as in the xmlns attribute of the <send>, this namespace can be used to validate the content of the <send>. A namespace specified on a <send> applies only to the attributes and content of the <send>. Multiple namespaces MAY be included in the <send> to associate message content with more than one namespace.

When an explicit namespace is specified for the <send>, the content of the <send> is parsed but can be ignored by the sending SCXML Interpreter until the <send> is executed. XML namespace identifiers contained in the <send> MUST be preserved and it is the responsibility of the Event I/O Processor responsible for forwarding events to the <send> target to parse the incoming message and remove the namespace prefix, if required by the <send> target.

The sending SCXML Interpreter MUST NOT alter the content of the <send>. The data contained within a <send> MUST be sent to the destination specified in the target attribute of <send> using the Event I/O Processor specified by the targettype attribute. When <send> is used with inline XML content, and the target is a SCXML session, the mapping of that XML content to event object properties is implementation-specific, and outside the scope of this specification. Although the full set of requirements for the Event I/O Processor is not within the scope of this specification, an event processor sending an event to a SCXML Interpreter is required to generate an event which can be processed in a SCXML Session. See Section 9.1 for details regarding the processing of incoming events by an SCXML Interpreter.

When a message is successfully sent to the target, a send.successful event will be thrown. Note that this does not mean that the target processed the message successfully. It is up to the target to generate events specific to the message. These events are application specific.

If the send request fails, an event signifying the error will be returned to the SCXML Session. The failure events are documented at the end of this section.

5.2.1.2 Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
event false This attribute may not be specified in conjunction with inline content Expression none An expression which returns a character string that indicates the type of event being generated. The event type may include alphanumeric characters and the "." (dot) character. The first character may not be a dot or a digit. Event type names are case-insensitive. If neither the data attribute or inline content is specified, an error.fetch event will be thrown. If used in conjunction with the inline content, an error.fetch will be thrown.
target false Expression none A valid target URL An expression returning the target location of the event. The target attribute specifies the unique identifier of the event target that the Event I/O Processor should send the event to.
targettype false Expression scxml scxml An expression which returns a character string that specifies the type of the Event I/O Processor that the event should be dispatched to. Values defined by the specification are:
  • scxml - This species that the event will be dispatched to the SCXML Session Event Processor.

sendid false Left Hand Side Expression none Variable An left hand side expression evaluating to a previously defined variable. The value of the attribute will receive an internally generated unique string identifier to be associated with the event being sent. If this attribute is not specified, the event identifier is dropped.
delay false Expression '0s' An expression which returns a character string in CSS2 [CSS2] format The character string returned is interpreted as a time interval. The send tag will return immediately, but the event is not dispatched until the delay interval elapses. Timers are useful for a wide variety of programming tasks, and can be implemented using this attribute. Note: The queue for sending events is maintained locally. Any events waiting to be sent will be purged when the session that issued this request terminates.
xmlns:[YourNameSpacePrefix] false string none This returns a namespace identifying the contained message format. More than one xmlns attribute may be included.
namelist false This attribute may not be specified in conjunction with inline content Var List none List of Variable names A list of zero or more whitespace separated CCXML variable names to be included with the event. When an variable is included with the event, its value is first converted into a string. If the variable is an Object, the mechanism by which it is included is not currently defined. Instead of including Objects directly, the application developer may explicitly include the properties of an Object. e.g. "date.month date.year". If used in conjunction with the inline content, an error.fetch will be thrown.
hints false Expression none An expression. The data returned contains information which may be used by the implementing platform to configure the event processor. The meaning of these hints is specific to the implementing platform and the event processor.

5.2.2 <cancel>

5.2.2.1 Overview

When a SCXML program uses <send> to send an event and includes a delay attribute, the <cancel> command will cancel the pending event, if possible.

The cancel operation will cancel a pending event by removing it from the event queue of the SCXML session from which it has been sent. If the delay has expired and the event has already been removed from the event queue, the <cancel> request will fail and an error.notallowed event will be delivered to the event queue of the SCXML session that executed the <cancel>.

The <cancel> element may be used to cancel events delivered to local or remote SCXML sessions. Compliant SCXML implementations are REQUIRED to support the cancellation of local events but may choose not to support the cancellation of remote events in which case an error.notallowed event should be thrown for such requests. The format of the event identifier returned by a <send> request, and specified in the sendid attribute of <cancel>, is implementation specific but is expected to uniquely define events across SCXML sessions.

5.2.2.2 Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
sendid true Expression none A valid event identifier An expression which returns the value of the event identifier that was received when the send command was issued.

5.3 Flow Control Elements

5.3.1 <if>

5.3.1.1 Overview

<if> is a container for conditionally executed elements. <else> and <elseif> can optionally appear within an <if> as immediate children, and serve to partition the elements within an <if>. <else> and <elseif> have no content. <else/> is a synonym for <elseif cond="true"/>.

Each partition within an <if> is preceded by an element having a cond attribute. The initial partition is preceded by the <if> and subsequent partitions by <elseif>s (or <else>s). The first partition in document order with a cond that evaluates to true is selected. <else> always evaluate to true. A partition may be empty.

If an <if> has no immediate <elseif> or <else> children, the full contents of the <if> will be selected when the cond attribute is true.

<else> was chosen to match similar concepts in other languages, and supports examples such as

<if cond="...">
  <!- selected when <if cond> is true ->
  <else/>
  <!- selected when <if cond> is false ->
</if>
           

However, <else> is a synonym for <elseif cond="true"/>, so an example such as:

<if cond="...">
  <!- selected when <if cond> is true ->
  <else/>
  <!- selected when <if cond> is false ->
  <else/>
  <!- never selected ->
</if>
 

is also possible and must be interpreted as:

<if cond="...">
  <!- selected when <if cond> is true ->
  <elseif cond="true"/>
  <!- selected when <if cond> is false ->
  <elseif cond="true"/>
  <!- never selected ->
</if>

With this definition for <else>, a valid XML [XML] document is also a valid SCXML document.

5.3.1.2 Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
cond true Expression none A valid expression An expression which can be evaluated to true or false.

5.3.2 <elseif>

5.3.2.1 Overview

An <elseif> partitions the content of an <if>, and provides a condition that determines the selection of the partition it begins. <elseif> can appear optionally as an immediate child of an <if>.

5.3.2.2 Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
cond true Expression none A valid expression An expression which can be evaluated to true or false.

5.3.3 <else>

5.3.3.1 Overview

<else> is a synonym for <elseif cond="true"/>.

5.3.3.2 Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
none none else is a synonym for elseif cond="true".

5.4 Debugging Elements

5.4.1 <log>

5.4.1.1 Overview

<log> allows an application to generate a logging or debug message which a developer can use to help in application development or post-execution analysis of application performance. The manner in which the message is displayed or logged is platform-dependent. The usage of label is platform-dependent. The use of <log> SHOULD have no other side-effects on interpretation. <log>is an empty element.

5.4.1.2 Attribute Details
Name Required Attribute Constraints Type Default Value Valid Values Description
label false Expression none An expression which returns a character string which may be used, for example, to indicate the purpose of the log.
expr true Expression none An expression evaluating to a string to be logged.

6 Conditional Expressions

This section describes the content that can be placed in guard conditions inside cond elements in a transition. In general, a restricted subset of executable content is permitted, namely that which evaluates to a boolean and does not have side effects. (Note that in particular send is not permitted inside cond.) In addition to general side-effect free executable content, certain extra predicates are defined, as defined below.

6.1 Special Predicates

6.1.1 In

6.1.1.1 Overview

The In predicate allows guard condition in one state to test whether the system is also in another state. This is useful in parallel regions.

6.1.1.2 Attribute Details
  • state The id of a state. The expression returns true if the system is currently in that state.

7 Related Work

A number of other XML-based state machine notations have been developed, but none serves the same purpose as SCXML. XMI [UML XMI] is a notation developed for representing UML diagrams, including Harel State charts. However it is intended as a machine interchange format and is not readily authorable by humans. ebXML [OASIS ebXML] is a language for business process specification intended to support B2B e-commerce applications. It contains a state machine language that is in some ways similar to the one presented here, but its syntax and semantics are closely tied to its intended use in e-commerce. It is therefore not suitable as a general-purpose state machine language. XTND [XTND], also called XML Transition Network Definition, is a notation for simple finite state machines but lacks Harel's notions of hierarchical and parallel states and are thus not suitable for a general-purpose state machine that is semantically equivalent to Harel statecharts.

A Open Issues

A.1 Empty Event Property of Transition

Issue (IssueEmptyEventOnTransition):

Can the event property of transition be empty? If so, the transition would be triggered whenever its guard evaluated to true . This can be a useful feature, but may be difficult to implement.

Resolution:

None recorded.

A.2 Scoping Rules for ID

Issue (IssueScopeRulesForID):

What are the scoping rules for id? It should certainly be unique within the document, but it would be difficult to insure uniqueness across multiple documents, especially if you are including an existing machine.

Resolution:

None recorded.

A.3 State Templates

Issue (IssueStateTemplates):

Need to define exactly how state templates work. Suppose the template contains a transition for event Foo with cond P1, while the in-line definition defines a transition for Foo with cond P2. Does the resulting state contain both transitions or just the second?

Resolution:

None recorded.

A.4 XML Content in Send

Issue (IssueXMLSend):

What happens when an SCXML session sends XML content to itself or another SCXML session?. Is the XML data automatically converted to ECMAScript?

Resolution:

None recorded.

A.5 junction, choice, fork, and join

Issue (IssuePseudo_states):

Do we need junction, choice, fork and join pseudo-states? They are mostly a graphical convenience in UML and don't add anything to the actual semantics of the language. junction and choice states have one or more incoming transitions and multiple outgoing ones with a case-statement logic. Thus their semantics are "if x go to S1, else if y go to S2 else go to S3". They are thus equivalent to having multiple transitions with the same conditions in the source state. Thus their only purpose is to make the lines neater in a graphical representation. Similarly, fork pseudo-states have one or more incoming transitions and multiple outgoing transitions which are all taken simultaneously once the state is entered. The targets of the outgoing transitions must all be the same parallel region. A transition entering a fork pseudo-state is thus exactly equivalent to one with multiple values for target, one for each of the outgoing transitions from the fork pseudo-state. Finally the join pseudo state has multiple incoming transitions, which must all be from the same parallel region, and one or more outgoing transitions. The outgoing transition is taken only when all of the incoming ones have been taken. Thus the join pseudo-state provide barrier logic allowing different threads of control to wait for each other. But that functionality is already present in our definition of parallel.

Resolution:

None recorded.

A.6 Automatic Logging

Issue (logging):

Should we add some form of automatic logging, e.g., of all events and transitions? This would be a convenience for authors and could be controlled via a log-level attribute on state, allowing authors to control the amount of logging on a per-state basis. Would we then need to specify the format of the logged data? Whether it was written to a file or sent to a database? Or can we just specify that certain data be logged and leave all details up to the implementation?

Resolution:

None recorded.

B Schema

A RELAX NG Schema is available for the markup proposed in this specification and examples

Download SCXML.rng

C CCXML to SCXML Conversion

One of the goals of the SCXML activity is to make sure that the resulting language is compatible with CCXML and that there is an easy path for CCXML scripts to be converted to SCXML without major changes to the programing model or document structure. To help facilitate this the working group has developed a XSLT script to convert a CCXML document into SCXML.

Note: This XSLT assumes that the CCXML working group develops a standalone set of events and Custom Action Elements for SCXML. This XSLT is currently only a prototype and is currently only shown as an example of how a script like this may work in the future.

Download CCXMLtoSCXML.xsl

CCXMLtoSCXML.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ccxml="http://www.w3.org/2002/09/ccxml"
    xmlns="http://www.w3.org/2005/07/scxml"
    xmlns:str="http://exslt.org/strings"
    version="1.0">
    <xsl:preserve-space elements="*"/>
    <xsl:output
        method="xml"
        standalone="yes"
        indent="yes"
        encoding="UTF-8"/>
    <xsl:template match="/ccxml:ccxml">
        <!--
        -
        - Take the <ccxml/> and map it into a <scxml/>
        - and set the intial state to CCXML. 
        - This beast will only be a single-state 
        - state machine as we handle CCXML's 
        - state vars using cond's on the transition 
        - elements. 
        -
        -->
        <scxml version="1.0" initalstate="CCXML">
            <!--
            -
            - There really should ever be one of 
            - these but we are going to do a for-each
            - just for the fun of it. 
            -
            -->
            <xsl:for-each select="ccxml:eventprocessor">
                <xsl:variable name="statevariable" select="@statevariable"/>
                <state id="CCXML">
                    <!--
                    -
                    - If there is a statevar create the 
                    - var to hold it
                    -
                    -->
                    <xsl:if test="@statevariable != ''">
                        <var>
                            <xsl:attribute name="name"><xsl:value-of select="@statevariable" /></xsl:attribute> 
                        </var>
                    </xsl:if>
                    <!--
                    -
                    - Process each of the ccxml <transition>
                    - elements and map them in SCXML <transition>'s
                    -
                    -->
                    <xsl:for-each select="ccxml:transition">
                        <transition>
                            <!--
                            -
                            - @event and @name move over without 
                            - really any magic. 
                            -
                            -->
                            <xsl:if test="@event != ''">
                              <xsl:attribute name="event"><xsl:value-of select="@event" /></xsl:attribute> 
                            </xsl:if>
                            <xsl:if test="@name != ''">
                                <xsl:attribute name="name">
                                    <xsl:value-of select="@name" />
                                </xsl:attribute> 
                            </xsl:if>
                            
                            <!--
                            -
                            - @state and @cond require a bit of
                            - munging to get to work right as 
                            - the CCXML states are modeled as 
                            - cond attributes in SCXML. 
                            -
                            -->
                            <xsl:choose>
                                <xsl:when test="@state != '' and @cond !='' ">
                                    <xsl:attribute name="cond">(<xsl:for-each select="str:split(@state)">(<xsl:value-of select="$statevariable" /> == '<xsl:value-of select="." />')<xsl:if test="not(position()=last())"> || </xsl:if></xsl:for-each>) &amp;&amp; (<xsl:value-of select="@cond" />)</xsl:attribute> 
                                </xsl:when>
                                <xsl:when test="@state != ''">
                                    <xsl:attribute name="cond"><xsl:for-each select="str:split(@state)">(<xsl:value-of select="$statevariable" /> == '<xsl:value-of select="." />')<xsl:if test="not(position()=last())"> || </xsl:if></xsl:for-each></xsl:attribute> 
                                </xsl:when>
                                <xsl:when test="@cond  != ''">
                                    <xsl:attribute name="cond">
                                        <xsl:value-of select="@cond" />
                                    </xsl:attribute> 
                                </xsl:when>
                            </xsl:choose>
                            
                            <!--
                            -
                            - This should pick up all
                            - the executable content 
                            -
                            -->
                            <xsl:apply-templates/>
                        </transition>
                    </xsl:for-each>
                </state>
            </xsl:for-each>
        </scxml>
    </xsl:template>
    <!--
    -
    - The CCXML <if>/<elseif>/<else> elements 
    - just need to be mapped into their SCXML versions.
    -
    -->
    <xsl:template match="ccxml:if">
        <if>
            <xsl:attribute name="cond"><xsl:value-of select="@cond" /></xsl:attribute> 
            <xsl:apply-templates/>
        </if>
    </xsl:template>
    <xsl:template match="ccxml:elseif">
        <elseif>
            <xsl:attribute name="cond"><xsl:value-of select="@cond" /></xsl:attribute> 
            <xsl:apply-templates/>
        </elseif>
    </xsl:template>
    <xsl:template match="ccxml:else">
        <else>
            <xsl:apply-templates/>
        </else>
    </xsl:template>
    <!--
    -
    - The CCXML <exit> also needs to be remaped.
    -
    -->
    <xsl:template match="ccxml:exit">
        <exit/>
    </xsl:template>
    
    <!--
    -
    - This should pick up all the executable content. 
    - For this stuff we just copy it in keeping 
    - the original namespace. 
    -
    -->
    <xsl:template match="/ | @* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

D Examples

D.1 Language Overview

This SCXML document gives an overview of the SCXML language and shows the use of it's state machine transition flows:

Note. In this example, the namespace URI http://www.w3.org/2005/07/vxml3 qualifies VoiceXML 3.0 markup. However, VoiceXML3.0 is currently under development by the Voice Browser Working Group and no specification has been published yet. The namespace URI is therefore only defined for this example.

Example: Main.scxml
<?xml version="1.0" encoding="us-ascii"?>
<!-- A wrapper state that contains all other states in this file
- it represents the complete state machine -->
<scxml xmlns="http://www.w3.org/2005/07/scxml"
       version="1.0"
       initalstate="Main">  
  <state id="Main">
    <!-- its initial state is Test1 -->
    <initial>
      <transition>
        <target next="Test1"/>
      </transition>
    </initial>
    <!-- Really simple state showing the basic syntax. -->
    <state id="Test1">
      <initial>
        <transition>
          <target next="Test1Sub1"/>
        </transition>
      </initial>
      <!-- Runs before we go into the substate -->
      <onentry> 
        <log expr="'Inside Test1'"/>
      </onentry>
      <!-- Here is our first substate -->
      <state id="Test1Sub1">
        <onentry>
          <log expr="'Inside Test1Sub1.'"/>
        </onentry>
        <onexit>
          <log expr="'Leaving Test1Sub1'"/>
        </onexit>
        <!-- Go to Sub2 on Event1 -->
        <transition event="Event1">
          <target next="Test1Sub2"/>
        </transition>
      </state>
      <!-- Here is the second substate 
           -    It is final, so Test1 is done when we get here -->
      <state id="Test1Sub2" final="true">
        <onentry>
          <log expr="'Inside Test1Sub2...'"/>
        </onentry>
        <onexit>
          <log expr="'Leaving Test1Sub2'"/>
        </onexit>
      </state>
      <!-- We get this event when we reach Test1Sub2. -->
      <transition event="Test1.done">
        <target next="Test2"/>
      </transition>
      <!-- We run this on the way out of Test1 -->
      <onexit>
        <log expr="'Leaving Test1...'"/>
      </onexit>
    </state>
    <state id="Test2">
      <initial>
        <transition>
          <target next="Test2Sub1"/>
        </transition>
      </initial>
      <!-- This time we reference a state 
           -    defined in an external file -->
      <state id="Test2Sub1" src="Test2Sub1.scxml"/>
      <!-- This time we reference a state 
           -    defined in an external file and 
           -    use the templating support to add
           -    an onexit hander. -->
      <state id="Test2Sub2" src="Template.scxml">
        <onexit>
          <log expr="'Leaving Substate Test2Sub2'"/>
        </onexit>
      </state>
      <!-- Test2Sub2 is defined as final, so this
           -  event is generated when we reach it -->
      <transition event="Test2.done">
        <target next="Test3"/>
      </transition>
    </state>
    <state id="Test3">
      <initial>
        <transition>
          <target next="Test3Sub1"/>
        </transition>
      </initial>
      <state id="Test3Sub1">
        <onentry>
          <log expr="'Inside Test3Sub1...'"/>
          <!-- Send our self an event in 5s -->
          <send event="Timer"  delay="5s"/>
        </onentry>
        <transition event="Timer">
          <!-- Transition on to Test4.
               -    This will exit both us and our parent. -->
          <target next="Test4"/>
        </transition>
        <onexit>
          <log expr="'Leaving Test3Sub1...'"/>
        </onexit>
      </state>
      <onexit>
        <log expr="'Leaving Test3...'"/>
      </onexit>
    </state>
    <state id="Test4">
      <onentry>
        <log expr="'Inside Test4...'"/>
      </onentry>
      <!-- Here we use the inline features of 
           -    target to create our scratch state.-->
      <initial>
        <transition>
          <target>
            <state id="Test4Sub1" >
              <onexit>
                <log expr="'Leaving Test4Sub1...'"/>
              </onexit>
              <!-- This transition causes the state to exit immediately
                   - after entering Test4Sub1.  The transition has no event or guard 
                   - so it is always active -->
              <transition>
                <target next="Test5"/>
              </transition>
            </state>
          </target>
        </transition>
      </initial>
    </state>
    <state id="Test5">
      <onentry>
        <log expr="'Inside Test5...'"/>
      </onentry>
      <initial>
        <transition>
          <target next="Test5P"/>
        </transition>
      </initial>
      <!-- Fire off our parallel states -->
      <parallel id="Test5P">
        <state id="Test5PSub1" final="true">
          <onentry>
            <log expr="'Inside Test5PSub1...'"/>
          </onentry>
        </state>
        <state id="Test5PSub2" final="true">
          <onentry>
            <log expr="'Inside Test5PSub2...'"/>
          </onentry>
        </state>
        <onexit>
          <log expr="'all parallel states done'"/>
        </onexit>
      </parallel>
      <!-- The parallel states are all final, so this
           -  event is generated immediately -->
      <transition event="Test5P.done">
        <target next="Test6"/>
      </transition>
    </state>
    <!-- 
         - This state shows invocation of external component
         - We will use CCXML + VoiceXML actions as an example 
         - as it is a good smoke test to show how it all 
         - fits together. 
         - Note: Odds are in a real app you would 
         - split this over several states but we 
         - are trying to keep it simple here. 
    -->
    <state id="Test6"
           xmlns:ccxml="http://www.w3.org/2002/09/ccxml"
           xmlns:v3="http://www.w3.org/2005/07/vxml3">
      <onentry>
        <!--
            - Use <send> to run a createcall using the 
            - CCXML component / Event I/O Processor
        -->
        <var name="dest" expr="'tel:+18315552020'"/>
        <send targettype="ccxml" event="ccxml:createcall" namelist="dest"/>
      </onentry>
      <transition event="ccxml:connection.connected" name="evt">      
        <!--
            - Here we use example V3 
            - Custom Action Elements instead of send . 
        -->
        <v3:form id="HelloWorld">
          <v3:block><v3:prompt>Hello World!</v3:prompt></v3:block>          
        </v3:form>
      </transition>
      <!--
          - Here we are using the low level <send> 
          - element to run a v3 form. Note that the event "v3:HelloWorld.done" 
          is assumed either to be set/sent explicitly by the v3:form code or 
          implicitly by some process outside of the v3:form
      -->
      <transition event="v3:HelloWorld.done" name="evt">
        <var name="src" expr="'helloworld2.vxml'"/>
        <var name="id" expr="'HelloWorld'"/>
        <send targettype="v3" event="v3:formstart" namelist="src id"/>
      </transition>
      <transition event="v3:HelloWorld2.done" name="evt">
        <ccxml:disconnect connectionid="evt.connectionid"/>      
      </transition>
      <transition event="ccxml:connection.disconnected">
        <!--
            - Here we are using the <exit/> shorthand to 
            - move ourself to a final state.
            - In this example you could do <target next="Done"/>
            - and get the same result.
        -->
        <exit/>
      </transition>
      <!-- Transitions to handle events generated by the component
           - component invoked successfully. this transition has no target 
           - so Test6 is not exited.
           - We are just going to log tha we were able to send an event. -->
      <transition event="send.successful">
        <log expr="'Event was able to be sent'"/>
      </transition>
      <!--
          - If we get an error event we move to the Done state that 
          - is a final state. 
      -->
      <transition event="error.send">
        <log expr="'Sending to and External component failed'"/>
        <target next="Done"/>
      </transition>
      <onexit>
        <log expr="'Finished with external component'"/>
      </onexit>
    </state>
    <!-- This final state is an immediate child of Main
         -  when we get here, Main.done is generated. -->
    <state id="Done" final="true"/>
    <!-- End of Main > -->
  </state>
</scxml>
Example: Template.scxml
<?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <!-- 
  -
  - This is our template state. 
  - We end up referencing this in the 
  - Main.scxml code. 
  -
  -->
  <state id="Template" final="true">
    <onentry>
      <log expr="'Loaded the template'"/>
    </onentry>
  </state>
</scxml>
Example: Test2Sub1.scxml
<?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <!-- 
  -
  - This is an example substate defined in
  - an external file referenced by Main.scxml. 
  -
  -->
  <state id="Test2Sub1">
    <onentry>
      <log expr="'Inside Test2Sub1'"/>
     </onentry>
    <transition event="Event2">
       <target next="Test2Sub2"/>
    </transition>
  </state>
</scxml>

E An Overview of Harel State Table Notation and Semantics

The event processing model and the semantics of states and transitions are defined in detail in the UML specification [UML 1.5]. Nevertheless it is worth outlining some of their salient features here. The most basic concepts are states and transitions. Diagram 1 shows a simple state machine with three states S1, S2, and S3.

E.1 A Simple State Machine

Example: A Simple State Machine
a basic diagram with three states

SCXML Equivalent

 <?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state id="S1">
    <transition event="Event1">
      <target next="S2"/>
    </transition>
  </state>
 
  <state id="S2">
    <transition event="Event2">
      <target next="S1"
    cond="X&gt;0"/>
    </transition>
    <transition event="Event2">
      <target next="S3"
      cond ="X&lt;0"/>
    </transition>
  </state> 
  
  <state id="S3">
  </state>
  
</scxml>
       

These states linked by transitions, which are triggered by events. In this example State S1 transitions to state S2 when the event Event1 occurs. This is the only way the system can move from S1 to S2, since it is the only transition between those two states. Any other events that occur while the system is in S1 will therefore be ignored. The logic in S2 is slightly more complex. It has two transitions, both triggered by event Event2. Both transitions have guard conditions that check the value of the variable X. If X < 0, S2 will transition to S3 when Event2 occurs. If X > 0, it will transition back to S2. Note that there is no condition covering the case where X = 0. Therefore the system will remain in state S2 if X = 0 when Event2 occurs. As in state S1, all events not mentioned in transitions will be ignored.

E.2 Executing Actions On Entering And Exiting

OnEntry and OnExit handlers are a useful feature of Harel State Tables. They allow code to be embedded in states that will be executed whenever the state is entered or exited. In Diagram 2 we see the same three states, but now S1 has an OnEntry handler that decrements X , while S2 has an OnExit handler that also decrements X. S3 has both OnEntry and OnExit handlers, both of which increment X. Now suppose that X has a current value of 2, and that the system enters S1. When it does so, X is decremented to 1. When Event1 occurs, the system will transition to S2, as before. Now when Event2 occurs, X is set to 1, so the system will transition back to S1. As the system exits state S2, the OnExit handler will decrement X to 0. Note that this happens after the transition is selected and the guard condition has been evaluated. X. The entry into S1 decrements X again to -1. Now if Event1 occurs again and the system returns to S2, it will transition to S3 when Event2 occurs, since X is now < 0. Leaving S2 will decrement X again, but entering S3 will increment it, so X = -1 when the system is in S3. S3 has no transitions so the system will stay in S3 forever. However if a transition is added to S3, the OnExit handler in S3 will set Y to 0 when S3 is exited.

Example: Diagram 2. OnEntry and OnExit Handlers
diagram with onentry and onexit handlers added

SCXML Equivalent

 <?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state id="S1">
    <onentry> 
      <assign name="X" expr="X--"/>
    </onentry>
    <transition event="Event1">
      <target next="S2"/>
    </transition>
  </state>
 
  <state id="S2">
    <transition event="Event2">
      <target next="S1"
    cond= "X &gt; 0"/>
    </transition>
    
    <transition event="Event2">
      <target next="S3"
      cond ="X &gt; 0"/>
    </transition>
    <onexit> 
      <assign name="X" expr="X--"/>
    </onexit>    
  </state> 
  
  <state id="S3">
    <onentry> 
      <assign name="X" expr="X++"/>
    </onentry>
    <onexit> 
      <assign name="Y" expr="0"/>
    </onexit>       
  </state>
  
</scxml>
       

E.3 Complex States

Of particular interest is the concept of a complex state, namely one that has substates. In Diagram 3 below, the State S1 now has two substates, labeled S11 and S12.

Example: Diagram 3. A State with Sequential Substates
diagram with sequential substates added

SCXML Equivalent

 <?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state id="S1">
    <state id="S11">
    </state>
    <state id="s12">
    </state>
    <initial>
      <transition>
        <target next="S11"/>
      </transition>
    </initial>    
  </state>
</scxml>
       

In this particular case, S1 has sequential substates. When a state machine is in a state with such substates, it must also be in one and only one of the substates. The substates have a kind of "Or" semantics and can be thought of as representing a decomposition of the parent state. A transition moving the system to S1 may specify S11 or S12 as its target directly. However, to handle the case where it doesn't, S1 contains an initial element defining the default substate that it will start in if the transition simplify specifies S1 as its destination. In Diagram 3, the default substate is S11.

E.4 Parallel States

In addition to sequential substates, Harel State Charts provide concurrent substates, which represent a form of "And" logic. When a state machine is in a state with concurrent substates it must be simultaneously in each of the concurrent child states. The concurrent child states operate independently until they all terminate (normally by reaching terminal child states) at which point the parent state also terminates. Concurrent substates thus represent fork and join logic. They are represented in our notation by the parallel tag. Diagram 4 below represents an elaboration of Diagram 3. First of all, State S11 has been decomposed into further sequential substates, S111 and S112, with S111 being the default initial state. Secondly, concurrent substates S121, S122, and S123 have been added to State S12.

Example: Diagram 4. A Combination of Concurrent and Sequential Substates
diagram with both sequential and concurrent substates added

SCXML Equivalent

 <?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state id="S1">
    
    <state id="S11">
      <state id="S111"/>
      <state id="S112"/>
      <initial>
        <transition>
          <target next="S111"/>
        </transition>
      </initial>  
    </state>
    
    <state id="s12">
      <parallel>
        <state id="S121"/>
        <state id="S122"/>
        <state id="S123"/>
      </parallel>
    </state>
    
    <initial>
      <transition>
        <target next="S11"/>
      </transition>
    </initial>
  </state>
  <state>   
  </state>
</scxml>
       

As Diagram 4 shows, the notion of complex state is fully recursive, so that the child states of a complex parent may themselves have sequential or concurrent children. Thus a complex state machine is not normally in a single state, but in a configuration of compatible states. Applying the rules for sequential and concurrent states recursively in Diagram 4, we see that when the machine is in S1 it must also be in S11 or S12. When the machine is in S11, it must be in S111 or S112. When the machine is in S12, on the other hand, it must simultaneously be in all three substates S121, S11 and S1123. Thus there are 3 legal configurations they machine can be in: S1 plus S11 plus S111, S1 plus S11 plus S112, and S1 plus S12 plus S121, S122, and S123.

E.5 Concurrency And Event Queues

The Harel semantics for transitions is based on the notion of an underlying event queue. At any given point, the state machine is in a specific configuration of states. If there is an event in the queue, it is processed according to the given state configuration, and a transition may be triggered. The transition is then taken and it and all actions associated with it are executed before the next event in the queue is examined. Of particular interest is the way that onexit and onevent handlers interact with transitions. Suppose the machine is in state S2 (which is not shown in the diagram) and an event occurs which triggers a transition to state S112 in Diagram 4. In this case, the machine first leaves S2, executing S2's onexithandlers. It then executes any actions in the selected transitions. Then it enters S1, S11, and S112 executing their onentry handlers in that order. Only when all these actions have been executed will the machine check its queue for another event. Suppose that there is an event in the queue and it triggers a transition from S112 to S12. Going to S12 entails leaving both S112 and S11, so both their onexit handlers fire in that order, before the actions in the transition. (Note that the onexit handlers fire in the reverse order of the onentry handlers.) Since S11 and S12 are both substates of S1, this transition does not entail leaving S1 so its onexit handler does not fire. After the transition's actions, S12's onentry handler will fire. Furthermore, the semantics of parallel states requires that entering S12 also involves entering each of its concurrent substates simultaneously. Therefore the onentry handlers for S121, S122, and S123 will all fire after the one for S12. Since entry into the parallel substates is simultaneous, however, there is no guarantee on the order in which the three substate handlers fire.

Complex state configurations also interact with the selection of the transition to execute. First off, note that even a simple state may contain multiple transitions that match a given event. For example State S1 may contain two transitions, T1 which is triggered by event E1 with guard Cond1, and T2 which is also triggered by E1, but with a different guard expression Cond2. If the machine is in S2 when event E1 is taken from the queue and processed, it is possible that both Cond1 and Cond2 will evaluate to true. In this case, we will say that both T1 and T2 are enabled, but only one of them can be selected and executed. In the case of a single state, we will use document order as the tie-breaker, choosing whichever transition occurs first in the definition of S1. With complex states, the issue is more difficult. Returning to Diagram 4, suppose that we are in the complex configuration S1, S11, and S112, when event E1 is processed. It is possible that all three states, S1, S11, and S112, contain transitions that are enabled. In this case, we start in the innermost state S112. If it has an enabled transition, we select it (using document order as a tie-breaker if it has more than one.) If S112 does not contain an enabled transition, we look in S11 and then in S1. Thus the most narrowly scoped transition wins. The motivation for this choice becomes clear when we remember that sequential substates are decompositions of the parent state. Thus S112 is a refinement of S11 and S11 in turn is a refinement of S1. The innermost state thus "knows the most" about the situation so its transitions are preferred to those in outer states, which can be treated as defaults or fallbacks.

In the case of concurrent substates, the event is processed by all concurrent states simultaneously and they select their transitions independently. Thus if we are in S1, S12 and parallel substates S121, S122, and S123, any event will be processed by S121, S122, and S123 simultaneously, and they may all select transitions. This makes most sense if all three states are themselves complex and the event is triggering transitions among their substates. If none of the three states handles the event, we move to S12 and then to S1.

Although parallel substates run independently their operations can be coordinated by means of Join and Synch states. The Join pseudo-state is has multiple incoming transitions and one or more outgoing transition. The incoming transitions must be unconditional (i.e., they cannot have cond or event properties.) The outgoing transitions on the join may not have event triggers and at least one must lack a cond guard condition. Thus when the join pseudo-state is finally entered, there is always a transition that can be taken immediately. The join pseudo-state is not entered until all its incoming transitions are enabled. Thus the various threads of control wait in their current states until they are all ready to enter the join, at which point they all enter simultaneously and an outgoing transition is selected.

Now suppose we have two parallel states, S1 and S2, with sequential substates S11, S12, S13 and S21, S22 and S23, as shown in Diagram 5.

Example: Diagram 5. Parallel States to be Coordinated
diagram with concurrent substates added

SCXML Equivalent

<?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state>
    <parallel>
      
      <state id="S1">
        <state id="S11">
          <transition>
            <target next ="S12"/>
          </transition>
        </state>
        <state id="S12">
          <transition>
            <target next="S13"/>
          </transition>
        </state>
        <state id="S13"/>
      </state>
      
      <state id="S2">
        <state id="S21">
          <transition>
            <target next ="S22"/>
          </transition>
        </state>
        <state id="S22">
          <transition>
            <target next="S23"/>
          </transition>
        </state>
        <state id="S23"/>
      </state>
      
    </parallel>
  </state>
</scxml>
       

E.6 Synchronizing And Concurrency

Given the basic Harel semantics S1 and S2 will function independently, so that S1 will move from S11 to S12 to S13 without regard to what S2 is doing, and vice-versa. But now suppose that we want to ensure that S2 does not transition from S22 to S23 until S1 has left S11. Diagram 6 shows how we can do this using join and syncstates.

Example: Diagram 6. Use of the Synch State
diagram with sync state added

SCXML Equivalent

 <?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state>
    <parallel>
      
      <state id="S1">
        <state id="S11">
          <transition>
            <target next ="S12"/>
            <target next="synch1"/>
          </transition>
        </state>
        <state id="S12">
          <transition>
            <target next="S13"/>
          </transition>
        </state>
        <state id="S13"/>
      </state>
      
      <state id="S2">
        <state id="S21">
          <transition>
            <target next ="S12"/>
          </transition>
        </state>
        <state id="S22">
          <transition>
            <target next="j1"/>
          </transition>
        </state>
        <state id="S23"/>
      </state>
      
      <sync id="synch1">
        <transition>
          <target next="j1"/>
        </transition>
      </sync>
      
      <join id="j1">
        <transition>
          <target next="S23"/>
        </transition>
      </join>
      
    </parallel>
  </state>
</scxml>
       

We have inserted a join pseudo-state between S22 and S23, with a conditionless incoming transition from S22 and a conditionless outgoing transition to S23. (The join pseudo-state is represented as a vertical bar with multiple incoming transitions and a single outgoing transition.) We also added a sync state with a conditionless outgoing transition to the same join. Then we took all the transitions that leave S11 and have them branch to include the sync state as an extra target. (In the diagram this is shown by inserting a 'fork' vertical bar, with a single incoming transition and multiple outgoing transitions. In our SCXML notation, we would use multiple values in the target element). Now when the machine reaches S22, it will wait until the sync state is active (and therefore ready to transition) before entering the join and transitioning to S23. When S1 is ready to leave S11, it in effect branches control, with its normal execution continuing along one branch of the transition while the other branch enters the sync state, which triggers the join and allows S2 to proceed. Note that S1 may reach the sync state before or after S2 reaches S22. In either case, the combined effect of the sync state and the join is to allow S1's processing to continue as before, while ensuring that S2 will wait in S22, if necessary, for the signal that S1 has left S11.

E.7 Sync Explained

The sync state is really serving as a buffer to keep the effect of the join from propagating back into S1. For example, it would be possible to omit the sync state and connect S11's branching transition directly to the join. However, in that case, if S1 was ready to leave S11 before S2 reached S22, by the semantics of the join, S1 would have to block in S11 waiting for S2. This is not the behavior we want because the purpose of the synchronization is to control the behavior of S2 without changing the flow of S1. If we want to synchronize multiple regions, so that both S2 and S3 would wait until S1 left S11, we can use multiple sync states, one for S2 and one for S3, and have the transition from S11 branch to both of them.

The sync state uses an internal counter to keep track of how often it has been entered and exited, augmenting the counter when it is entered and decrementing it when it is exited. The sync state will take its outgoing transition only when the counter is positive. The bound value puts a limit on how large a value the counter can hold. For example, setting bound to 1 turns the state into a binary semaphore, that can be exited only once no matter how often it has been entered. The default value for bound is unlimited.

For an example of the use of a higher bound, consider states S1 and S2 as before, but now suppose that we want to restrict S2 to wait in S21 until S1 exits S11 and to wait in S22 until S1 exits S12. We could use two separate syncsteps for this, but one will suffice, as Diagram 7 shows.

Example: Diagram 7. Use of the Bound value in a Synch State
diagram showing use of bound

SCXML Equivalent

<?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
  <state>
    <parallel>
      
      <state id="S1">
        <state id="S11">
          <transition>
            <target next ="S12"/>
            <target next="synch1"/>
          </transition>
        </state>
        <state id="S12">
          <transition>
            <target next="S13"/>
            <target next="synch1"/>
          </transition>
        </state>
        <state id="S13"/>
      </state>
      
      <state id="S2">
        <state id="S21">
          <transition>
            <target next ="S12"/>
          </transition>
        </state>
        <state id="S22">
          <transition>
            <target next="j1"/>
          </transition>
        </state>
        <state id="S23"/>
      </state>
      
      <sync id="synch1">
        <transition>
          <target next="j1"/>
        </transition>
        <transition>
          <target next="j2"/>
        </transition>
      </sync>
      
      <join id="j1">
        <transition>
          <target next="S23"/>
        </transition>
      </join>
      
      <join id="j2">
        <transition>
          <target next="S23"/>
        </transition>
      </join>
      
    </parallel>
  </state>
</scxml>
       

Here we have branching transitions from S11 and S12, and two outgoing transitions, one to a join between S21 and S22, and another to a join between S22 and S23. Suppose S1 races ahead of S2, moving from S11 to S12 to S13. The sync state will have been entered twice, so its counter will be 2. When S2 is ready to leave S21, the syncstate will be ready and take the transition to the join, decrementing its counter to 1. When S2 is ready to leave S2, the fact that the counter is still positive means that the sync state will still be active and ready to take the transition to the join.

E.8 Microwave Oven

This example implements a simple microwave oven that can be in one of two states:

On --- the oven is running
Off --- the oven is turned off

State on itself has two substates:

Cooking --- the oven is cooking
Idle --- the oven is idle

The oven responds to three external event sources:

Door open/close
Timer that tracks cook-time
Power button



Example: Microwave Oven
State machine diagram for a microwave showing the logic for switching among its various states.

SCXML Equivalent:

<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml"
       version="1.0"
       initialstate="off">
  
  <!--  trivial microwave oven example -->
  <state id="off">
    <!-- off state -->
    <transition event="turn_on">
      <target next="on"/>
    </transition>
  </state>
  <state id="on">
    <initial>
        <transition>
            <target next="idle"/>
        </transition>
    </initial>
    <!-- on/pause state -->
    <onentry>
      <!-- we assume the cook_time is passed in as a context parameter -->
      <if cond="${empty cook_time}">
        <!-- default setting -->
        <var name="cook_time" expr="${5}"/>
      </if>
      <!-- again, door_closed should be a part of a global context -->
      <if cond="${empty door_closed}">
        <!-- default setting -->
        <var name="door_closed" expr="${true}"/>
      </if>
      <!-- timer variable -->
      <var name="timer" expr="${0}"/>
    </onentry>
    <transition event="turn_off">
        <target next="off"/>
    </transition>
    <transition cond="${timer ge cook_time}">
        <target next="off"/>
    </transition>
    <state id="idle">
      <transition cond="${door_closed}">
        <!-- default immediate transition -->
        <target next="cooking"/>
      </transition>  
      <transition event="door_close">
        <assign name="door_closed" expr="${true}"/>
        <!-- start cooking -->
        <target next="cooking"/>
      </transition>
    </state>
    <state id="cooking">
      <transition event="door_open">
        <assign name="door_closed" expr="${false}"/>
        <target next="idle"/>
      </transition> 
      <transition event="time">
        <assign name="timer" expr="${timer + 1}"/>
        <target next="cooking"/>
      </transition>
    </state>
  </state>
</scxml>
       

Next, we show the same microwave example, but this time implemented using parallel.

Example: Microwave Oven
Microwave logic implemented using concurrency

SCXML Equivalent:

<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0"
       initialstate="oven"> 
  <!--  trivial microwave oven example -->
  <!-- using parallel and In() predicate -->
  <state id="oven">
    <parallel id="parts">
      <state id="engine">
        <transition>
          <target next="off"/>
        </transition>
        <state id="off">
          <!-- off state -->
          <transition event="turn_on">
            <target next="on"/>
          </transition>
        </state>
        
        <state id="on">
          <transition>
            <target next="idle"/>
          </transition>
          <!-- on/pause state -->
          <onentry>
            <!-- we assume the cook_time is passed in as a context parameter -->
            <if cond="${empty cook_time}">
              <!-- default setting -->
              <var name="cook_time" expr="${5}"/>
            </if>
            <!-- timer variable -->
            <var name="timer" expr="${0}"/>
          </onentry>
          
          <transition event="turn_off">
              <target next="off"/>
          </transition>
          <transition cond="${timer ge cook_time}">
              <target next="off"/>
          </transition>
          
          <state id="idle">
            <transition cond="${In('closed')}">
              <target next="cooking"/>
            </transition>
          </state>
          
          <state id="cooking">
            <transition cond="${not In('closed')}">
                <target next="idle"/>
            </transition>
            <transition event="time">
              <assign name="timer" expr="${timer + 1}"/>
              <target next="cooking"/>
            </transition>
          </state>
        </state>
      </state>
      <state id="door">
        <initial>
          <transition>
            <target next="closed"/>
          </transition>
        </initial>
        <state id="closed">
          <transition event="door_open">
              <target next="open"/>
          </transition>
        </state>
        <state id="open">
          <transition event="door_close">
              <target next="closed"/>
          </transition>
        </state>
      </state>
    </parallel>
  </state>
</scxml>
       

F References

IETF RFC 2119
RFC 2119: Key words for use in RFCs to Indicate Requirement Levels. Internet Engineering Task Force, 1997. (See http://www.ietf.org/rfc/rfc2119.txt.)
IETF RFC 2396
RFC 2396: Uniform Resource Identifiers. Internet Engineering Task Force, 1995. (See http://www.ietf.org/rfc/rfc2396.txt.)
W3C VoiceXML 2.0
VoiceXML 2.0: Format for Literal IPv6 Addresses in URL's. W3C, 2004. (See http://www.w3.org/TR/VoiceXML20.)
W3C CCXML 1.0
CCXML 1.0 : Voice Browser Call Control Markup Language. W3C, 2005. (See http://www.w3.org/TR/2005/WD-ccxml-20050111/.)
UML 1.5
UML Specification Version 1.5. (See http://www.uml.org/#UML1.5.)
CSS2
Cascading Style Sheets, level 2: CSS2 Specification. B. Bos, et al., Editors. World Wide Web Consortium, 12 May 1998. This version of the CSS2 Recommendation is http://www.w3.org/TR/1998/REC-CSS2-19980512/. The latest version of CSS2 is available at http://www.w3.org/TR/REC-CSS2/. (See http://www.w3.org/TR/1998/REC-CSS2-19980512/.)
UML XMI
XML Metadata Exchange version 2.1. (See http://www.omg.org/technology/documents/modeling_spec_catalog.htm#XMI.)
OASIS ebXML
ebXML Business Process Specification Schema v2.0. (See http://www.oasis-open.org/committees/documents.php?wg_abbrev=ebxml-bp.)
XTND
XML Transition Network Definition. (See http://www.w3.org/TR/2000/NOTE-xtnd-20001121/.)