1st April 2020
The AsmM
concrete syntax (AsmetaL) is a textual notation
to be used by modelers to effectively write ASM
models within the ASMETA framework. It is defined in terms of an EBNF (extended
Backus-Naur Form) grammar derived from a semantic interpretation of the AsmM
metamodel (the abstract syntax).
The AsmetaL
language can be divided roughly into four parts: the structural
language (provides the constructs required for describing the structure
of an ASM model.), the definitional language (provides the basic
definitional elements such as functions, domains, rules and axioms characterizing
an algebraic specification), the language of terms (provides all
kinds of syntactic expressions which can be evaluated in a state of an ASM),
and the behavioral language or
the language of rules (provides a notation to specify the transition
rule schemes of an ASM).
This quick guide gives a
description of each part by presenting the notation in an intuitive style
for better readability, instead of reporting the grammar productions. For
a more formal definition see the EBNF grammar.
Note that, to write an ASM
model of a system, the file containing the ASM spec must contain a single
ASM structure definition and take the ".asm"
extension (e.g. MyAsmModel.asm).
In this guide the following
conventions are adopted:
An ASM model is structured
into four sections: an header, an initialization, a
body and a main rule. The schema below shows the concrete notation for each
section.
|
[asyncr] asm name where: |
[ import m1 [( id11,...,id1h1 )] where: |
|
Body |
definitions : turbo rule TR1 [( x11 in b11,...,x1k1 in b1k1 )][ in b1] = rule1 where: |
[ main rule R = rule ] where: |
[ init I1 :
[ domain D11 = Dterm11
...
domain D1n1 = Dterm1n1
]
[ function F11 [( p11 in d11,...,p1s1 in d1s1 )]= Fterm11
...
function F1m1 [( pm11 in dm11,...,pm1sm1 in dm1sm1 )]= Fterm1m1
]
[ agent A11 : r11
...
agent
A1u1 : r1u1
]
...
]
default init Id :
[ domain Dd1 = Dterm11
...
domain Ddnd = Dtermdnd
]
[ function Fd1 [( p11
in
d11,...,p1s1 in d1s1 )]= Ftermd1
...
function Fdmd [(
pmd1 in dmd1,...,pmdsmd in dmdsmd )]= Ftermdmd
]
[ agent Ad1 : rd1
...
agent
Adud : rdud
]
[ ...
init It :
[ domain Dt1 = Dtermt1
...
domain Dtnt = Dtermtnt
]
[ function Ft1 [( p11
in
d11,...,p1s1 in d1s1 )]= Ftermt1
...
function Ftmt[( pmt1
in dmt1,...,pmtsmt in dmtsmt )] = Ftermtmt
]
[ agent
At1 : rt1
...
agent
Atut: rtut
]
]
where:
- I1,...,Id,...,It are names for the initial states
of the ASM; the default initial state Id is compulsory;
- Dij are names of dynamic concrete domains
- already declared in the signature (see Header) - initialized in the
initial state Ii;
- Fij are names of dynamic functions -
already declared in the signature (see Header) - initialized in the initial state Ii;
- pij are variable terms which specify
the formal parameters of the corresponding function and dij are the domains where pij take their value;
- Ftermij e Dtermij are terms (see section Terms) specifying the intial
value for the function Fij and domain Dij;
- Aij and rij are agent domains (concrete sub-domains of the Agent
type-domain) and rules* assigned as programs to the agents,
respectively.
*Note that, rij is a macro-call
rule (see section Transition rules), i.e. the invocation of a named rule declared
in the ASM or imported from an other module.
If no agent initialization clause is specified, as default the ASM is
assumed single-agent and the program and the identifier of
the unique agent are respectively the ASM's main rule (see Main rule) and the ASM's
name.
A
lightweight notion of module is also supported. An ASM module is an
ASM without a main rule and without a characterization of the set of initial
states. We write a module in the same way as ASMs
with the keyword asm replaced by the
keyword module.
|
module name where name is the name of the ASM module. It
must be equal to the name of the ASM file (as name.asm).
|
[ import m1 [( id11,...,id1h1 )] where: |
|
Body |
definitions : where: |
We
use the following rules to distinguish among names of domains, functions,
enumeration elements, rules, variables:
ID_VARIABLE a
string begining with the dollar sign "$";
e.g. $x $abc $pippo
ID_ENUM
a string of length greater than or equal
to two and consisting of upper-case letters only; e.g. ON OFF
RED
ID_DOMAIN
a string begining with an upper-case letter;
e.g. Integer
X SetOfBags
Person
ID_RULE
a string begining the lower-case letter "r"
followed by the underscore symbol "_"; e.g. r_SetMyPerson r_update
ID_FUNCTION a
string begining with a lower-case letter, but not
starting with "r_"; e.g. plus
minus re
The ASM domains (or
universes) are classified in: typedomains
and concrete-domains.
The type-domains
represent all possible super domains (for practical reasons, the superuniverse |S| of an ASM state S is divided into smaller
universes) and are further classified in: basic type-domains, domains
for primitive data values like booleans, reals, integers, naturals, strings, etc.; structured
type-domains, domains for building
data structures (like sets, sequences, bags, maps, tuples
etc.) over other domains; abstract type-domains,
dynamic user-named domains whose elements have no precise structure and are
imported as fresh elements from a possibly infinite reserve by means of extend
rules (see section Transition rules); and enum
domains, finite user-named enumerations to introduce new concepts of
type (e.g. one may define the enumeration Color
= {RED, GREEN, BLUE} to introduce the new concept of "color").
Concrete domains are user-named sub-domains of
type-domains. As for functions, a concrete domain can be static or dynamic.
The schema below shows the
notation for declaring a domain. Domains declared as "anydomain"
are generic domains representing any other type-domain. The standard library
defines one "predefined" anydomain, named Any, which represents the most generic one. As basic
type-domains only Complex, Real, Integer, Natural, String, Char, Boolean, Rule,
and the singleton Undef={undef} are allowed and defined in the standard library as
predefined basic type-domains. Moreover, two other special abstract domains are
considered predefined: the Agent domain for agents, and the Reserve domain
which works as "reserve" to increase the working space of an ASM. Note
that, the Reserve domain is considered "abstract", and therefore
"dynamic", since it is updated automatically upon execution of an
extend rule (see section Transition rules) – it can not be updated directly by
other transition rules –.
Model
element |
Concrete syntax |
anydomain D where D is the name
of the domain representing any other type-domain. A predefined generic domain
named Any is declared in the standard library and considered the most generic
one. |
|
basic domain D Only Complex, Real, Integer,
Natural, String, Char, Boolean, Rule, and Undef are allowed (users can not define other
basic domains). They are declared in the standard library as
"predefined" basic type-domains. |
|
abstract domain D where D is the name
of the type-domain. |
|
enum domain D = { EL1|...|ELn } where: |
|
Prod ( d1,d2,...,dn ) where d1,...,dn are the domains over which the cartesian
product is defined. |
|
Seq ( d ) where d is the domain over which the sequence domain is defined. |
|
Powerset ( d ) where d is the domain over which the power set is defined. |
|
Bag ( d ) where d is the domain over which the bag domain is defined. |
|
Map ( d1,d2 ) where d1,d2 are the domains over which the map domain is defined. |
|
[ dynamic ] domain D subsetof td where: |
To declare an ASM function
it is necessary to specify the name, the domain, and the codomain
of the function. Moreover, the function name must be preceded by one of the
keywords static, dynamic or derived,
depending on its kind. Dynamic functions are further classified in monitored,
controlled, shared, out and local.
Local dynamic functions are not considered part of the signature; they are
declared and used only in the scope of a turbo transition rule with "local
state" (see section Transition rules).
The schema below shows the
concrete syntax for declaring a function F (the name) from D (the domain)
to C (the codomain).
Model
element |
Concrete syntax |
static F : [ D -> ] C |
|
[ dynamic ] ( monitored | controlled
| shared | out
| local ) F : [ D -> ] C A dynamic function is declared specifying its
kind (monitored, controlled, shared, or out);
optionally, the keyword dynamic can be also added as prefix. Local
dynamic functions can be declared only in the scope of a turbo transition
rule with local state (see section Transition rules). |
|
derived F : [ D -> ] C |
There are two types of terms, basic terms
as in first-order logic (variables, constants and function
applications) and extended terms to represent special terms like tuple terms, collection terms
(sets, maps, sequences, bags), the conditional term, variable-binding
terms, etc.
Model
element |
Concrete syntax |
Complex number, as in x+iy, where x and y are real numbers and i is the imaginary
unit. A complex number must be written without spaces within, because it is
considered a unique token. E.g.: -2-i3 Real terms as floating point numbers. E.g: +3.4 , -3.4
, 3.4, 0.0
,etc... Integer terms as signed numbers. E.g.: 3, +3, -3, 0, etc... Natural numbers as unsigned numbers plus the
suffix "n". E.g.: 3n, 0n, etc... Char terms as char literals delimited by single
quotes. E.g.: 'a', '5',
etc... String terms as a string of literals delimited
of double quotes: E.g.: "hello", "1256", etc... Boolean terms: true,
false Enum term: e where e is an element of an enumeration
type-domain. |
|
v where v is a variable. The variable can
be a location variable (which is replaced by a location term ), or a rule
variable (which is replaced by a rule term ), or a logical
variable (which is replaced by a term that is neither a location term
nor a rule term). |
|
[id . ]f [ ( t1,...,tn ) ] where: |
|
A specialized function term where f is a dynamic
function fixed by the ASM signature. |
Model
element |
Concrete syntax |
( t1,...,tn ) where t1,...,tn are terms, that can have a distinct nature. The empty tuple is not allowed. |
|
[ t1,...,tn ] where t1,...,tn are terms of the same nature. [ ] denotes
the empty sequence. A
finite sequence over numbers (real, integer and natural)
can be also defined by means of an interval notation, as in [ tlow
: tupp [ ,s ] ] where: |
|
[
v1 in S1,...,vn in Sn
[|
Gv1,...,vn ] : tv1,...,vn
] where: |
|
{ t1,...,tn } where t1,...,tn are terms of the same nature. { } denotes the empty set. A
finite set over numbers (real, integer and natural)
can be also defined by means of an interval notation, as in [ tlow
:
tupp [ ,s ] ] where: |
|
{
v1 in D1,...,vn in Dn [|
Gv1,...,vn ] : tv1,...,vn
} where: |
|
< t1,...,tn > where t1,...,tn are terms of the same nature. < > denotes the empty bag. A
finite bag over numbers (real, integer and natural)
can be also defined by means of an interval notation, as in [ tlow
: tupp [ ,s ] ] where: |
|
< in B1,...,vn in Bn [|
Gv1,...,vn ] : tv1,...,vn
> where: |
|
{
t1 -> s1,...,tn -> sn } where: { ->} denotes the empty map. |
|
{v1 in D1,...,vn in Dn [|
Gv1,...,vn ] : tv1,...,vn -> sv1,...,vn
} where: |
|
if
G then tthen [
else telse ] endif where: |
|
switch t case t1 : s1 ... case tn : sn [ otherwise sn+1 ] endswitch where: |
|
let ( v1=t1,
..., vn=tn ) in tv1,...,vn endlet where: |
|
( exist v1 in D1,...,vn in Dn
[ with Gv1,...,vn ]) where: |
|
( exist unique v1 in D1,...,vn in Dn
[ with Gv1,...,vn ]) where: |
|
( forall v1 in D1,...,vn in Dn
[ with Gv1,...,vn ]) where: |
|
D where D is the name of a domain declared
in the ASM signature or directly the expression for a structured type-domain. |
|
<< R[ ( D1,...,Dn ) ] >> where R is the name of a defined transition rule, and D1,...,Dn (if any) are the domains of the formal rule parameters*. It is a special term used to denote a transition rule where a term is expected (e.g as actual parameter in a rule application to represent a transition rule). Its interpretation results, therefore, in a transition rule. *Similarly to functions, rules can
be overloaded. When rules are overloaded, it is necessary to indicate
the domains of the formal rule parameters. |
In addition to these terms, the AsmM
concrete syntax admits special expressions to support the infix notation for some well-known functions on basic domains (like plus,
minus, mult, etc.) of the AsmM Standard Library. In these expressions, basic
terms and the domain term are used as operands. The table
below show the infix operators corresponding to these functions,
together with their associativies and priorities. The
operator priorities range from 0 to 9, where 9 indicates
the strongest one and 0 the weakest one.
Function |
Infix
operator |
Type |
Associativity |
Priority |
minus (unary) plus (unary) |
- + |
Complex → Complex |
left |
9 |
pwr |
^ |
Real × Real → Real |
left |
8 |
mult |
* |
Complex × Complex →
Complex |
left |
7 |
div |
/ |
Complex × Complex →
Complex |
left |
7 |
mod |
mod |
Integer × Integer → Integer |
left |
7 |
plus |
+ |
Complex × Complex →
Complex |
left |
6 |
minus |
- |
Complex × Complex →
Complex |
left |
6 |
lt |
< |
Real × Real → Boolean |
left |
5 |
le |
<= |
Real × Real → Boolean |
left |
5 |
gt |
> |
Real × Real → Boolean |
left |
5 |
ge |
>= |
Real × Real → Boolean |
left |
5 |
eq |
= |
D × D → Boolean |
left |
5 |
neq |
!= |
D × D → Boolean |
left |
5 |
in |
in |
powerset(D) × D → Boolean |
left |
4 |
notin |
notin |
powerset(D) × D → Boolean |
left |
4 |
not |
not |
Boolean → Boolean |
left |
3 |
and |
and |
Boolean × Boolean →
Boolean |
left |
2 |
xor |
xor |
Boolean × Boolean →
Boolean |
left |
1 |
or |
or |
Boolean × Boolean →
Boolean |
left |
1 |
implies |
implies |
Boolean × Boolean →
Boolean |
left |
0 |
iff |
iff |
Boolean × Boolean →
Boolean |
left |
0 |
In a given state, a
transition rule of an ASM produces for each variable assignment an update set
for some dynamic functions of the signature. We classify transition rules in
two groups: basic rules and turbo rules. The former are
simply rules, like the skip rule and the update rule, while
the latter are rules, like the sequence rule and the iterate rule,
introduced to support practical composition and structuring principles of the ASMs. Other rule schemes are derived from the basic and the
turbo rules.
Model
element |
Concrete syntax |
skip |
|
l := t where: |
|
par R1 R2 ... Rn endpar where R1,R2,...,Rn are transition rules. |
|
if
G then Rthen [else Relse] endif where: |
|
switch t case t1 : R1 ... case
tn : Rn [otherwise Rn+1] endswitch where: |
|
let ( v1=t1,
..., vn=tn ) in Rv1,...,vn endlet where: |
|
forall v1 in D1, ..., vn in Dn with Gv1,...,vn do Rv1,...,vn where: |
|
choose v1 in D1, ..., vn in Dn with Gv1,...,vn do Rv1,...,vn [ ifnone
P ] where: |
|
r [t1,...,tn] where: r [] is used for a macro with no
arguments. |
|
extend D with v1,...,vn do R where: |
|
seq R1 R2 ... Rn endseq where R1,R2,...,Rn are transition rules. |
|
iterate R enditerate where R is a transition rule. |
|
while G do R where: |
|
r(t1,...,tn) where: r() is used to call a rule with no
arguments. |
|
recwhile G
do R where G is a term representing a boolean condition and R is a transition rule. |
|
[dynamic] local f1 :[D1 ->]C1 [ Init1 ] where: |
|
try P catch l1,...,ln Q where: |
|
l <- r(t1,...,tn) where: |
|
v where v is either a rule variable or a
function term. This rule works as a form of wrapper to allow the use of
either a function term or a variable term where a rule is expected. |
Comments can be written as
follows:
// text to be commented
/* text to be
commented*/