Personal Universal Controller
Appliance Specification Language Documentation

Documention originally written by Jeffrey Nichols and Mathilde Pignol.

Language design by the personal universal controller working group: Michael Higgins, Joe Hughes, Peter Lucas, Brad A. Myers, Jeffrey Nichols, and Mathilde Pignol. Speech interface contributions by Thomas K. Harris.



Table of Contents

  1. Introduction
  2. Revision History
  3. Conceptual Basis
  4. Language Description
  5. Schema
  6. Tag Reference
  7. Future Work
  8. Appendix A. Example Specification
  9. References

Introduction

The personal universal controller (PUC) project's goal is to build a software framework running on top of a personal digital assistant (PDA) or other mobile device that is capable of providing an interface that will allow users to control any appliance within their environment. In essence, the PUC is a device-independent, appliance-independent, user-dependent remote control device.

Because of the universal nature of the PUC, it is not reasonable to pre-program the controller device with an interface for every appliance that might be encountered. Similarly, it is not reasonable to require each appliance to provide hard-coded interfaces for several device form factors, and expect the controller devices to interpolate to their actual form factor. This approach ignores user interface conventions that may differ among controller platforms, which cannot easily be interpolated between. For example, certain platforms may not have support for certain types of widgets, and it is possible to imagine a future device that would differ significantly from the devices of today (e.g. a watch with a circular display that uses several physical dials for input).

We have chosen to automatically generate user interfaces on the controller device from an interface-independent specification language. This specification language describes the functions of the appliance and provides knowledge about how these functions relate to each other. We hope that many different kinds of interfaces can be generated from this specification, including interfaces for handhelds, WAP cellular phones, and future devices with new and different interaction styles. We also plan to explore the use of our specification with the automatic generation of speech interfaces.

This document describes the specification language that we have designed for supporting automatic generation of user interfaces. It begins with a description of the conceptual basis for the language, and then defines the language in concrete terms. The document concludes with a section detailing planned additions to the specification language.

Users of this document may also be interested in documentation of the network protocol that is used by PUCs to communicate with appliances.

Revision History

DateNameComments
02/22/2002 jwn Fixed typos and added information about new tags for supporting the creation of speech interfaces from the specification language. See <phonetic> tag and the label dictionary explanation.
02/23/2002 jwn Made priority a parameter of <group>, <state>, <command>, and <explanation> instead of having its own tag.
02/27/2002 jwn Made changes to support the DTD and its formatting requirements. Added the DTD section. Updated the example spec to reflect all of the recent language revisions. Added the <apply-type> and <object-ref> tags to support the reuse of type declarations and multiple occurences of the same object within the group tree. This was previously included as a feature that was incompatible with the restrictions of the DTD. Added the <number> tag to make numeric values symmetrical with the use of <refvalue>, again for DTD conformance. Also removed the recording parameter from the <map> and <labels> elements. Instead, each of these elements may now contain multiple <text-to-speech> elements that may specify similar information.
03/11/2002 jwn Added a reference to the new protocol documentation. Also moved the published versions of the DTDs and docs to the pebbles web site, and updated the links in this documentation appropriately.
10/06/2003 jwn Started updating documentation to include all changes to the specification in the last year and a half. This includes significant changes to the group systems, new dependencies, list and union structures, Smart Templates, and some changes to which XML tags are allowed. Updates not completed and new version not released.
05/19/2004 jwn Finished updating the documentation for the new specification language format. Wrote and added an XML Schema for the language, and updated the tag reference. Removed the example specification in Appendix A for now, as this document describes changes that are not actually implemented in any specification language. Once the Mitsubishi DVCR spec is complete, I will add it to the appendix.

Conceptual Basis

The design of the specification language was based upon prototyping interfaces for a phone and a stereo appliance on a standard handheld form factor (we tried both Palm and PocketPC). These prototypes taught us several things about the functions of appliances:

Each of these items are described in more detail below.

Appliance Objects

Three types of appliance objects are supported in the specification language.

Although there are differences between states, commands and explanations, they also share a common property of being enabled. When an object is enabled (or active), the user interface widgets that correspond to that object can be manipulated by the user. Knowing the circumstances in which an object will be enabled or disabled can provide a helpful hint for structuring the interface, because items that are active in similar situations can be grouped, and items can be placed on panels such that the widgets are not visible when the object would not be active. Specifying the prior knowledge of the enabled property is discussed in more detail in the Dependency Information sub-section.

Label Information

Another common property of appliance objects is the need to specify rich labeling information for flexibility when generating interfaces in different form factors.

To support specifying labeling information, we use the concept of a label dictionary. At any place in the specification where a label can be entered, more than one label may be provided. It is expected that all these labels contain the same general information, but vary in terms of length and detail. We also allow the specification designer to designate one label as "preferred" for use in an interface. The interface generator would choose the preferred label or the longest label that fits within the space allocated on the screen. In certain situations, the preferred label may be used as the basis for making layout decisions.

Labels can be specified for any appliance object, and also be linked with particular values of an appliance state's type.

