There are 4 predefined types: int, bool, clock, and chan. Array and record types can be defined over these and other types.
Type ::= Prefix TypeId
Prefix ::= 'urgent' | 'broadcast' | 'meta' | 'const'
TypeId ::= ID | 'int' | 'clock' | 'chan' | 'bool'
| 'int' '[' Expression ',' Expression ']'
| 'scalar' '[' Expression ']'
| 'struct' '{' FieldDecl (FieldDecl)* '}'
FieldDecl ::= Type ID ArrayDecl* (',' ID ArrayDecl*)* ';'
ArrayDecl ::= '[' Expression ']'
| '[' Type ']'
The default range of an integer is [-32768, 32767]. Any assignment out of range will cause the verification to abort.
Variables of type bool can have the values false and true, which are equivalent to the the integer values 0 and 1. Like in C, any non-zero integer value evalutes to true and 0 evaluates to false.
Channels can be declared as urgent and/or broadcast channels. See the section on synchronisations for information on urgent and broadcast channels.
Integers, booleans, and arrays and records over integers and booleans can be marked constant by prefixing the type with the keyword const.
Integers, booleans, and arrays and records over integers and booleans can be marked as meta variables by prefixing the type with the keyword meta.
Meta variables are stored in the state vector, but are sematically not considered part of the state. I.e. two states that only differ in meta variables are considered to be equal. Example:
const int NUM_EDGES = 42; meta bool edgeVisited[NUM_EDGES];
The example uses meta variables to maintain information about the history of a path, without affecting the state-space exploration. With the declaration above and a system with 42 edges, all with an update assigning true to their corresponding entry in edgeVisited, the query below can be used to determine if there is a path where all edges are visited (and find such a path, if trace generation is enabled).
E<> forall (i : int[0,41]) edgeVisited[i]
Arrays can be defined using a either a expressions or a types to specify the size of each array dimensions. If a type is used it must be either a bounded integer or a scalar set, for example:
typedef scalar[3] s_t; int a[s_t];
Record types are specified by using the struct keyword, following the C notation. For example, the record s below consist of the two fields a and b:
struct
{
int a;
int b;
} s;