Types
A type defines the set of possible values of an expression or a variable. Its syntax is defined as follows.
-
The
ElementaryType
block contains types that do not build on other types. They are explained further in Elementary types. -
The
ContainerType
block contains types that can store values of a single other type, the 'list', 'set', and 'dictionary' type. These types are further explained in Container types. -
The
TupleType
block describes 'tuples', a type that can hold values of several other types. -
The
ChannelType
blocks describes communication channels that connect processes with each other, see Channel type for more explanation. -
The
DistributionType
block contains the stochastic distribution type, explained in Distribution type. -
The
FunctionType
can hold a function definition. It allows you to pass a function to a process or another function. It is further explained in Function type. -
The
ProcessType
can hold a process definition. It allows you to pass a process definition to a another process. It is further explained in Process type.
The TypeName
is the name of a type defined with a type
definition (explained in Type definitions). For example:
type lot = real;
model M():
lot x;
...
end
The lot x
variable declaration (explained in Local variables) uses the type definition of lot
at the first line to define the type of variable x
.
The EnumTypeName
is similar, except it uses an enumeration definition (see Enumeration definitions) as type. For example:
enum FlagColours = {red, white, blue};
model M():
FlagColours x = white;
...
end
The FlagColours x
variable declaration defines that variable x
has the type of the enumeration, and can hold its values.
Elementary types
The elementary types do not depend on other types to define their set of allowed values. They have the following syntax:
As you can see, they are mostly just a single keyword. The ConstantExpression
nodes in the matrix
type line are integer expressions with a fixed (and known) value before execution of the program. More information about the elementary types is provided below.
Boolean type
The bool
keyword denotes the boolean data type. The allowed values are false
and true
. While it is allowed to store boolean values in other data types, their most frequent use is in expressions of statements that decide what to do, for example, the condition in the while
, if
or select statement (see While loop statement, Choice statement and Select statement). Expressions with booleans are explained in Boolean expressions.
Integer type
The int
keyword denotes the integer data type, integer numbers from 2147483647
to -2147483648
(a standard signed 32 bit number). Values outside that range give undefined behavior. Expressions with integers are explained in Integer expressions.
Real type
The real
keyword denotes the real number data type, real numbers between 4.94065645841246544e-324
to 1.79769313486231570e+308
positive or negative (a standard 8 bytes IEEE 754 number). As normal with floating point numbers in computer systems, many values are missing from the above range. Expect rounding errors with each calculation. Expressions with real numbers are explained in Real number expressions.
String type
The string
keyword denotes strings, sequences of characters. It contains all printable ASCII characters U+0020 to U+007E, and 'tab' (U+0009) and 'new line' (U+000A). Expressions with strings are explained in String expressions.
File type
The file
keyword denotes a file at the file system of the computer. It allows reading and writing values of many data types (not all data types can be read or written). Expressions with files are explained in File handle expressions. How to work with files is explained in Input and output.
Instance type
The inst
keyword denotes an instance type, it can store a running process. Its use is to check whether the stored process has ended. The Finish statement gives more details and provides an example.
Timer type
The timer
keyword denotes a count-down timer. Variables of this type measure time that has passed since their initialization. Expressions with timers are given in Timer expressions, a tutorial about using timers can be found in Timers.
Matrix type
The matrix
type takes two constant expressions that define the number of rows and the number of columns of the matrix. The main purpose of the data type is to allow temporary storage of matrices so they can be passed on to other software. The Chi language also has expressions to write literal matrices, see Matrix expression for details.
Void type
The void
type denotes that no data is involved. Values of type void
do not exist. The type is allowed at two places in the Chi specification, namely:
-
As data type of synchronization channels. Further explanation can be found at Communication statements and Channel type.
-
As exit type of Model definitions and Process definitions, to express that it may return an exit value from an Exit statement without arguments.
Container types
The main function of container types is to organize and hold a collection of values of another type (the element type). The syntax diagram of the container types is as follows.
The language has three container types, lists (explained in List type), sets (explained in Set type), and dictionaries (explained in Dictionary type).
List type
The list type has an ordered collection of values from its element type as its value. Duplicate element values are allowed.
The syntax of a list type is given below.
It starts with the keyword list
, optionally followed by a parenthesized (non-negative) integer expression denoting the initial number of element values in the collection, and finally the type of the element values.
The default size of the collection is the value of the integer expression, or 0 if there is no such expression. The value of the elements in the initial list value depends on the type of the elements.
A few examples:
list bool # A list of boolean values, initial value is <bool>[]
list (2) int # A list of integer values, initial value is [0, 0]
For a discussion of operations on values of this type, see List expressions.
Set type
The set type has an unordered collection of values from its element type as its value. Duplicate element values are silently discarded.
The syntax of the set type is given below.
The set type starts with a set
keyword, followed by the type of its elements. Its initial value is the empty set. An example:
set real # A set of real numbers, initial value <real>{}.
For a discussion of operations on values of this type, see Set expressions.
Dictionary type
The dictionary type has an unordered collection of values of its key type, so called keys. The keys are unique in the collection. In addition, the dictionary has a value of its value type associated with each key.
The syntax of a dictionary type is given below.
The syntax starts with a dict
keyword, and the key type and value type between parentheses, separated by a colon. The initial value of a dictionary type is the empty dictionary. An example:
dict (bool : int) # A dictionary with boolean keys, and integer values.
# Initial value <bool:int>{}.
For a discussion of operations on values of this type, see Dictionary expressions.
Tuple type
A tuple contains a fixed number of values of (possibly) different types. It has the following syntax:
A tuple type starts with the keyword tuple
, followed by the list of its fields between parentheses. Each field has a name and a type. Sequences of fields with the same type can share their type description, which reduces the amount of text of the tuple type. Tuple types must have at least two fields.
Examples:
tuple(int a, b) # A tuple containing fields 'a' and 'b', both of type int
tuple(int a; int b) # A tuple containing fields 'a' and 'b', both of type int
tuple(lot x; real start) # A tuple with a 'lot' and a 'real' type.
The first two examples are equivalent, the first form is just a bit shorter in notation. The third example is more common fields of different types that are kept together in the modeled system. Expressions with tuples are discussed in Tuple expression.
Channel type
The channel type defines the direction and the type of values transported. The syntax of the channel type is as follows.
The chan
keyword denotes a channel type is being created. It may be followed by allowed directions of transport, a !
means that sending values is allowed but not for receiving, and a ?
means that receiving values is allowed and sending is not allowed. Finally !?
means both sending and receiving is allowed. The latter is also selected when no direction is specified. The language silently discards allowed directions. A channel usable for both sending and receiving may be used as a channel for sending only (dropping the ability to receive at that point). It does not allow adding directions, a receive-only channel cannot be used for sending. It can also not be used as a channel for sending and receiving, even if then latter is only used for receiving values (that is, sending is never done).
The type of data that is transported with a communication is given by the Type
block. Signalling channels (that only synchronize without transporting data) are indicated by the void
keyword. The only expressions available for channels are the equality tests, and a function to create new channels, see Channel expressions for details.
Distribution type
The distribution type represents a stochastic distribution. It has the following syntax:
A stochastic distribution allows modeling of random behavior, but with a known chance distribution. The Type
block in the DistributionType
diagram defines the type of values drawn. For a discussion of expressions for the distribution type, see Distribution expressions.
Function type
The function type can hold a function. Its syntax is as follows.
A function type starts with the keyword func
followed by the return type of the function and the type of the formal parameters. The purpose of the function type is to pass functions to processes or other functions, for example, the predicate function in sort
and insert
, see List functions.
Process type
The process type is similar to the function type (discussed in Function type), except this type can hold a process definition. It has the following syntax:
The type starts with the keyword proc
followed by the formal parameters of the process definition to store between parentheses. Expressions with process types are explained in Process expressions.