Skip to main content Skip to navigation

ADM - the Abstract Definitive Machine

The Abstract Definitive Machine (ADM) was designed by Meurig Beynon, Mike Slade and Edward Yung in 1988. It was developed in collaboration with Mark Norris at British Telecom as part of an investigation into animation tools based on LSD, an agent-oriented specification language. The first implementation was due to Slade. Later Simon Yung developed a translator from ADM to EDEN. This document brief describes the basic principle of Abstract Definitive Machine, the principal features of am, Mike Slade's implementation of the Abstract Definitive Machine, and adm, Simon Yung's ADM to EDEN translator.

Basic Principles of Abstract Definitive Machine

The ADM is motivated by the following:

  • The computational model of EDEN is in some ways unsatisfactory. It includes features such as actions that describe state by side-effect that can be easily abused. Our motivation behind the design of ADM is to address the question, "Is there a good abstract model for "proper use" of EDEN?". The ADM was then designed as a computational model that is based upon definitive representation of state.
  • We need to develop a tool for animating the LSD specifiations. Under this heading, we need:
    • to represent concurrent action by parallel redefinition
    • to reflect context dependence of agent actions by the use of scripts

Implementing ADM - Mike Slade's Version

Program Specification

An ADM program is specified by a set of entity descriptions, each of which consists of a header and a body. The entity descriptions describe the sets of variables and actions which can be instantiated.

entity description
An entity description is of the form
entity name (parameter_list)
{ body }
The name of the entity is an alphanumeric identifier, and must start with a letter. The parameter list is a possibly empty list of comma-separated parameter names, where each parameter name starts with an underscore ("_"), e.g. (_bank, _number). A set of entity descriptions gives a program specification. Any occurrence of "//" is the start of a comment, which is terminated by a newline.
entity body
An entity body is of the form
definition variable_list
action action_list
where variable_list is a list of variables, each of which can be optionally initialised with a definition (e.g. a = b * c * d). The action_list is a comma-separated list of actions.
An action is of the form
guard procedural_action -> command
where a guard is an arithmetic or boolean expression involving constants and other variables. It is false or zero, and true otherwise. A procedural_action is of the form
print (message)
where message is a comma-separated list of quoted strings (e.g. "Number: "), parameters and parametric variables. The value of supplied paramteres or variables is printed. A command is a semicolon-separated list of dynamic actions and definitions, or the keyword stop, which halts execution.
dynamic action
A dynamic action involves the instantiation or deletion of an entity. An entity instantiation is of the form
name (parameter_list)
where name is the name of the entity to be instantiated, and parameter_list is the comma-separated list of parameters. Each parameter can be an arithmetic or boolean expression involving either parameters of the entity or constants, but not variables. An entity deletion is of the same form, but prefixed with the keyword delete. Parameters are used in a call-by-value manner, so a parameter cannot be redefined.
A definition is of the form
variable = expression
where expression is a boolean or integer arithmetic expression. The boolean operators available are <, <=, ==, >=, >, !=, && and ||, and the arithmetic operators available are the four standard operators (+, -, *, /), unary minus (-), the rand() function where rand(n) returns a value between 1 and n, and the arithmetic if...then...else... construct. Expressions can also contain constants (true, false, @ and integers), the evaluation operator (e.g. |date|), and other variables.
A variable is an identifier and possibly an associated parameter list. An identifier is an alphanumeric string which starts with a letter. The associated parameter list may be empty, or may consist of a list of parameters enclosed in square brackets. Parameters are identifiers prefixed by an underscore (_). Examples of variables include valid, book[_number] and cheque[_date,_signed].

Implementing ADM - Mike Slade's Version

Program Execution

Once the entity descriptions are entered, the desired instantiations are made by commands of the form

name (parameter_list)

More than one instantiation of the same entity can occure, but each must be disambiguated by the use of distinct parameters. The program can be executed by typing start. Execution consists of repeated execution cycles. Each execution cycle involves evaluating all guards, performing the procedural actions associated with true guards and putting the associated command lists into the run set, and then executing the lists of commands on the run set. Evaluation is optimised, so "true || x" always evaluates to true. Evaluation of guards and printing of messages is performed prior to any redefinition in an execution cycle.

The program executes until a stop command is executed, no guards are true, the specified number of iterations have been performed, or an error occurs. Errors are classified into notifiable, avoidance and fatal, with explanatory diagnostics. A notifiable error occurs when a variable which is referred to is not in the definition store D, or a dynamic action refers to an entity which is not in the program store P. An avoidance error occurs when a guard cannot be evaluated. A fatal error occurs when there is interference between the commands in the run set. See the summary of the execution model below.

Control variables in am

There are four control variables used by am (default values in brackets):

nflag (true)
if true then print notifiable errors
aflag (true)
if true then print avoidance errors
silent (false)
if false then print information during simulation
iterations (0)
the number of execution cycles which are to be performed in each simulation

Their values can be examined by the keyword status, and can be changed either by using the command line flags -n, -a, -s and -inumber respectively, or as a command from within am using the keyword set, e.g. "set iterations = 12" or "set aflag = false".

Commands to am

Generally a program will be executed for a specified number of execution cycles (according to the value of iterations), and then the user will be allowed to intervene. The contents of the various stores can be examined:

l en
list the contents of the program store P
l ds
list the contents of the definition store D
l as
list the contents of the action store A
l in
list the currently instantiated entities

The run set can be loaded and examined:

load runset
load the run set
l runset
list the run set

Entities can be instantiated, in the same way as the initial instantiations were made. Variables can be redefined directly:

define variable = expression ;

The definition and value of a variable can be printed:


Notice that these facilities are intrinsic to the execution of an ADM program, and are not merely debugging aids. In particular, it is intended that the user will intervene to effect changes of state by means of redefinitions and instantiations. Such changes will be guided by the curent state, which is discerned by examination of the various stores. Execution can then be continued by using the keyword cont.

The implementation described here uses boolean and arithmetic data types and operators. Other underlying algebras could have been used, which would be more suitable for specialised applications. More sophisticated variants of the ADM can be simulated by using the print command to generate input to an interpreter for a special purpose definitive notation, such as DoNaLD and SCOUT.

There is more information in Mike Slade's MSc thesis, including a 'man' page for am in Appendix 3.

Execution of ADM

while there is another variable to be examined in D
if the variable is defined in a non-existent manner
then issue a notifiable error
while there is another guard to be examined in A
evaluate the guard
if the guard cannot be evaluated
then issue an avoidance error
elsif the guard is true
if the procedural action involves a non-evaluable variable
or a non-evaluable variable is evaluated in a command
or a variable used as a parameter cannot be evaluated
then halt execution due to a fatal error
add the associated command to the command list
if the run set is empty
then halt
if the run set contains a redefinition of a non-existent variable
or the run set contains an instantiation of an entity not in P
or the run set contains two redefinitions of the same variable
which are not in the same command list
or the run set contains a redefinition of a variable and a
dynamic action on the entity owning that variable, other
than when the redefinition and dynamic action are in the
same command list and either the redefinition comes before
an entity deletion or after an entity instantiation
or the run set contains an invalid dynamic action
or the run set contains two dynamic actions on the same
entity, other than when they are in the same command list
and valid when performed sequentially
then halt execution due to a fatal error
simulate the parallel execution of all the command lists in the run set

ADM to EDEN Translator - Simon Yung's Work

Comparison of AM and ADM

Since we are talking about two implementations of the same application, I would like to start with the following distinction. Am here refers to the original interpreter for the Abstract Definitive Machine described in Mike Slade's thesis and adm refers Simon Yung's translator to EDEN. The following shows the relative strength and weaknesses for the two implementations.


+ Parallel actions
+ Conflict detection
+ More reliable
+ Has semi-evaluation operator (| |)
- Limited algebra (only has integer and boolean)
- Restricted interface to definitive notations


+ Accept most (if not all) EDEN definitions
+ Fully supported by other definitive notations
+ More advanced parameter specification
- Sequential execution
- No conflict detection
- Poor handling of entity deletion
- Not fully tested yet

The principal aim of translating ADM to EDEN is to enhance the underlying algebra of Abstract Definitive Machine. With ADM it is possible to program more sophisticated simulations. However, because EDEN is basically sequential, the true power of Abstract Definitive Machine cannot be utilised with the current implementation of ADM. The choice of using am or adm is up to the user to determine.

ADM to EDEN Translator - Simon Yung's Work

Using ADM


A typical adm file consists of an adm program enclosed by lines beginning with %adm:

non-processed lines (e.g. lines with Scout, DoNaLD and EDEN)
program in adm
non-processed lines

Note: an adm file may have at most ONE adm program.

After translation, the EDEN file (may have also Scout, DoNaLD ...) can be executed as usual.

After start-up, you may change a few simulation parameters (EDEN variables) before starting the simulation:

stopTime (Default: -1)
The simulation will stop at or after this system time. Note that the system time will not reset after stopping, so you have to set the stopTime forward in order to continue execution. Negative numbers such as -1 carry the special meaning of executing continuously.
Pause (Default: 0)
Minimum time gap between two adm execution cycles, in seconds.
Silent (Default: 0)
Set to suppress messages from the simulation

To start or continue the simulation, type:

        startClock = 1;

To stop the simulation before the preset time is reached, type:

        stopClock = 1;

ADM to EDEN Translator - Simon Yung's Work

Syntax of ADM

Because ADM accepts a richer algebra, the syntax of ADM has deviated from the original specification of the Abstract Definitive Machine.

  • Since Mike uses [] for parameterising variables, which crashes with EDEN's list indexing operator, ADM uses {} instead for parameterising variables.
  • EDEN has no support for semi-evaluation (| |). Therefore ADM follows EDEN's tradition of using 'is' and '=' for defining formula variables and value variables.
  • ADM supports two types of parameters. For example:
    entity fielder(_F)(_P) {
    pos{_F} is _P,
    The first group of parameters (one parameter only (_F) in this case) has the same meaning as the parameters of the original Abstract Definitive Machine - both for disambiguating the entity and for parameter passing; the second group of parameters (also only one parameter (_P) in this case) is only for parameter passing, it does not contribute to the identification of entity. For instance, the ADM instantiation command:
    will create a fielder_sy entity (and a definition
            pos_sy is [0,0,0]
    and so on) which will be deleted by the command:
            delete fielder("sy")

(Note: this document was originally titled "A Note on the Abstract Definitive Machine".)