This language also supports the specification of label information for speech interfaces. This support is for both recognition and text-to-speech. Label dictionaries can store phonetic information to help recognizers interpret label names. Multiple pronunciations can be specified for robustness, just as multiple labels can be specified. To assist text-to-speech engines, each label dictionary can be associated with a URL that points to an audio recording of the label.

State Variable Types

Every appliance state has a type object associated with it. The type information is used to determine what kinds of widgets can be used to manipulate the state, and is one of the paramters that is used to recognize Smart Templates.

There are currently eight different kinds of types that can be used in the specification:

Each of these types has a different set of parameters that can be specified for it. For a complete list of those parameters, see the tag reference.

The binary type is used for data that cannot be described as a string, e.g. images, sound clips, or video. Unlike the other types, interface generators are not expected to have a default rendering for variables with binary types. A Smart Template must be used in conjunction with a binary state to ensure that the state is rendered.

The list selection type allows the user to specify an item in a list. This is used in locations where it would not make sense to duplicate the list state variables. For more on lists see the lists section.

Older versions of the specification language supported a custom primitive type, which was used for representing domain-specific types. This type is no longer allowed. See the section on Smart Templates later for more information on our current solution for this problem.

The specification language contains a provision for re-using type declarations in subsequently defined state variables via the <apply-type> element. This allows two or more state variables to have the same type without specifying that information multiple times in a specification. No data is shared between those state variables.

The Group Tree

Proper structure is a very important part of any user interface. In our language we use a hierarchical "group tree" to specify structure. The leaf nodes in the tree are appliance objects, and the branch nodes are groups. Each node in the tree has a name which must not be the same as any other child of its parent. Thus each node has a locally unique name, and a globally unique name can be constructed by pre-pending the names of all a nodes parents. We use a "." character to separate each name. For example, the locally unique name of a state variable might be "PlayState" but the globally unique name would be "Stereo.CD.PlayState". That same specification could also contain other states like "Stereo.Tape.PlayState". Note that the root name "Stereo" cannot be re-used as a name anywhere in the specification.

It is often necessary to explicitly refer to state variables in a specification. This may be done using any name that starts with a globally unique name. Since the root name is unique, the full name will always work. For the above examples, "Tape.PlayState" and "CD.PlayState" would also work, assuming that there are no other groups or states named "CD" or "Tape".

There are three types of groups: normal, list, and union. A normal group is used for putting related data together, similar to a record in a programming language. List and union groups have special behavior beyond that of normal groups, which are discussed in the next section.

Lists

Specifying a list group is similar to specifying an array of records in a programming language, and multiple list groups can be nested to create multi-dimensional lists. Each list group has an implicit length state variable (named "Length") that always contains the length of the current list. If this variable is undefined, then the list currently has no members. The specification may define bounds on the length of the list in order to help the interface generator create a better rendering. An exact size may be specified, or a minimum and/or maximum size may be specified.

List groups also maintain an implicit structure to keep track of one or more list selections. The number of selections allowed may be defined in the specification ("one" and "many" are the only options currently), and the default is one if nothing is specified. If a list allows only one selection, then an implicit "Selection" variable is created which contains the index of the current selection (undefined means no selection). If multiple selections are created, then an implicit list group named "Selection" is created. This group contains a "Length" state (as all list groups do) and an "Index" state which contains all of the selected indices.

Unions

A union group is simliar to specifying a union in a programming language; of the children within a union (either groups or appliance objects), only one may be active at a time. An implicit state variable named "ChildUsed" is automatically created within a union group that contains the name of the currently active child.

Dependency Information

Dependency information is specified for each appliance object as a boolean equation. This information gives the interface generator some approximate a priori knowledge of when the object will be enabled (see the Appliance Objects section for more information).

Five kinds of dependencies can be specified. Each of these dependencies specifies a state that is depended upon, and most specify a value of that state. In those cases where a value must be specified, a pointer to another variable may be used instead with the <refvalue> tag.

These dependencies can be composed into boolean formulas using AND and OR.

Specifying dependencies on list state variables must be done using the special <apply-over> element. This element applies the dependencies it contains over all the elements in a list and returns a value depending on the value of its "true-if" property. This property may be either "all", "any" or "none". If "true-if" is "all", then all of the dependencies contained in the "apply-over" element must be true for elements if true is returned. If "true-if" is "any", then all of the dependencies contained in the "apply-over" must be true for one of the elements. If "true-if" is "none", then the dependencies must not be satisfied by any element to return true.

Smart Templates

Smart Templates extend the primitive types of the specification language with high-level semantic information. With a Smart Template, a group in a specification might be marked as "media-controls" for example, and an interface generator could use this information to create an interface that uses the standard play and stop icons that people are accustomed to. More information about Smart Templates is available in this paper.

Documentation about applying and specifying templates and a list of the Smart Templates specified so far is available here.

Language Description

Our specification language is based on the XML standard from the Worldwide Web Consortium. A Schema for the language is shown below. You may separately download the schema from here. The tag reference and the example specifications in Appendix A may also be helpful for understanding the particulars of our specification language.

