Acumen 2016 Reference Manual, Walid Taha

Acumen 2016 Reference Manual (2016/12/11)

Author:  Walid Taha

Acumen is an experimental environment for model-based development of hybrid-systems. It is built around a small, textual modeling language. This document is a reference manual for the key features of the environment and the language when the “Traditional” option is selected from the semantics pull-down menu.

The most up-to-date version of this manual is available at http://bit.ly/Acumen-manual-2016.  To report bugs with Acumen and/or issues with this document, please use the online form available at http://www.acumen-language.org/p/report-bug.html. To continue to be updated about the development of Acumen, please subscribe to the announcements mailing list at http://bit.ly/Acumen-list.

The Acumen Environment and Graphical User Interface

The standard mode for using the Acumen environment is through the GUI, which makes it possible to:

Basic Structure of An Acumen Model

A complete Acumen model consists of a series of model declarations. A complete model must contain a declaration for a model called Main. The declaration of the Main model must have exactly one parameter. By convention, that parameter is called simulator. For example, a typical model would have this form:

   model Ball (mass, size) =

     // Body of declaration of a model for a Ball

   

   model Main (simulator) =

     // Body of declaration of the model Main

The remainder of any line after the keyword // is ignored and treated as a comment. Similarly, any text that starts with /* and ends with */ is also a comment.

Model declarations may appear in any order.

Model Parameters and the “Initially” and “Always” Sections

Model declarations start with a name for the model and a list of formal parameters, followed by an equality sign (=). After the name and parameters, the model declaration can contain an “initially” section. An example is as follows:

   model Ball (mass, size) =

     initially

       x_position = 0,

       y_position = 0 

     always

       // Rest of the body of declaration of model Ball

“Initially” sections define the initial value for the variables introduced in this section. Parameter variables can be used in the definition of these initial values. Both parameter variables and model variables can be used in the rest of the body of the model declaration. Variables introduced in this section cannot be referenced in the section itself.

“Always” sections contain a sequence of statements, usually consisting of assignments and/or conditional assignments.  It is very important to realize that all such assignments are executed at the same time.  Thus, the order of assignments does not matter.  It is still possible to model the change of value (let’s say a variable x) through the use of derivatives (the special variable x’) and the use of next-value (the special variable x+).  As we will see in the rest of this document, both of these variables can be assigned a value to cause the value of the original variable (in this case x) to change in different ways.  Derivatives make it possible to change the value in a continuous manner, and next-value makes it possible to change the value in a sudden (discontinuous) manner.

Object Instantiation

Within a model declaration, it is possible to instantiate objects of another model. This can be done in either the “initially” section or in the rest of the body. When done in the “initially” section, it is called a 'static' instance, and when in the body, a 'dynamic' instance.

   model Main (simulator) =

     initially

       b = create Ball (5, 14) // Static instance

     always

       // First part of model definition

       create Ball (10, 42)    // Dynamic instance

       // Last part of model definition

New users will find it easier to work with static instances, since creating dynamic instances requires more care.

Expressions

Acumen expressions can be built out of variables, literals, built-in functions, vector generators, and summations.

Variable Names

In Acumen, a variable name is a sequence of one or more characters starting with a letter or an underscore, and thereafter possibly including digits. Examples of variable names include a, A, red_robin, and marco42.

As a convention, variable names used in the language in a special way usually start with an underscore (_). An example is the special variable _3D.

Variables

