TLDR:
break: an (always executable) instruction which makes the execution jump at the end of the innermost loop in which it is contained. This type of instruction is pretty much universal for pretty much any programming language.
skip: an empty (always executable) instruction that has no effect. There are plenty of no-op examples from other languages, like pass
in python
, ;
(and others) in C
, jQuery.noop()
in jQuery
, etc.
active proctype A(){
do
:: !x -> break
:: else -> skip
od
… //more code
}
In this instance, as soon as x
becomes false then break
forces the loop to terminate, whereas skip
is just an empty instruction to explicitly represent the fact that in the other case the loop keeps doing nothing.
From the docs of break
NAME
break - jump to the end of the innermost do loop.
[...]
EXAMPLES
L1: do
:: t1 -> t2
:: t3 -> break
:: break
od;
L2: ...
In this example, control reaches the label L1 immediately after statement t2 is executed. Control can also reach label L2 immediately after statement t3 is executed, and optionally, in one execution step, control can also move from label L1 to label L2.
From the docs of skip
NAME
skip - shorthand for a dummy, nil statement.
[...]
EXAMPLES
proctype A()
{
L0: if
:: cond1 -> goto L1 /* jump to end */
:: else -> skip /* skip redundant */
fi;
...
L1: skip
}
The skip statement that follows label L1 is required in this example. The use of the skip statement following the else guard in the selection structure above is redundant. The above selection can be written more tersely as:
L0: if
:: cond1 -> goto L1
:: else
fi;
Because Promela is an asynchronous language, the skip is never needed, nor effective, to introduce delay in process executions. In Promela, by definition, there can always be an arbitrary, and unknowable, delay between any two subsequent statement executions in a proctype body. This semantics correspond to the golden rule of concurrent systems design that forbids assumptions about the relative execution speed of asynchronous processes in a concurrent system.