Schema

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.cs.cmu.edu/~pebbles/puc/"
	xmlns="http://www.cs.cmu.edu/~pebbles/puc/" elementFormDefault="qualified">

	<!-- Attributes -->
	<xs:attribute name="name" type="xs:string" />
	<xs:attribute name="index" type="xs:string" />
	<xs:attribute name="list" type="xs:string" />
	<xs:attribute name="state" type="xs:string" />
	<xs:attribute name="is-a" type="xs:string" />
	<xs:attribute name="text" type="xs:string" />
	<xs:attribute name="recording" type="xs:string" />
	<xs:attribute name="value" type="xs:string" />

	<xs:attribute name="access" default="read-write">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="read-only" />
				<xs:enumeration value="read-write" />
			</xs:restriction>
		</xs:simpleType>
	</xs:attribute>

	<xs:attribute name="ignore" default="none">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="none" />
				<xs:enumeration value="parent" />
				<xs:enumeration value="all" />
			</xs:restriction>
		</xs:simpleType>
	</xs:attribute>

	<xs:attribute name="version">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="PUC/2.0" />
				<xs:enumeration value="PUC/2.1" />
			</xs:restriction>
		</xs:simpleType>
	</xs:attribute>

	<xs:attribute name="type-name" default="one">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="one" />
				<xs:enumeration value="multiple" />
			</xs:restriction>
		</xs:simpleType>
	</xs:attribute>

	<xs:attribute name="priority" default="0">
		<xs:simpleType>
			<xs:restriction base="xs:integer">
				<xs:minInclusive value="0" />
				<xs:maxInclusive value="10" />
			</xs:restriction>
		</xs:simpleType>
	</xs:attribute>

	<xs:attribute name="true-if" default="any">
		<xs:simpleType>
			<xs:restriction base="xs:string">
				<xs:enumeration value="any" />
				<xs:enumeration value="all" />
				<xs:enumeration value="none" />
			</xs:restriction>
		</xs:simpleType>
	</xs:attribute>


	<!-- Simple Elements -->

	<xs:element name="item-count" type="xs:integer" />
	<xs:element name="pointpos" type="xs:integer" />
	<xs:element name="label" type="xs:string" />
	<xs:element name="phonetic" type="xs:string" />


	<!-- State Attribute, No Content Elements -->

	<xs:complexType name="stateAttribNoContent">
		<xs:attribute ref="state" use="required" />
	</xs:complexType>

	<xs:element name="refvalue" type="stateAttribNoContent" />
	<xs:element name="refstring" type="stateAttribNoContent" />

	<xs:element name="static">
		<xs:complexType>
			<xs:attribute ref="value" use="required"/>
		</xs:complexType>
	</xs:element>


	<!-- Selection Type Element (Two Attrib, No Content) -->

	<xs:element name="selection-type">
		<xs:complexType>
			<xs:attribute ref="type-name" use="required" />
			<xs:attribute ref="access" use="required" />
		</xs:complexType>
	</xs:element>


	<!-- Dependency Relation Elements -->

	<xs:complexType name="StaticOrReference">
		<xs:choice>
			<xs:element ref="static" />
			<xs:element ref="refvalue" />
		</xs:choice>
	</xs:complexType>

	<xs:element name="defined" type="stateAttribNoContent" />
	<xs:element name="undefined" type="stateAttribNoContent" />

	<xs:element name="equals">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="StaticOrReference">
					<xs:attribute ref="state" use="required" />
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>

	<xs:element name="lessthan">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="StaticOrReference">
					<xs:attribute ref="state" use="required" />
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>

	<xs:element name="greaterthan">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="StaticOrReference">
					<xs:attribute ref="state" use="required" />
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>


	<!-- Dependency Operator Relations -->

	<xs:complexType name="DependencyContent">
		<xs:sequence>
			<xs:choice minOccurs="1" maxOccurs="unbounded">
				<xs:element ref="or" />
				<xs:element ref="and" />
				<xs:element ref="not" />
				<xs:element ref="apply-over" />
				<xs:element ref="defined" />
				<xs:element ref="undefined" />
				<xs:element ref="equals" />
				<xs:element ref="greaterthan" />
				<xs:element ref="lessthan" />
			</xs:choice>
		</xs:sequence>
	</xs:complexType>

	<xs:element name="or" type="DependencyContent" />
	<xs:element name="and" type="DependencyContent" />

	<xs:element name="not">
		<xs:complexType>
			<xs:choice minOccurs="1" maxOccurs="1">
				<xs:element ref="or" />
				<xs:element ref="and" />
				<xs:element ref="apply-over" />
				<xs:element ref="defined" />
				<xs:element ref="undefined" />
				<xs:element ref="equals" />
				<xs:element ref="greaterthan" />
				<xs:element ref="lessthan" />
			</xs:choice>
		</xs:complexType>
	</xs:element>

	<xs:element name="apply-over">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="DependencyContent">
					<xs:attribute ref="list" use="required" />
					<xs:attribute ref="true-if" use="optional" />
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>

	<xs:element name="active-if">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="DependencyContent">
					<xs:attribute ref="ignore" use="optional" />
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>


	<!-- Label Dictionary Elements -->

	<xs:element name="text-to-speech">
		<xs:complexType>
			<xs:attribute ref="text" />
			<xs:attribute ref="recording" />
		</xs:complexType>
	</xs:element>

	<xs:element name="labels">
		<xs:complexType>
			<xs:sequence>
				<xs:choice minOccurs="1" maxOccurs="unbounded">
					<xs:element ref="label" minOccurs="1" />
					<xs:element ref="refstring" />
					<xs:element ref="phonetic" />
					<xs:element ref="text-to-speech" />
				</xs:choice>
			</xs:sequence>
		</xs:complexType>
	</xs:element>


	<!-- Value Space Elements -->

	<xs:element name="min" type="StaticOrReference" />
	<xs:element name="max" type="StaticOrReference" />
	<xs:element name="incr" type="StaticOrReference" />
	<xs:element name="average" type="StaticOrReference" />

	<xs:element name="binary">
		<xs:complexType>
			<xs:sequence>
				<xs:any minOccurs="0" maxOccurs="unbounded" />
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<xs:element name="boolean" />

	<xs:element name="enumerated">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="item-count" minOccurs="1" maxOccurs="1" />
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<xs:complexType name="NumericParameters">
		<xs:sequence>
			<xs:element ref="min" minOccurs="0" maxOccurs="1" />
			<xs:element ref="max" minOccurs="0" maxOccurs="1" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="NumericIncrParameters">
		<xs:complexContent>
			<xs:extension base="NumericParameters">
				<xs:sequence>
					<xs:element ref="incr" minOccurs="0" maxOccurs="1" />
				</xs:sequence>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>

	<xs:element name="integer" type="NumericIncrParameters" />
	<xs:element name="floatingpt" type="NumericParameters" />

	<xs:element name="fixedpt">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="NumericIncrParameters">
					<xs:all>
						<xs:element ref="pointpos" minOccurs="1" maxOccurs="1" />
					</xs:all>
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>

	<xs:element name="list-selection">
		<xs:complexType>
			<xs:attribute ref="list" />
		</xs:complexType>
	</xs:element>

	<xs:element name="string">
		<xs:complexType>
			<xs:all>
				<xs:element ref="min" minOccurs="0" maxOccurs="1" />
				<xs:element ref="max" minOccurs="0" maxOccurs="1" />
				<xs:element ref="average" minOccurs="0" maxOccurs="1" />
			</xs:all>
		</xs:complexType>
	</xs:element>


	<!-- Value Labels Elements -->

	<xs:element name="map">
		<xs:complexType>
			<xs:all>
				<xs:element ref="labels" minOccurs="1" maxOccurs="1" />
				<xs:element ref="active-if" minOccurs="0" maxOccurs="1" />
			</xs:all>
			<xs:attribute ref="index" />
		</xs:complexType>
	</xs:element>

	<xs:element name="value-labels">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="map" minOccurs="1" maxOccurs="unbounded" />
			</xs:sequence>
		</xs:complexType>
	</xs:element>


	<!-- Type Elements -->

	<xs:element name="type">
		<xs:complexType>
			<xs:sequence>
				<xs:choice minOccurs="1" maxOccurs="1">
					<xs:element ref="binary" />
					<xs:element ref="boolean" />
					<xs:element ref="enumerated" />
					<xs:element ref="fixedpt" />
					<xs:element ref="floatingpt" />
					<xs:element ref="integer" />
					<xs:element ref="list-selection" />
					<xs:element ref="string" />
				</xs:choice>
				<xs:element ref="value-labels" minOccurs="0" maxOccurs="1" />
			</xs:sequence>
			<xs:attribute ref="name" use="optional" />
		</xs:complexType>
	</xs:element>

	<xs:element name="apply-type">
		<xs:complexType>
			<xs:attribute ref="name" use="required" />
		</xs:complexType>
	</xs:element>


	<!-- Appliance Object Elements -->

	<xs:attributeGroup name="ApplianceObjectAttribs">
		<xs:attribute ref="name" use="required" />
		<xs:attribute ref="is-a" use="optional" />
		<xs:attribute ref="priority" use="optional" />
	</xs:attributeGroup>

	<xs:element name="state">
		<xs:complexType>
			<xs:sequence>
				<xs:choice minOccurs="1" maxOccurs="1">
					<xs:element ref="type" />
					<xs:element ref="apply-type" />
				</xs:choice>
				<xs:element ref="labels" />
				<xs:element ref="active-if" />
			</xs:sequence>
			<xs:attributeGroup ref="ApplianceObjectAttribs" />
			<xs:attribute ref="access" use="optional" />
		</xs:complexType>
	</xs:element>

	<xs:element name="command">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="labels" />
				<xs:element ref="active-if" />
			</xs:sequence>
			<xs:attributeGroup ref="ApplianceObjectAttribs" />
		</xs:complexType>
	</xs:element>

	<xs:element name="explanation">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="labels" />
				<xs:element ref="active-if" />
			</xs:sequence>
			<xs:attributeGroup ref="ApplianceObjectAttribs" />
		</xs:complexType>
	</xs:element>


	<!-- Grouping Elements -->

	<xs:complexType name="GroupingType">
		<xs:sequence>
			<xs:element ref="labels" minOccurs="0" maxOccurs="1" />
			<xs:element ref="active-if" minOccurs="0" maxOccurs="1" />
			<xs:choice minOccurs="1" maxOccurs="unbounded">
				<xs:element ref="group" />
				<xs:element ref="state" />
				<xs:element ref="command" />
				<xs:element ref="explanation" />
			</xs:choice>
		</xs:sequence>
		<xs:attributeGroup ref="ApplianceObjectAttribs" />
	</xs:complexType>

	<xs:element name="group" type="GroupingType" />

	<xs:element name="union-group">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="GroupingType">
					<xs:attribute ref="access"/>
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>

	<xs:element name="list-group">
		<xs:complexType>
			<xs:complexContent>
				<xs:extension base="GroupingType">
					<xs:sequence>
						<xs:choice minOccurs="0" maxOccurs="1">
							<xs:sequence>
								<xs:element ref="min" minOccurs="0" maxOccurs="1" />
								<xs:element ref="max" minOccurs="0" maxOccurs="1" />
							</xs:sequence>
							<xs:element ref="item-count" />
						</xs:choice>
						<xs:element ref="selection-type" minOccurs="0" maxOccurs="1" />
					</xs:sequence>
				</xs:extension>
			</xs:complexContent>
		</xs:complexType>
	</xs:element>


	<!-- Top-Level Elements -->

	<xs:element name="groupings">
		<xs:complexType>
			<xs:choice minOccurs="1" maxOccurs="unbounded">
				<xs:element ref="group" />
				<xs:element ref="list-group" />
				<xs:element ref="union-group" />
			</xs:choice>
		</xs:complexType>
	</xs:element>

	<xs:element name="spec">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="labels" />
				<xs:element ref="groupings" />
			</xs:sequence>
			<xs:attribute ref="name" />
			<xs:attribute ref="version" />
		</xs:complexType>
	</xs:element>
	