A variable has a name followed by zero or more apostrophes ('). Such apostrophes indicate that this variable is the time derivative of a variable with the apostrophe removed. Examples of such variables include x', x'', and x'''.

Literals

Acumen supports literal values of different types, including booleans (true and false), integers (1, 2, 3, etc.), decimal values (1.2, 1.3, etc), floating point numbers (1.2E-17, 1.3E14, etc.), strings ("rabbit", "ringo", etc.), and vector values ((1,2,3), (true, false, false), ("a", "ab", "abc"), etc.).

The special constants, pi, children, and the names of basic colors (see below) are also literals.

Vector and Vector Generators

Vectors can be constructed by writing things like (1,2,3) and (1,1+1,2+1).  In addition, they can be generated by specifying a starting value, step size, and ending value. This is written as start:step:end. For example, 4:2:8 generates (4,6,8). We can omit the step if it is 1, and write start:end. For example, 4:8 generates (4,5,6,7,8).

We can look up elements in a vector by writing x(0) to mean the first element of x, writing x(1) for the second element, and so on.  The length function can be used to determine the length of lists:

model Main(simulator) =

  initially

    list = (1,2,3,4,5),

    size = 0

  always

    size = length(list)

More typically, length(list) would be used for iteration.

Matrices

A matrix is represented a vector of vectors.  For example, the following is a two dimensional identity matrix: ((1,0),(0,1)).   The supported operations are the arithmetic operators (+, -, *); functions inverse (inv), transpose (trans) and determinant (det).  A sub-matrix can be extracted from an existing matrix using index slicing:

model Main(simulator) =

  initially

    I3 = ((1,0,0),(0,1,0),(0,0,1)),

    I2 = ((0,0),(0,0))

  always

    I2 = I3(0:1,0:1) // First two rows and columns of I3

Summations

It is possible to iterate over collections to compute the summation of a series of values. The following example illustrates the syntax for this operation:

  sum i*i for i=1:10 if i%2 == 0

As this example illustrates, this construct allows us to indicate the iteration range and to filter the values being adding based on a condition. The if clause can be omitted when the intention is that the condition is always true.

Statements

There are five types of statements in Acumen, namely: continuous assignments, conditional (or guarded) statements, discrete assignments, iteration, and sequences of statements.

Continuous Assignments

A continuous assignment has a left-hand side that must be a variable or the derivative of a variable, and a right-hand side that can be any expression. Examples include the following:

  a   = f/m

  x'' = -9.8

Any such statements in the same object are evaluated simultaneously after all discrete assignments have been performed and are not causing any further change to the state of the program. Continuous assignments where the left-hand side is not a derivative are taken into account when assignments (both continuous and discrete) are evaluated. Thus:

  x'' = -g, g = 9.8

is equivalent to:

  x'' = -9.8

If-Statements

If-statements are the first type of conditional statement. They allow us to express that  different statements take effect under different conditions. The following code illustrates how if-statements are written:

  if (x>0) then

    x'' = -9.8

  else

    x' = 0

In this example, as long as x is greater than zero then the first continuous assignment is in effect. The result will be that the x' is decreasing, and when it becomes negative, x will also decrease until the condition is no longer true. Once that happens, the second equation will take effect, which will cause x to remain constant. By surrounding multiple comma-separated statements in parentheses, they can be included in the else branch of an if statement :

  if (x>0) then

    x'' = -9.8

  else

    (x' = 0, ...)

Match-Statements

A match-statement is the second type of conditional statement. It can be viewed as a generalization of an if-statement. It allows us to enable different statements under multiple different cases depending on the value of a particular expression that we are matching on. The following example illustrates this idea:        

  match myCommand with

  [ "Fall" ->

    x'' = -9.8

  | "Freeze" ->

    x' = 0

  | "Reset" ->

    x = 0

  ]

Only one case can be enabled at any one point in time.  Matching must be done against an explicit, constant value (like "Fall" and "Freeze").  If multiple clauses match the same value, only the first one will be enabled.

Discrete Assignments

A discrete assignment has a left hand side that must be a variable or the derivative of a variable, and a right hand side that can be any expression. Examples include the following statements:

  t+   = 0

  t'+  = 1

  t''+ = 0

Discrete assignments represent an instantaneous change in values. They are used in the private section of models, where the initial values for variables are specified. They can also be used to indicate that there is a discontinuous change (hence the name “discrete”) to a particular variable during a simulation.

For a simulation to behave properly, any discrete assignment in the body of a model definition (that is, outside the “initially” section) should generally occur inside a conditional statement (such as an if-statement or a match statement). The following example illustrates an acceptable use of discrete assignments:

 

  if (x>=0) || (x'>0) then

    x'' = -9.8

  else

    x'+ = -0.5 * x'

Here, the value of x' is reset to change direction (the negative sign) and reduce magnitude (multiplication by 0.5) to model a “bounce” when a “ball” of height x hits the ground at level 0.

Note that as soon as the assignment happens, the condition is falsified, so the discrete assignment is enabled for exactly one time instant. Furthermore, because the condition requires that x' is negative, the new x' must be positive; therefore, we can also expect that the condition on the first line will become true, and the “ball” will again be subject to a downward acceleration (which can be seen as modeling the effect of gravity).

For-Statement

For-statements allow us to perform iteration. Examples include:

  foreach i in 1:10 do x=2*y

and

  foreach c in children do c.x + = 15

The second type of iteration illustrates how an object can assign a value to the x field of all its children.

Sequences of Statements

Multiple simultaneous statements can be expressed in a collection by simply placing a comma (,) between them. For example:

  x'' = -9.8,

  y'' = 0

Order is irrelevant in such statements, as they are always evaluated simultaneously.

How a Model is Simulated (Order of Evaluation)

Initially, the simulation of an Acumen model has only one object, Main. As objects are created dynamically, a tree of objects is formed. Main is always the root of this tree. The children of an object are the objects created by that object.

Every simulation sub-step involves a traversal of the entire tree starting from Main. Two kinds of sub-steps are performed, according to the diagram below. During a discrete step, discrete assignments and structural actions (create, terminate and move) are processed: the tree is traversed to perform active structural actions and collect active discrete assignments. Once collected, the discrete assignments are performed in parallel. So, for example, x+ = y, y+ = x is a swap operation. For every object, first the structural actions of each parent are executed, and then the structural actions of all children are executed. If there are active actions that also change the state, we keep making discrete steps in this fashion. Otherwise, we make a continuous step. During a continuous step, all continuous assignments and integrations are performed.

Visualization Using the _3D Panel

Acumen has a _3D panel that can be used to create static or dynamic visualizations in 3D. Following we introduce the constructs needed to use this functionality.

Colors

All 3D objects must have a color. Colors are described by a three-dimensional intensity representing the red-green-blue (RGB) dimensions of the colors. The color is represented by a vector of the form (r,g,b). Each of the values of r, g, and b is called an intensity, and is a real number be between 0 and 1. The following display illustrates some basic examples of RGB combinations:

It is important to note here that the vectors indicate intensities, and NOT coordinates. The fact that both are represented as a triple (that is, the vector is size three) is coincidental.

To make it easier to put together _3D statements, Acumen also defines constants for the intensities of the basic colors:  red, green, blue, white, black, yellow, cyan and magenta.

Transparency

A 3D object has a transparency parameter, which takes a floating point number ranging from 0 to 1. With value 0 representing opaque and 1 for the maximal transparency. The following model depicts a transparent box:

model Main(simulator) =

initially

  _3D = (), _3DView = ()

always

  _3D = (Box                

         center=(0,0,0)      

         size=(0.2,1,3)      

         color=red          

         rotation=(0,0,0)

         transparency = 1),

  _3DView = ((0,-10,0), (0, 0, 0))

Coordinate System

Acumen's _3D panel display uses a right-hand coordinate system, which is illustrated by the above image from the Wikipedia article on the Cartesian Coordinate System:

The figure on the right illustrates the coordinate system and some examples of points in that system. Each point is marked by a small cube, and next to it is text indicating the (x,y,z) coordinate of that point:

Note that, unlike in the case of the color illustration above, the triples here are coordinates in three dimensional space, and not color intensities.

Untitled.png

Rotations are specified as a triple of angles (in radians) about the center of the object, and are applied in the order described in the above illustration.

Text

Text can be displayed in the _3D panel using a command such as the following:

 _3D =

 (Text                 // Type of _3D object

  center=(-2.2,0,0)    // Starting point in (x,y,z) form

  size=0.75            // Font size

  color=(255,255,0)    // Color in red-green-blue (RGB) intensity

  rotation=(pi/2,0,0)  // Orientation (pi/2 around x-axis)

  content="Hello!")    // Text you wish to display

Note that the starting point is where the text starts (the leftmost point of the displayed text), and not the center of where the text is displayed.

Orientations are angles that indicate how the text should be rotated around the x-, y-, and z-axes, respectively. Rotations are measured in radians, and specify an anti-clockwise rotation. Orientation rotations can be interpreted as rotations around the global frame of reference with the origin relocated to the reference point of the object that we are rotating; they can also be interpreted as having the rotation around the x-axis done first, then the y-axis, then the z-axis.

Here are the characters supported by the Text primitive:

Box

A box can be displayed in the _3D panel using a command such as follows:

 _3D = (Box                 // Type of _3D object

        size = (0.2,1,3))   // Size in (x,y,z) form

Note that, unlike text, boxes and the other geometric objects use the point indicated in the _3D statement to represent its center point rather than a corner point.

Cylinders

A cylinder can be displayed as follows:

 _3D = (Cylinder

         radius = 0.1        // Radius

         length = 4)         // Length

Unlike a box, a cylinder only has two parameters to specify its dimensions, namely, radius and length.  The initial orientation is for its length to be along the y-axis.

Cone

A cone can be drawn as follows:

 _3D = (Cone  

         radius = 0.4        // Radius

         length = 1)         // Length

Note the similarity between the parameters for the cone and cylinder. The parameter types are the same, but they have a different meaning depending on the shape.  The length is along the y-axis, and the pointy side is directed with the increase in the y-axis.

Spheres

A sphere can be drawn as follows:

 _3D = (Sphere                   // Type of _3D object

         size = 0.55)            // Size

Orientation on a sphere will not have a significant impact on the image.

Surface

A parametric surface, which is defined by a parametric equation with two parameters can be drawn using the Surface 3D object.  A torus with outer radius 2 and inner radius 0.5 can be drawn as follows:

_3D = (Surface (phi, psi) ->

 ((2 + 0.5*cos(psi))*cos(phi),

  (2 + 0.5*cos(psi))*sin(phi),    

   0.5*sin(psi))

  foreach phi = [0 .. 7] psi = [0 .. 7]

    resolution = 0.2

  color = 0.6*blue + 0.4*white)

Note for each parameter, its range should be specified using an interval such as [0 .. 7].  In the above example, both phi and psi are ranging from 0 to 7.  To control the smoothness of the surface, one can specify the resolution parameter, the smaller the value the more smooth the surface object will be, but the rendering time will be longer.

Obj

Acumen supports loading 3D meshes saved as OBJ files as follows:

_3D = (Obj

        color = cyan         // Blended with texture of OBJ file

        content = "Car.obj") // OBJ file name

Default Values Are Provided for All Parameters for all Shapes

To make things easier, a default value is provided for any missing parameters.  Therefore, any of the following examples are acceptable ways to produce a sphere:

 _3D = (Sphere                      // Type of _3D object

         center = (0,0,0)           // Center point in (x,y,z) form

         color = cyan               // Color

         rotation = (0,0,0))  // Orientation

or

 _3D = (Sphere                       // Type of _3D object

         center = (0,0,0)     // Center point in (x,y,z) form

         rotation = (0,0,0) ) // Orientation

or

 _3D = (Sphere                // Type of _3D object

         center = (0,0,0))    // Center point in (x,y,z) form

or even

 _3D = (Sphere)               // Type of _3D object

Similarly, defaults are provided for all other types of 3D objects.

Composites

All the display commands illustrated above can be combined by adding a comma separator and inserting multiple commands inside the outer parens. For example, the following command illustrates the effect of the rotation parameter:

  _3D =

    (Text center=(-2,0,0) size=1 color=(1,0,0)

          rotation=(-pi/2,0,0) content="X",

     Text center=(-2,0,0) size=1 color=(0,1,0)

          rotation=(-pi/4,0,0) content="2",

     Text center=(-2,0,0) size=1 color=(0,0,1)

          rotation=(0+t,0,0) content="3",

     Text center=(0,0,0) size=1 color=(1,0,0)

          rotation=(0,0,0) content="Y",

     Text center=(0,0,0) size=1 color=(0,1,0)

          rotation=(0,pi/4,0) content="2",

     Text center=(0,0,0) size=1 color=(0,0,1)

          rotation=(0,pi/2+t,0) content="3",

     Text center=(2,0,0) size=1 color=(1,0,0)

          rotation=(0,pi/2,0) content="Z",

     Text center=(2,0,0) size=1 color=(0,1,0)

          rotation=(0,pi/2,pi/4) content="2",

     Text center=(2,0,0) size=1 color=(0,0,1)

          rotation=(0,pi/2,pi/2+t) content="3")

This example shows how to combine multiple text objects, but the list can contain combinations of different object types.

Shapes, their Parameters, and their Default Values

The following table lists the _3D shapes recognized by Acumen, together with supported parameters and the corresponding default values.

Shape

center

rotation

color

coordinate

transparency

content

Box

(0,0,0)

(0,0,0)

(0,0,0)

"global"

0

None

Cone

None

Cylinder

None

Obj

“”

Sphere

None

Text

“”

Trangle

None

To specify the size of a 3D object, the following table lists the different default values supported for different shapes,

Shape

Size parameter and its default value

Box

size =(0.4,0.4,0.4) or

length = 0.4 width = 0.4 height = 0.4

Cone

size =(0.4,0.2) or 

length = 0.4 radius = 0.2

Cylinder

size =(0.4,0.2) or 

length = 0.4 radius = 0.2

Triangle

points = ((0,0,0),(1,0,0),(0,1,0))  height = 0.4

Obj

size = 0.2

Sphere

size = 0.2 or

radius = 0.2

Text

size = 0.2

Surface

resolution = 0.2

Dynamic _3D Displays

In the examples above we simply assigned an initial value to the _3D field in the initially section in the current object. In fact, it is also possible to continuously assign a changing value to the _3D parameter. When this is done, the _3D panel animates the progression of this three- dimensional scene, as observed through the simulation time.

Manual Control of the View of the _3D Scene

To rotate the view around the center of the current _3D view, click and hold the left mouse button and move the mouse. To change the center of the _3D view, click and hold the right mouse button (on Mac OS, tap touchpad with two fingers ) and move the mouse. The mouse wheel can be used to zoom the view in and out (on Mac OS, swipe up and down with two fingers ).

In-model Control of the View of the _3D Scene

The camera that defines the _3D view can also be manipulated directly in the model. This is done by adding the special variable _3DView to the model. Note that, as with the _3D variable, to use the _3DView variable in the always section, it is necessary to first declare it in the initially section. In the following model, the camera is situated at (10,10,10) and is rotated by 0.5 radians along each axis, so that it looks at the origin:

  initially

        _3D = (), _3DView = ()

  always

        _3D =        (Box         center=(0,0,0) size=(1,1,1)

                     color=red rotation=(0,0,0)),

   _3DView = ((10,10,10), (0.5,0.5,0.5))

This configuration of the _3DView variable will yield the following view of the _3D scene:

Static object view

To make a object static without affecting by the position of camera or munal view rotation or zoom in/out, the user can set the parameter coordinates to "camera".For example:

 _3D =  

   (Text

     center=(-2.2,0,0)          

     color=(1,1,0)      

     coordinates = "camera"

     content="Hello Acumen!")

Would result in the following visualization.  Note that although the view has been manually rotated, as indicated by the axises.  The text is still facing the screen. 

Built-in Functions

Acumen provides the following built-in functions:

In most cases, operators that start with a letter are prefix operators that take explicit arguments, such as the case with sin(x), while operators that start with a symbol are infix operators, such as x+y. The only exceptions to this rule are xor, which is an infix operator, and unary -, which is a prefix operator that has no parentheses.

Function Declarations

To use custom functions beyond the build-in ones, Acumen provides a top-level function structure.  The structure of a typical function declaration is as follows:

function f(x,y) = x  + 2*y

Inlining, which substitute the call to a function in the code with a copy of the function body using the actually input arguments, is performed for every function call before running the simulation. For example, the function call f(1,2)is replaced with the expression 1 + 2 * 2.

Operator Precedence

The precedence ordering for built-in functions in Acumen is as follows:

  1. Boolean disjunction ||
  2. Boolean conjunction &&
  3. Boolean equality == and then Boolean inequality ~=
  4. Integer less than <, greater than >, less than or equal to <=, and then greater than or equal to >=
  5. Vector generators :
  6. Numeric addition +, subtraction -, vector addition .+, vector subtraction .-
  7. Numeric multiplication *, division /, vector multiplication .*, vector division ./, and integer modulus %
  8. Numeric exponentiation ^ and then vector exponentiation .^
  9. Numeric unary negation -
  10. Field access .
  11. Built-in prefix function applications and vector lookup
  12. Field check ?

Intervals

The reference semantics supports the entry of intervals in models, and simulates using a sampling of values from these intervals. By default, only the limits of the interval are sampled. It is important to note that simulations produce runs representing simulation output on individual (sampled) values and not on all values within the interval.  To illustrate the use of intervals, consider the following model and the plot produced by its simulation:

model Main(simulator) =

initially

  x=0, x'=0, x''=0,

  a=1, b=1,

  _Plot=(x,x')

always

  x''= a*(1-x) - b*x'

Intervals can be used in place of numerical values in the initially section. For example, we may wish to consider the effect of changing the parameter a on the dynamics of the system. This can be achieved by replacing the value 1 in the initialization a=1 with the interval value [0.5 .. 2].  The resulting model and output from this simulation are as follows:

model Main(simulator) =

initially

  x=0, x'=0, x''=0,

  a=[0.5 .. 2], b=1,

  _Plot=(x,x')

always

  x''= a*(1-x) - b*x'

When more frequent sampling is desired, this can be expressed by following the interval literal with a splitby keyword.  The following example illustrates the use of this construct:

model Main(simulator) =

initially

  x=0, x'=0, x''=0,

  a=[0.5 .. 2] splitby 5, b=1,

  _Plot=(x,x')

always

  x''= a*(1-x) - b*x'

Naturally, intervals can be used (and split) in multiple different initial values.

model Main(simulator) =

initially

  x=0, x'=0, x''=0,

  a=[0.5 .. 2] splitby 5,

  b=[0.5 .. 2] splitby 5,

  _Plot=(x,x')

always

  x''= a*(1-x) - b*x'

Distributions

Variables can now be assigned probability distributions in the initially section. For example:

initially x = normald(0,1) central 0.75 splitby 5

This statements creates split intervals representing the bounds of the central (that is, closes to the mean) five equi-probable intervals with a probability that adds up to 0.75 and that are drawn from a normal distribution with mean 0 and standard deviation of 1.

If we consider the example above and the associated plot, we can express a related simulation as follows:

model Main(simulator) =

initially

  x=0, x'=0, x''=0,

  a=normald(1,0.10) central 0.99 splitby 20,

  b=normald(1,0.10) central 0.99 splitby 20

always

x''= a*(1-x) - b*x'

The main characteristic to note here is that even when the standard deviation on the distribution is relatively small, when we try to cover 99% of possible trajectories we notice that a larger number of them can take a long time to stabilize, compared to when we consider a strictly bounded range for the possible values for the parameters.

Other distributions that are available include the uniform and beta distributions:

uniformd(lo,hi)

betad(lo,hi,alpha,beta)

For a simulation that contains variables with probability distributions, clicking on the plot at a given time will produce a plot of the estimated probability.

Simulator Settings

The simulator setting to the Main model provides the user with a mechanism to codify how the model should be simulated, as part of the model itself. There are three settings that the user can specify:

It is generally recommended that any adjustments to these values are made using a discrete assignment at the very start the simulation time.

Command Line Parameters

For batch processing, it is often useful to pass parameters to a simulation from the commandline. For this purpose, Acumen supports a simple mechanism for passing such information. It consists of two parts:

The follow example illustrates how the parameters can be passed from the command line, and how the can be used within the model.

To start a simulation in offline mode from the command line with certain parameter values, write:

java -jar acumen.jar --parameters abc 11

To use these values, the model itself can use the simulator.parameters type as follows:

model myModel (a,b) =

initially x=a, x'=b, x''=0

always  x''=-x

model Main (simulator) =

initially

 p = create simulator.parameters(), // Get command line parameters and put in an object

 init_phase = true

always

 if init_phase

  then if (p?a && p?b) // Check to see if parameters were provided in the command line

           then create myModel (p.a,p.b)    // Use command line parameters a and b

           else create myModel (  17, 42) , // Default values, useful for interactive mode

       init_phase+ = false

  noelse

It is good practice to use the ? test on parameters to make sure that they have been provided (as shown in the example above), and then to use default values in the case that they are not there. This ensures that models can be easily run in both command line and interactive modes.

Print to Standard Output (stdout) or Console

For batch processing and also for the interactive mode, Acumen provide support for printing. In batch mode, printing sends output to stdout. In interactive mode, it goes to the console.

To see how the print annotation works, consider the following model:

model Main (simulator) =

initially 

  x = 5

// print out the value x-1 and x

always

  if x > 0 then

    x+ = print("x-1=", print("x=",x)-1)

  noelse

Running this model results in the value of x being repeatedly decremented by one until it reaches zero. If we wish to observe this process on the console (or stdout), then we would insert a print annotation around the value being assigned to x in the if statement.  The annotated version is as follows:

model Main (simulator) =

initially 

  x = 5

always

  if x>0

    then x+ = print(x-1)

  noelse

Note that on the console the values are printed backwards (as are all messages).

BNF of Acumen

The following context free grammar defines the current syntax of the Acumen language.   The notations ?, * is used for optional and repetition, and text after \\ is for comment.

digit

::=

[0-9]

letter

::=

 [A-Za-z]

symbol

::=

! | @ |  # | $ | % | ^ | & | ( | ) | - | + | =|  | {|  } | [ |  ] |  : | ;
“| ‘ | < | >| , | . | ? | / | * |

id_character

::=

letter | “_”

ident

::=

 id_character (int | id_character)*

int

::=

“-” ? digit+

float

::=

“-” ? digit+ “.” digit+

boolean

::=

true | false

string

::=

(symbol | id_character)*

gvalue

::=

nlit | string | boolean |  [ nlit .. nlit ] // interval

nlit : GroundValue

::=

 int | float  // number

name: Variable

::=

ident | name

expr : Expressions

::=

 | gvalue | name    

 | type (className) // type of

 | f(expr*) // function application

 | expr op expr       // binary operation

 | expr’[expr] // partial derivative

 | (expr)’ | (expr)’’ … // time derivative

 | (expr*) // expression vector

 | name(expr)     //  vector indexing 

 | (expr)

 | expr . name // field access

 | expr ? name // field check        

 | let  name = expr * in expr  // let notation

 | sum expr in name = expr if expr // summation

op: Operators

::=

| + | - | * | / | % | < | > | <= | >= | && | || |

| == | ~= | .* | ./ | // pointwise operator

action : Action

::=

 | name+ = expr   // discrete assignment

 | name = expr   // continuous assignment

 | create className (name*)

 | name:= create className (name*) 

 | terminate expr // eliminate object

 | move expr expr   // move object to new parent      

 | if expr then action*  else action* // conditionals

 | foreach name in expr do action*  //  foreach

 | match expr with [ clause | clause ... ]

 | claim expr  // claim predicate expr is true

 | hypothesis expr | hypothesis string expr

clause: Clause

::=

 gvalue claim expr  -> action* | case gvalue -> action*

classDef : Class Definition

::=

 model className (name*) inits action*

inits: Initialization

::=

initially (name := expr | create className (expr*))* always

program : Prog

::=

classDef *

include

::=

 #include string

interpreter

::=

"reference2015" | "optimized2015" | "reference2014" | "optimized2014" | "reference2013" | "optimized2013" | "reference2012" | "optimized2012" | “enclosure2015”

semantics

::=

#semantics interpreter

function

:=

function ident (ident +) = expr

fullProg

::=

 semantics? Include? function?  classDef*

Acknowledgements

This manual was prepared by Walid Taha. It was edited by Mark Stephens. Valuable input relating to the core language and its intricacies was provided by Kevin Atkinson, Adam Duracz, Veronica Gaspes, Viktor Vasilev, Fei Xu and Yingfu Zeng. Roland Philippsen and Jawad Masood suggested several suggestions from the point of view of actual users with expertise in analytical dynamics.  Support for the development of Acumen and this manual was provided by the US National Science Foundation (NSF) Cyber-Physical Systems (CPS) project #1136099, by the Swedish Knowledge Foundation (KK), and by Halmstad University.

Licensed under a Creative Commons Attribution 3.0 Unported License 

Available online at http://bit.ly/Acumen-manual-2016