- 6 -
5 :: fromA?data(d,b) -> toB!data(d,b)
6 :: fromB?control(b) -> toA!control(b)
7 od
8 }
We have specified a behavior for the lower protocol in a proctype definition. The process type is named
lower and has four parameters, one for each message channel that it must access (line 1). The body of the
process definition is enclosed in curly braces. It starts with the declaration of two internal variables on line
2. One variable is of type byte and one is of type bit. We have now seen four different types of
PROMELA objects:
proctype, chan, bit, and byte
There are only two other types (both data types, i.e., for variables)
short, and int.
A object of type bit is a variable that can hold a single bit of information. An object of type byte is a
variable with a type that is equivalent to a C unsigned char. The precise range of such a variable is
machine dependent. On most machines it suffices to store 8 bits of information. Objects of types short
and int are signed variables that are mapped onto the same data types in C. On most machines again, a
short stores 16 bits of information, and an int stores 32 bits.
The behavior is specified as a single loop (lines 4-7). The syntax is derived from Dijkstra’s guarded com-
mand language [Dijkstra ’75], and Hoare’s language CSP [Hoare ’78], but the semantics are different (cf.
Appendix A). A do-loop, for instance, is repeated until it is explicitly terminated by the execution of a
break statement, or a goto jump.
The loop on lines 4-7 is not broken, and therefore will not terminate. There are two options in the loop,
each starting with the :: flag, and each with two statements. Each time though the cycle of the loop, one of
the two options is selected for execution, using the rules stated below. The token -> is a statement separa-
tor. In fact, PROMELA allows two statement separators, the traditional semicolon, and the arrow. They are
semantically completely equivalent.
The first statement in each option is called a guard. The option can only be selected if the guard is exe-
cutable. The guard of the first option, on line 5, specifies the reception of a message data(d,b) from
channel fromA.
fromA?data(d,b)
This receive operation is executable if and only if a message of the required type is queued in channel
fromA. Channels behave as FIFO queues. A message of type data must therefore be at the head of that
queue. The receive statement is unexecutable when, for instance, a message of type control is at the head
of channel fromA. The number of parameters specified in the receive operation must always match the
number specified in the corresponding channel declaration.
The second statement in both options is a send operation. For the first option, for instance,
toB!data(d,b)
specifies the sending of message data(d,b) to channel toB. By default, the send action is only exe-
cutable if the target channel is not full. This means that in validation runs it is considered a design error if
message queues can be made to overflow. (The user can override the default though and stipulate that mes-
sages sent to full queues must be discarded.) ‘‘Executability’’ is a central concept in PROMELA, and the
main tool for formalizing process synchronization in a validation model.
Executability in PROMELA
Every statement in PROMELA is either executable or non-executable. The semantics of PROMELA (summa-
rized in Appendix A) specify the rules of executability for every type of statement. Assignment statements,
for instance, are always executable. Boolean conditions are executable if and only if they are true. Any
statement that is non-executable can block the executing process. In the loop of the example above, the
state of the channels determines which of the two guards will be executable and thus selectable by the lower
layer process. If no guard is executable, the process blocks. If more than one guard is executable, one of