</xs:schema>

Tag Reference

This section describes all of the tags available in the specification language and how they are used.

Tag Index

<active-if>
Contains dependency information for an appliance object or a group of objects. Defines an and relation with all dependencies that are contained within, unless they are grouped within a logical operation block, such as <or>.
<and>
Defines an and relation with the dependencies that are contained within.
<apply-over>
Applies dependency relations to a list of data.
<apply-type>
Allows the re-use of an existing type block within a specification.
<binary>
Binary type - encompasses any kind of binary data, including images and sounds. A Smart Template must be used to appropriately interpret and render the binary data.
<boolean/>
Boolean type - takes on true or false values.
<command>
Defines a command appliance object.
<enumerated>
Enumerated type - Define the number of items in the enumeration using the <item-count> tag. Labels can be defined within the <value-labels> tag.
<equals>
Used in conjunction with the <active-if> tag to define equals dependency information for this state variable.
<explanation>
Defines an explanation appliance object.
<fixedpt>
Fixed Point type - for variables that take the form of decimal values with a fixed decimal point location. Minimum, maximum and increment values can be defined using the <min>, <max>, and <incr> tags.
<floatingpt>
Floating Point type - for variables that take the form of decimal values. Minimum and maximum values can be defined using the <min> and <max> tags.
<greaterthan>
Used in conjunction with the <active-if> tag to define greaterthan dependency information for this state variable.
<group>
Used to define the nodes of the group tree.
<groupings>
Defines the section that includes the group tree.
<incr>
Defines the increment that an integer or fixed point variable must use. This restriction means that the variable must have a value equals to its minimum + n * increment, where n is an integer.
<item-count>
Used to denote how many values there are in an <enumerated> type or a <list-group>. Labels for the items can be defined within the <value-labels> tag.
<integer>
Integer type - for variables that take the form of integers. Minimum, maximum and increment values can be defined using the <min>, <max>, and <incr> tags.
<label>
Defines a label to be included within a label dictionary.
<labels>
Defines a label dictionary for an appliance object or group. The <map> tag specifies a dictionary to be associated with the specific value of a variable.
<lessthan>
Used in conjunction with the <active-if> tag to define lessthan dependency information for this state variable.
<list-group>
Specifies a special group that represents a list of data. The variables contained in this group have multiple values for every item in the list.
<map>
Specifies a label dictionary for the specific value of a variable.
<min>
Defines the minimum value a numeric variable may take.
<max>
Defines the maximum value a numeric variable may take.
<not>
Negates the value of a dependency equation.
<static>
Used to define a static value in any location where a reference would also be accepted.
<or>
Defines an or relation with the dependencies that are contained within.
<phonetic>
Provides pronunciation information for speech interfaces that are based upon this specification language. Many pronunciations may be included in a label dictionary.
<pointpos>
Defines the position of the decimal point for a fixed point type.
<refstring>
Used to define a string for a <label> tag that depends on the value of state variable with a string type.
<refvalue>
Used to define a numeric value for any of the value space parameter tags except the pointpos tag that depends on the value of a numeric state variable. E.g. a refvalue can be used to set the maximum of a numeric state variable to be the value of another state variable.
<selection-type>
Defines the number of selections allowed in a list.
<spec>
Every specification begins with this tag.
<state>
Defines a state variable appliance object.
<string/>
String type - for variables that take the form of strings.
<text-to-speech>
Defines a text-to-speech entry to be included within a label dictionary.
<type>
Describes the value space of a state variable (ex: Boolean, Integer, etc...) and the labels that its values take.
<union-group>
Specifies a special group in which only one of the children may have a valid value.
<value-labels>
Contains one or more <map> tags that provide label dictionaries for specific values that the variable might have.

Tag Descriptions

<spec>
<spec name="Sample Specification" version="PUC/2.1"></spec>
Every specification begins with this element. The name specified in the name attribute is a machine-readable name for the parser. The contained <labels> element specifies human-readable names for the appliance.

Placement:
First tag of the spec after the required XML header (E.g. <?xml version="1.0" encoding="UTF-8"?>)
Parameters:
  • name - required The name of the appliance defined in this specification
  • version - required The version of the specification language being used. Current valid values are "PUC/2.0" and "PUC/2.1". (This document describes PUC/2.1)
Must Contain:
<groupings>, <labels>

<groupings>

<groupings></groupings>
Contains the entire group tree.

Placement:
Inside the <spec> tag
May Contain:
<group>, <list-group>, <union-group>

<group>

<group name="GroupA" priority="10"></group>
Defines the nodes of the group tree.

Group nodes may be assigned a label dictionary with the <labels> tag. Group nodes may also specify dependencies for all their members using the <active-if> tag. These dependencies are applied to the rest of the member's dependencies with an AND logical operation.

Each group has a unique name that is its local name concatenated with the names of all its parent groups.

Placement:
Inside the <groupings>, <group>, <list-group>, or <union-group> elements
Parameters:
  • name - required The local name of this group.
  • is-a - The Smart Template that represents this group and its children.
  • priority - The priority this group should be assigned relative to other objects in its parent group.
May Contain:
<labels>, <active-if>, <state> <command>, <explanation>, <group>, <list-group>, <union-group>

<list-group>

<list-group name="ListGroupA" priority="10"></list-group>
Defines a special node of the group tree that represents a list.

A list group has the all the same qualities of a regular group, but also may contain some extra elements for describing the features of the list.

A list group automatically creates two states within itself. The "Length" state stores the current length of the list. If this state has an undefined value, then there are no items in the list. The "Selection" state stores the current selection(s). If multiple selections are allowed, then "Selection" is treated like another list-group, allowing list operators like <apply-over> to be applied to it.

Three elements are provided, item-count, min, and max, to allow the specification writer to pre-specify constraints on the size of the list.

Placement:
Inside the <groupings>, <group>, <list-group>, or <union-group> elements
Parameters:
  • name - required The local name of this group.
  • is-a - The Smart Template that represents this group and its children.
  • priority - The priority this group should be assigned relative to other objects in its parent group.
May Contain:
<labels>, <active-if>, <state> <command>, <explanation>, <group>, <list-group>, <union-group>, <selection-type>, <item-count>, <min>, <max>

<union-group>

<union-group name="UnionGroupA" access="read-only"></union-group>
Defines a special node of the group tree that represents a union.

A union group has the all the same qualities of a regular group. It does not contain any extra elements for describing the union.

The union group automatically creates one state named "ChildUsed", which defines the active child variable/group. The access parameter of this state is defined by the access attribute of the union group element.

Placement:
Inside the <groupings>, <group>, <list-group>, or <union-group> elements
Parameters:
  • name - required The local name of this group.
  • access - Defines how users interact with the ChildUsed variable. Possible values are read-only and read-write.
  • is-a - The Smart Template that represents this group and its children.
  • priority - The priority this group should be assigned relative to other objects in its parent group.
May Contain:
<labels>, <active-if>, <state> <command>, <explanation>, <group>, <list-group>, <union-group>

<selection-type>

<selection-type type-name="one" access="read-only" />
Defines the number of selections available in a list and whether or not a user may change the current selection(s).

Placement:
Inside the <list-group> element
Parameters:
  • type-name - required The number of allowed selections. Possible values are one and multiple.
  • access - Defines how users interact with the ChildUsed variable. Possible values are read-only and read-write.

<state>

<state name="StateName" access="read-write" priority="10"></state>
Defines a state variable appliance object.

Placement:
Inside a <group>, <list-group>, union-group>
Parameters:
  • name - required The name of the state variable.
  • priority - The priority this state should be assigned relative to other objects in the same group.
  • is-a - The Smart Template that represents this group and its children.
  • access - Defines how users interact with the ChildUsed variable. Possible values are read-only and read-write.
May Contain:
<active-if>, <labels>, <type>, <apply-type>

<command>

<command name="CommandName" priority="10"></command>
Defines a command appliance object.

Placement:
Inside a <group>, <list-group>, union-group>
Parameters:
  • name - required The name of the command.
  • priority - The priority this state should be assigned relative to other objects in the same group.
May Contain:
<active-if>, <labels>

<explanation>

<explanation name="ExplanationName" priority="10"></explanation>
Defines a explanation appliance object. The labels block, which is required for an explanation object, defines the text that will be used for the explanation.

Placement:
Inside a <group>, <list-group>, union-group>
Parameters:
  • name - required The name of the explanation.
  • priority - The priority this state should be assigned relative to other objects in the same group.
May Contain:
<active-if>, <labels>

<type>

<type name="TypeName"></type>
Describes the value space of a state variable (ex: Boolean, Integer, etc...) and the labels that its values take.

Placement:
Inside the <state> tag
Parameters:
  • name - The name of the type object.
May Contain:
<binary>, <boolean>, <enumerated>, <fixedpt>, <floatingpt>, <integer>, <list-selection>, <string>, <value-labels>

<apply-type>

<apply-type name="TypeName"/>
Allows the re-use of an existing type block within a specification. Using this element is exactly the same as cutting and pasting the type block. No data will be shared with other states that apply the same type. The type must have been declared earlier in the specification document.

Placement:
Inside a <state> tag
Parameters:
  • name - required The name of the appliance object to reference.

<binary/>

<binary/>
Binary type - contains any kind of a binary data, such as sounds or images. A Smart Template must be used with this type to ensure proper interpretation and rendering.

This type may contain arbitrary tags that act are parameters that particular Smart Templates will recognize.

Placement:
Inside the <type> element
May Contain:
Any arbitrary tag.

<boolean/>

<boolean/>
Boolean type - takes on true or false values.

Placement:
Inside the <type> element

<enumerated>

<enumerated></enumerated>
Enumerated type - Define the number of items this composite type contains using the <item-count> element. Note: the <value-labels> element must contain <map> elements that map each of the enumerated values with a label. So if there are 5 enumerated values in a particular enumerated type (denoted by <item-count>5<item-count/>) the value-labels section must contain 5 different mappings of values to labels.

Enumerated type values are treated as integers that range between 1 and the number of items in the type. Zero is not a valid value for an enumerated type. This is important when you specify an index to the <map> tag;

Placement:
Inside the <type> element
May Contain:
<item-count>

<item-count>

<item-count></item-count>
Used to denote how many enumerated values there are in an <enumerated> type. Labels for the items can be defined within the <value-labels> tag.

Placement:
Inside the <enumerated> and <list-group> elements

<fixedpt>

<fixedpt></fixedpt>
Fixed Point type - for variables that take the form of decimal values with a fixed decimal point. The location of the fixed decimal point is specified with the <pointpos> element. Minimum, maximum, and increment values can be defined using the <min>, <max>, and <incr> tags.

Placement:
Inside the <type> element
May Contain:
<pointpos>, <incr>, <max>, <min>

<pointpos>

<pointpos></pointpos>
Defines the position of the decimal point for a fixed point type.

Placement:
Inside the <fixedpt> tag

<floatingpt>

<floatingpt></floatingpt>
Floating Point type - for variables that take the form of decimal values. Minimum and maximum values can be defined using the <min> and <max> tags.

Placement:
Inside the <type> element
May Contain:
<max>, <min>

<integer>

<integer></integer>
Integer type - for variables that take the form of integers. Minimum, maximum, and increment values can be defined using the <min>, <max>, and <incr> tags.

Placement:
Inside the <type> element
May Contain:
<incr>, <max>, <min>

<incr> ... <max> ... <min>

<incr></incr>
<max></max>
<min></min>
Describe minimum, maximum and increment values that the variable may take.

The increment may not be defined for the floating point type.

Placement:
Inside the <fixedpt>, <floatingpt> (except for incr), <integer>, and <list-group> (except for incr) elements.
May Contain:
<static>, <refvalue>

<string/>

<string/>
String type - for variables that take the form of strings. You can specify parameters about the length of the string to help out the interface generators.

Placement:
Inside the <type> element
May Contain:
<min>, <max>, <average>

<average>

<average></average>
Describe the average length of a string.

Placement:
Inside the <string> element
May Contain: <refvalue>, <static>

<value-labels>

<value-labels></value-labels>
Contains one or more <map> tags that provide label dictionaries for specific values that the variable might have.

Placement:
Inside the <type> tag
May Contain:
<map>

<map>

<map index="value"></map>
Specifies a label dictionary for the specific value of a variable (specified by the index parameter).

Certain values of a variable can also be enabled based on dependency information which is specified in the enclosed <active-if> element.

Placement:
Inside the <value-labels> element.
Parameters:
  • index - required The value to associate this dictionary with
May Contain:
<labels>, <active-if>

<labels>

<labels></labels>
Defines a label dictionary for an appliance object or group.

Placement:
Inside the <command>, <explanation>, <group>, <list-group>, <union-group>, <state>, <spec>, or <map> elements.
May Contain:
<label>, <refstring>, <phonetic>, <text-to-speech>

<text-to-speech>

<text-to-speech text="<whisper>mute</whisper>" recording="mute.au"/>
Defines a text-to-speech entry to be included within a label dictionary. The text parameter may contain embedded SABLE markup tags.

Placement:
Inside the <labels> element
Parameters:
  • text - required the text to be spoken. May contain embedded SABLE tags.
  • recording - a recording of the text, if available

<label>

<label></label>
Defines a label to be included within a label dictionary.

Placement:
Inside the <labels> element
May Contain:
string

<phonetic>

<phonetic></phonetic>
Defines a pronunciation to be included within a label dictionary.

Placement:
Inside the <labels> element
May Contain:
string of phonemes using the arpabet representation

<active-if>

<active-if ignore="all" | "parent"></active-if>
Contains dependency information for an appliance object or group of objects. Defines an and relation with all dependencies that are contained within, unless they are grouped within a logical operation block, such as <and> or <or> tags.

Placement:
Inside the <command>, <explanation>, <group>, <list-group>, <union-group>, <map>, or <state> tag.
Parameters:
  • ignore - stop dependency inheritance through the group tree. The possible options are to omit the option, parent, and all
May Contain:
<and>, <apply-over>, <defined>, <equals>, <greaterthan>, <lessthan>, <not>, <or>, <undefined>

<apply-over>

<apply-over list="SomeList" true-if="any"></apply-over>
Used to apply dependency information to lists of information.

There are three different ways that dependencies can be applied. The apply-over block can be true if the dependencies are true for any item in the list, if they are true for all items in the list, or if they are true for no items in the list. The particular choice is chosen with the true-if attribute.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
Parameters:
  • list - required The name of the list group that the dependencies are applied to it.
  • true-if - Sets when the apply-over returns true. The possible options are any, all, or none.
May Contain:
<and>, <apply-over>, <defined>, <equals>, <greaterthan>, <lessthan>, <not>, <or>, <undefined>

<defined>

<defined state="SomeState"/>
Used in conjunction with the <active-if> tag to define that some appliance object depends on a state variable having a defined value.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
Parameters:
  • state - required The name of the state that is depended upon

<undefined>

<undefined state="SomeState"/>
Used in conjunction with the <active-if> tag to define that some appliance object depends on a state variable not having a defined value.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
Parameters:
  • state - required The name of the state that is depended upon

<equals>

<equals state="SomeState">value</equals>
Used in conjunction with the <active-if> tag to define equals dependency information for this state variable.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
Parameters:
  • state - required The name of the state that is depended upon
May Contain:
<refvalue>, <static>

<greaterthan>

<greaterthan state="SomeState">value</greaterthan>
Used in conjunction with the <active-if> tag to define greater-than dependency information for this state variable.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
Parameters:
  • state - required The name of the state that is depended upon
May Contain:
<refvalue>, <static>

<lessthan>

<lessthan state="SomeState">value</lessthan>
Used in conjunction with the <active-if> tag to define less-than dependency information for this state variable.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
Parameters:
  • state - required The name of the state that is depended upon
May Contain:
<refvalue>, <static>

<and>

<and></and>
Defines an and relation with the dependencies that are contained within.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
May Contain:
<and>, <apply-over>, <defined>, <equals>, <greaterthan>, <lessthan>, <not>, <or>, <undefined>

<or>

<or></or>
Defines an or relation with the dependencies that are contained within.

Placement:
Inside the <active-if>, <and>, <apply-over>, <not>, or <or> elements.
May Contain:
<and>, <apply-over>, <defined>, <equals>, <greaterthan>, <lessthan>, <not>, <or>, <undefined>

<not>

<not></not>
Defines a not relation with the dependencies that are contained within.

Placement:
Inside the <active-if>, <and>, <apply-over>, or <or> elements.
May Contain:
<and>, <apply-over>, <defined>, <equals>, <greaterthan>, <lessthan>, <or>, <undefined>

<refstring>

<refstring state="StateName"/>
Used to define a string for a <label dictionary> that depends on the value of a state variable with a string type.

Placement:
Inside the <labels> element
Parameters:
  • state - required The name of a state variable with a string type

<refvalue>

<refvalue state="StateName"/>
Used to define a numeric value for any of the value space parameter tags, except the <pointpos> tag, that depends on the value of a numeric state variable. E.g. a refvalue can be used to set the maximum of a numer state variable to be the value of another state variable.

Placement:
Inside the <max>, <min>, <average>, and <incr> elements.
Parameters:
  • state - required The name of a state variable with a numeric type

<static>

<static value="12">
Used to define a static value in any location where a reference would also be accepted (i.e. the <refvalue> element).

Placement:
Inside the <max>, <min>, <average> and <incr> elements.
Parameters:
  • value - required The static value.

Future Work

In the future, we are planning to add several new features to the specification language. This section discusses a few of these features.

Hints

Sometimes when defining a particular function of an appliance, it seems useful to give the interface generator a hint of how to appropriately render that function. For example, the balance of the output between the right and left speakers has an inherent horizontal quality that should be maintained in the user interface. Currently, there is no way for the specification designer to provide the interface generator with this kind of meta-information that may be critical to generating a good interface. Hints are a generic solution to this problem.

Unfortunately, the idea of a hint is a little too generic to support within the spec. While it is useful to have this information, the language should avoid allowing the specification designer to over-specify a device. This keeps the size of a device specification from getting excessively large, and also relieves the programmers of an interface generator from writing code to interpret a generic hint. A happy medium will need to be achieved.

Command/State Relationships

Some commands have an implicit relationship with state variables on the device. For example, the seek button on a radio must be represented as a command, because its affect on the radio station state variable can not be known a priori. However, it does affect a state variable in some way and this information could useful to the user interface. This will be included in an upcoming revision of the specification language.