|
What's New in Spin Versions 2.0 and 3.0(Updated for Version 3.0, July 1997)Spin is a general verification tool for proving correctness properties of distributed or concurrent systems. The systems can interact through shared memory, through rendezvous operations, or through buffered message exchanges. The coordination problems that these interactions may create can effectively be debugged with the Spin system. Once a correct design of the system has been obtained, a rigorous proof of its correctness can be provided.Spin, written in 1989, is based on the paradigm of on-the-fly model checking. Spin was first released through netlib in January 1991. Version 2.0 followed in January 1995, and Version 3.0 in July 1997. This note gives an overview of the changes that have been made in Spin since the first release, in the modeling language Promela, and in Spin's graphical user interface Xspin. Changes that are specific to the most recent version are collected in Section 4. A few other documents are useful to get started with the language Promela, and the use of Spin and Xspin:
0. Some ContextThe earliest work towards the construction of an automated verifier protocol models was done in the mid seventies. The principle of reachability analysis, and the notion that automated tools could exploit it, was well-established by this time. Among the first to built a fully automated tool was Jan Hajek at the Technical University in Eindhoven in The Netherlands [Haj78]. Between 1976 and 1978 Hajek's system Approver successfully uncovered bugs in a series of published designs for communications protocols. Hajek, however, never revealed the algorithms, and or heuristics, on which his system was based. At approximately the same time, Colin West at the IBM research lab in R uumluschlikon, Switzerland, started work on the implementation of a tool for Pitro Zafiropulo's duologue matrix analysis technique. This work quickly lead West to develop his own variant of a verification system, e.g. [W78]. Work leading to the Spin verifier started in 1980. Our verifier Pan found its first bug in a Bell Labs data-switch control protocol on 21 November 1980. Pan was, a general one-pass, on-the-fly, verification system for safety properties. Pan [H81] was succeeded in 1982 by Pandora [H83], in 1983 by Trace [H85], in 1987 by Supertrace [H88,H95], in 1988 by SdlValid [H89], and finally in 1989 by Spin [H91,H97b]. All systems were based on a systematic application of on-the-fly verification. In Spin the implementation of on-the-fly techniques was merely extended to cover omega-regular properties, which includes LTL properties as a subclass. Elsewhere, work began around 1981 on the direct construction of a different type of a verification system, called a logic model checker. Ed Clark at Carnegie Mellon University and his students started work on the CMU model checker, e.g. [ClEm81], and independently Joseph Sifakis and his students at Grenoble University in France started work on the Cesar model checker, e.g. [Qu82]. On-The-Fly Model CheckingThe terms on-the-fly verification and logic model checking are no longer sharply distinguished, since the tools have acquired largely the same basic capabilities. Still there are significant differences in the algorithms used in these two types of systems. A traditional logic model checker works with a two-pass verification procedure. In a first phase the basic behavior of the system being studied is explored and an abstract representation of that behavior, called a Kripke structure, is created. In a second phase this abstract representation is used to prove or disprove the correctness requirements. An on-the-fly verifier, in contrast, works with a single-pass verification procedure. Its aim is to store in memory as little information as is necessary for the correct completion of the verification process itself, and to perform the actual verification of the correctness requirements during the exploration of the smallest possible fragment of the system behavior as is possible, for the given correctness requirements.The advantage of an on-the-fly system is often that it can handle larger problem sizes, measured in terms of the basic time and space requirements that are minimally needed to solve the problem, and generally can discover errors in a design faster than a conventional model checker. The most significant extension of Spin version 2.0 was the adoption of the partial order reduction technique described in [P94] and [HP94]. In version 2.7 we added direct support for LTL model checking [GPVW95]. Version 2.8 made Spin portable to any system with a standard C compiler (including PC systems running Windows95). Spin version 3.0 adds an autamata based compression method, event traces, and a Postscript output option for message sequence charts, and compatibility with WindowsNT systems. The design of the algorithms used in the newer versions of Spin is documented in more detail in [H98]. Section 1 of this memo describes the changes that were made into Spin itself, starting with Version 2.0. Section 2 describes the changes made in the language Promela, and Section 3 describes changes in the graphical interface Xspin. Section 4 summarizes the changes that are specific to Version 3.0. Section 5 concludes this report. 1. Changes in SpinStarting with Version 2.0, the Spin sources, as well as all programs generated by Spin, conform fully to the ANSI C standard [KR88], and are, in as much as possible, POSIX compliant. Where an ANSI C standard compiler was recommended with previous versions of Spin, it is required with this version. The generally available Gnu C compiler gcc has the desired properties to compile all sources. Starting with Version 2.8, the Spin sources can also be compiled with gcc on standard PC systems. The graphical user interface Xspin can be setup to work properly on any Windows95 PC. Spin relies on the standard C preprocessor to be available in /lib/cpp on Unix systems, or as a plain command cpp on PCs. If the name or location of the preprocessor is different, you can either hardcode the new name by editing main.c, or pass Spin the name of the preprocessor from the command-line, using the -P option (new in Version 3.0, see Section 4). Minor system dependencies do persist. The hashing algorithms used in Spin, for instance, assume a 32-bit architecture. An adjustment should be made for machines that differ from this default. The standard options accepted by Spin are printed with a -- option: $ spin -- -a generate a verifier in pan.c 3 -b don't execute printfs in simulation 3 -c columnated -s -r simulation output 3 -Dxxx pass -Dxxx to the preprocessor 3 -Exxx pass xxx to the preprocessor 2 -d produce symbol-table information 2 -f "..formula.." translate LTL into never claim 3 -F file like -f, but read LTL formula from file -g print all global variables 2 -i interactive (random simulation) 2 -jN skip the first N steps in simulation trail -l print all local variables 3 -M print msc-flow in Postscript -m lose msgs sent to full queues -nN seed for random nr generator 3 -Pxxx use xxx as the preprocessor -p print all statements -r print receive events -s print send events -v verbose, more warnings 3 -t[N] follow [Nth] simulation trail 2,3 -[XY] reserved for use by xspin interface 2 -V print version number and exitFor those options that were not in the first release of Spin, a number in the left margin indicates the version number in which it was added. Some options, such as -b, -i and -j, will need little further explanation. The others are discussed in this report. Option -d (symbol table information) is discussed in Section 1.2. Option -f (LTL conversion) is briefly discussed at the end of Section 1.1. The extension of option -t is discussed in Section 1.6.6. Options -M and -P are discussed in Section 4. We first summarize the main changes in the Spin software since the book version [H91], focusing on new functionality. 1.1 Partial-Order ReductionSpin versions 2 and 3 includes the partial order reduction method that is outlined in [P94] and [HP94]. The reduction can be proven to preserve all safety and liveness properties during the verification [PC95], and is therefore generally applicable. Given a Promela validation model in a file bug_me, verifiers can be generated and compiled with or without the reduction algorithms enabled, as follows: recommended: $ spin -a bug_me # produce the verifier $ cc -o rfull pan.c # default, reduced exhaustive $ cc -DBITSTATE -o rbit pan.c # reduced supertrace not recommended: $ cc -DNOREDUCE -o full pan.c # conventional exhaustive search $ cc -DNOREDUCE -DBITSTATE -o bit pan.c # supertrace searchPartial order reduction is fully compatible with the bitstate searching (i.e., supertrace verification). Starting with version 2.8, the partial order reduction is the default compilation mode (earlier versions used exhaustive non-reduced search as their default, requiring -DREDUCE to enable the reductions). In most cases the reduction will shrink the memory requirements and the time requirements each by an order of magnitude. The reduction algorithm as implemented [HP94] has only negligeable overhead. One strict requirement for the correctness of the partial order reduction option applies to the use of Promela never claims, for instance for proving LTL properties. For the reduction to preserve liveness properties the never claims must be closed under stuttering. In other words, the property expressed by the never claim may not depend on the number of program steps that a property remains true or false. In practice this is not a serious restriction. For instance, all properties that can be expressed in next-time free linear time temporal logic are closed under stuttering. All versions of Spin from 2.7 forward include a translation option (-f) that allows conversion from standard LTL syntax into never claim automata, with the guarantee that the automata thus produced are closed under stuttering. For instance, $ spin -f "[] p"generates the never claim for expressing the LTL property p is invariantly true. This conversion option is most easily used with help from Xspin. To take full advantage of the partial order reduction, Promela supports two types of assertions, and four predefined functions to poll the status of message channels without introducing new dependencies that would limit the effect of the partial order reduction. They are: assertions: xr, xs, functions: nfull, nempty, empty, full.These primitives are discussed in more detail in Section 2. Examples of their use are included in the Test directory of the Spin distribution. 1.2 Symbol Table InformationIn some cases it can be useful to have a machine readable version of the symbol table information that is collected by Spin while parsing a Promela model. There is a new Spin option to produce this information: $ spin -d bug_meThe output produces for each Promela object its: type, name and number of elements (if declared as an array), it's initial value (if a data object) or size (if a message channel), its scope (global or local), whether it is declared as a variable or as a parameter, and it's subtypes (if declared as a message channel). For structure variables, the 3rd field defines the name of the structure declaration that contains the variable. The output is not meant for a human reader, but with its help it can be easier to built translators that convert Promela into other verification formats. 1.3 Complexity ProfilingSpin versions 2 and 3 support a compile-time flag -DPEG that causes some additional statistics to be gathered during the normal verification process. The verifier will count for each Promela statement (i.e., each basic type of transition in the reachability graph) the number of times that it is traversed during the verification process. The counts are printed at the end of the verification run. $ spin -a bug_me $ cc -DPEG ...other_directives... -o pan pan.cThe profiling option is compatible with all other search modes supported by Spin (including partial order reduction, and bitstate searching). The peg-counts can be used to identify the hot spots in a Promela validation model, i.e., those places in the model that contribute the most to the size of the reachability graph. 1.4 Verbose VerificationIn some cases it will be necessary to study what the verifier does at each step during the verification process in more detail. Spin supports two compile-time options -DVERBOSE, and the terser CHECK, for this purpose. The additional information is printed to the standard output during the verification process. $ spin -a bug_me $ cc -DCHECK -o pan pan.c # terse debugging info or $ cc -DVERBOSE -o pan pan.c # more verboseThese options work in all search modes. Where necessary, the precise state assignments that the verifier will refer to can be found with the runtime option -d (which does not require verbose compilation, but is available with all versions of the executable verifier): $ pan -dThe state machine format includes all information necessary also to understand the working of the partial order reduction algorithm. Two types of additional state labels are used for this purpose: L identifies the safe and conditionally safe transitions, and G identifies all other transitions [HP94]. 1.5 New Runtime OptionsAll the runtime options that existed in the earlier releases of Spin, e.g., [H91], have been preserved. The four main runtime options from the first release of Spin were: $ pan -- -a find acceptance cycles -cN stop at Nth error (default=1) -l find non-progress cycles (disabled, requires -DNP) -mN max search depth N (default=10k) -wN use hash table of 2^N entries (default=2^18) ...otherAcceptance cycle detection (runtime option -a) is enabled by default. The verifier must be compiled with the directive -DNP to replace acceptance cycle detection with non-progress cycle detection: $ cc -DNP -o pan pan.c $ pan -l(The algorithms for acceptance cycle detection and non-progress cycle detection were unified in version 2.9, and only one or the other can be enabled.) Two new runtime options were discussed in the previous subsection: -d print state tables and stop Section 1.3 -d -d print un-optimized state tablesThe following additional runtime options are supported by all verifiers that are generated by the more recent versions of Spin: -V spin version that generated this source Section 1.5.1 -a find acceptance cycles Section 1.5.2 -e create error trails for all errors found Section 1.6.6 -f enforce weak fairness constraint Section 1.5.3 -hN choose alternate hash-function 1..32 Section 1.5.5 -i search for the shortest path to an error Section 1.5.7 -I like -i, but approximate and faster Section 1.5.7 -n suppresses reachability report Section 1.5.4 -q require empty channels in valid endstates Section 1.5.8 -s single-bit forward hashing Section 1.5.5 -b single-bit backward hashing Section 1.5.5 -RN N repeated verification runs Section 1.5.6We summarize the usage of many of these options below. 1.5.1 Runtime Option -VThis option is understood both by Spin itself (starting with Spin version 1.5.0 of January 1993) and by all verifiers generated by Spin. Either the version number of Spin itself or the number of the version of Spin that generated the current program is printed and the program then exits. Examples: $ spin -V Spin Version 2.9.0 -- 10 June 1996 $ spin -a bug_me $ cc -o pan pan.c $ pan -V Generated by Spin Version 2.9.0 -- 10 June 1996 1.5.2 Runtime Option -a and -lStarting with Spin version 1.5.0, the search for acceptance cycles no longer happens by default when acceptance labels are specified. For consistency, the searches for non-progress cycles and for acceptance cycles are initiated only when the corresponding runtime option is specified. By default only a search for safety properties is performed (i.e., assertion violations, invalid endstates, unspecified receptions, unreachable code segments, etc.). Examples: $ spin -a bug_me $ cc -o pan pan.c $ pan # default search for safety properties ... $ pan -a # search for acceptance cycles ... $ cc -DNP -o pan pan.c # compile for non-progress cycles $ pan -l # search for non-progress cycles ...A non-progress cycle is an infinite behavior that does not pass through any state that is labeled with a progress-label. The cycle detection algorithms to support the -l and -a flags have been merged in the new version of Spin, to conform to the algorithm (and its correctness proof) from [CVWY92]. There is a small amount of overhead associated with the liveness options -l and -a. To avoid this overhead when only safety properties are being checked, the verifier can also be compiled as follows: $ cc -DSAFETY -o pan pan.c # with or without -DBITSTATE etc $ panThis can reduce time and memory requirements by roughly 10%. 1.5.3 Runtime Option -fStarting with Spin version 1.5.0, an option has been supported in the verifiers generated by Spin to enforce a weak-fairness constraint on all cycle analyses [GH93]. The original fairness algorithm from version 1.5 was based on an efficient, but flawed heuristic. Spin version 2 contains a new implementation, based on the more reliable construction from Choueka [C74], which is also mentioned in [CVWY92]. The worst case additional complexity contributed by this construction is a multiplication of the CPU time requirements by 2 x (N+1), where N is the number of processes in the Promela model. The memory requirements remain largely unaffected, by virtue of the storage technique that is explained in [GH93]. Because the fairness option modifies the cycle detection algorithm, and has no relevance to safety properties, it is an error to specify -f without -a or -l. 1.5.4 Runtime Option -nBy default, the verifiers produced by Spin will report on unreachable code in a Promela model at the end of a successfully completed (i.e., untruncated) verification run. The report can be suppressed with runtime option -n. Example: $ spin -a bug_me $ cc -o pan pan.c $ pan -nThe option is compatible with all other runtime options. 1.5.5 Runtime Options -s, -b, and -hBy default, the verifiers produced by Spin use a fixed double-bit hashing method when they are compiled for a supertrace search: $ spin -a bug_me $ cc -DBITSTATE -o pan pan.c $ pan ...In special cases, which are explained in more detail in [H95], the use of a single-bit hashing technique can be advantageous. The two hash-functions used together in the double-bit hashing technique can be separated with the options -s and -b. The first option corresponds to the forward hash; the latter corresponds to the reverse hash (applying the same function over the reversed state-vector. It can be shown that the combined coverage of two separate runs with the two single-bit hash functions gives equal or better coverage than a single run with double-bit hashing, assuming all other parameters remain unchanged. $ pan -s ... $ pan -b ...The runtime option -hN can be used to pick one of 32 predefined hash-functions; the default being -h0. A disadvantage is that the reachability and coverage reports generated by the single run with the default double-bit hashing is easier to interpret than those from two or more subsequent runs with single-bit hashing. See [H95] for more details on the rationale for this option. 1.5.6 Runtime Option -RNAs also detailed in [H95], the coverage of a supertrace search can be increased by repeating the runs several times, each time with independent hash functions. Spin version 2 supports up to 32 different predefined polynomials, each of which can be used to form two independent hash functions (forward and backward). The runtime option -RN allows the user to specify that a supertrace run is to be repeated N times, each time with a different (pair of) hash functions. Example: $ spin -a bug_me $ cc -DBITSTATE -o pan pan.c $ pan -R16 # performs 16 independent supertrace runs ...or, for maximum coverage (this will be overkill in all but very few applications): $ pan -R32 -s ... $ pan -R32 -b ...See [H95] for more details on the rationale for this option, and the methodology to predict the actual coverage of a series of verification runs with this method. 1.5.7 Runtime Options -i and -IIf the verifier is compiled with the optional extra directive -DREACH and -DNOREDUCE (-DREACH has no effect in BITSTATE mode), the runtime option -i can be used to search systematically for the shortest path to an error. The search starts as before, but when an error is found, the search depth (-m) is now automatically truncated to the length of that error sequence, so that only shorter sequences can be found from this point forward. The last sequence generated will be the shortest one possible. Runtime option -I is more optimistic: it halves the search depth whenever an error is found, to try to generate one that is at most half the length of the last generated one. If no errors are found at all, the use of -i or -I has no effect on the coverage of search performed. The effect of using -DREACH itself, however, can be an increase in the memory and time requirements. In many cases the increase is small, but be warned, in the worst case the increase caused by -DREACH can be exponential in the size of the statespace. 1.5.8 Runtime Option -qRuntime option -q enforces stricter conformance to what is promised in the Spin book from 1991 [H91]. By default, the verifiers produced by Spin require each process to have either terminated or be in a state labeled with an endstate-label, whenever the system as a whole terminates. The book says that for such a state to be valid all channels must also be empty. Option -q enforces this stricter check. 1.6 Internal Changes (skip on first reading)A series of other changes in Spin's implementation sets it apart from earlier releases, although they may not be directly visible to the user. The most important changes are briefly discussed. 1.6.1 Byte MaskingThe state-vector is now compressed in exhaustive (i.e., non supertrace) verifications to reduce the memory requirements in return for a small additional runtime expense. The compression also has the beneficial, though unintended, side-effect that it reduces the number of hash collisions. All rendez-vous channels (i.e., zero-capacity message channels) now no longer take up space in the state vector. This is possible because rendez-vous handshakes are defined to happen atomically. There is never a system state in which a message can be found inside the message channel, in the midpoint of a rendez-vous handshake. This property, that follows immediately from the semantics of the rendez-vous, also explains that any attempt to poll the contents of a rendez-vous channel will fail. (The addition of event-trace definitions in Version 3.0 addresses this problem. See section 4.) For example, in: chan q = [0] of { mtype, byte, byte }; if :: q?[mesg(a,b)] /* this is always false */ ... fithe condition cannot ever become true because it attempts to poll the intermediate state of the rendez-vous handshake. Spin version 2 will warn the user if it finds the above construction. (See Section 2.1.8 for an alternative method to model conditional rendez-vous operations. See also the description of the event trace option in the section on Version 3.0) To reduce memory usage, in Spin version 2 and later the data structures for all rendez-vous channels are omitted from the state vectors before they are stored. There is no detectable change in the functionality of the verification process. The default byte masking compression can be disabled (e.g., for ebugging purposes, when safety properties are checked) by compiling the verifier with the flag -DNOCOMP. Independently, more agressive compression algorithms can also be invoked, by compiling the pan.c source with the directive -DCOLLAPSE, or -DHC. For obvious reasons -DNOCOMP cannot be combined with -DCOLLAPSE or -DHC. The COLLAPSE compression method is explained more fully in [H97a]. The HC compression method was added in version 3.2.1, and is based on Pierre Wolper's hash-compact algorithm, that achieves remarkably good compression at relatively low risk of omission. In Spin version 3 and later, another, still more aggressive state-space compression algorithm can be invoked by compiling with -DMA=N, as explained in more detail in Section 4. 1.6.2 Compliance with Automata TheoryIn previous versions of Spin the synchronous product of the system state space with the B\üchi automaton that corresponds to a never claim was defined such that no proposition could be checked on the initial system state (the root of the reachability tree). In this one instance, though harmless, the behavior of Spin deviated from the formal theoretical framework on which it is founded. This is fixed in version 2.0 to make Spin completely conform to the theory.
If a verification against a never claim is performed, the
first step taken in the verification process is to perform an action
(i.e., evaluate a proposition) from the initial state of the never
claim.
The immediately following step is from one of the asynchronous processes
that make up the rest of the model (i.e., the `program').
A system state transition in this verification process always consists of two
synchronously linked steps: one step of the never claim followed
by one step of the program.
(In previous versions of Spin the two steps were reversed.)
States are only stored after such a state transition pair is completed.
In some cases, a never that worked correctly with a previous
version of Spin may need an extra initial skip statement
(i.e., true proposition) to perform correctly with Spin version 2.
No other changes should be necessary.
In pervious versions of Spin, in a check for non-progress cycles (runtime option -l) also terminating sequences that did not pass through at least one progress label would be reported as errors. This aberration has been removed from version 2. 1.6.4 New Semantics of TimeoutIn previous versions of Spin, if the system reached a valid end-state (e.g., a state in which all processes have stopped at a state that is marked with an end-label), no timeout options would be considered. This lead to unexpected behavior, for instance in cases where the initial system state was defined to be a valid end-state and all system behavior was meant to be triggered by an initial timeout. In Spin version 2 this will work correctly. The possibility of a timeout is now independent of the validity of the current system state as an end-state, as also required by Promela semantics. 1.6.5 New Randomizer for SimulationsThe behavior of the default random number generators on some systems left much to be desired. The new version of Spin contains it's own random number generator, based on [PM88]. The specific way in which process actions are randomized within non-deterministic selections and in the process scheduling algorithm for the random simulations has also been improved. 1.6.6 More Robust Guided SimulationThe format of an error trail generated by the verifiers produced by earlier versions of Spin was defined in terms of states. The guided simulator, when trying to follow such a trail, could get confused, and declare to have `lost the trail' in cases where there would be more than one possible path from one state of the trail to the next. In the new version of Spin this is avoided by defining the trails in terms of the precise transitions to be executed along the trail. Spin version 2 also creates a separate trail file for each specification it analyzes, rather than using a single fixed name pan.trail. In cases where more than one, numbered, trail file exists, (these can be generated with the runtime option -e), the user can select the trail file to be used in a guided simulation by adding the trail-file sequence number to the -t flag, e.g. as in $ spin -t4 spec 1.6.7 Improved Error ReportingThe syntax requirements of Promela have been relaxed a little, to avoid pedantic error reports about (especially) missing, or misplaced semi-colons. Some extra type checking is performed, and the error reports issued should be easier to interpret. Starting with Version 3.0 also, Spin will mildly complain when data-types are used that needleslly increase the memory requirements of a verification run, e.g., when integer variables are used for booleans. 2. Changes in Promela2.1 New Language ConstructsNine new language constructs were added to Promela. In no particular order, the extensions are summarized below. 2.1.1 ElseThe most frequently asked for language construct is now supported. Syntax: elseSemantics: An else statement is executable if and only if no alternative statement within the same process is executable. The else statement can be used as the guard (i.e., the first statement) of an option sequence inside selection or iteration constructs. It is a syntax error to specify more than one else statement within a single selection or iteration construct. Example: if :: a > b -> ... :: a == b -> ... :: else -> ... fiAs an aside:now that else has been defined, the Promela timeout statement can be understood as a system-wide else (i.e., the timeout is executable only when no alternative statement within the system is executable). 2.1.2 UnlessA concept based on the comparable construct watching from Esterel [BCG86], [Hal93], and analogous concepts in languages such as Statecharts [Har87]. Syntax: B unless Cwhere B and C are arbitrary Promela program fragments. If either of these fragments contains more than one statement, they must be grouped by enclosing them in curly braces. For instance: { B1; B2; B3 } unless { C1; C2 }Semantics: Execution of the unless statement begins with the execution of fragment B (B1). Before each step in B, including the first one, the executability of the fragment C (C1) is checked, using the normal Promela semantics of executability. Execution of statements from B proceeds only while the fragment C remains unexecutable. The first instance during the execution of B that an initial statement from C (C1) is found to be executable, control changes to the start of C (C1), and execution continues as defined for C. Statement executions in Promela remain indivisible, so control can only change from inside B to the start of C in between individual statement executions. In the fragment C does not become executable during the execution of B, it is skipped when B terminates. Example: A; do :: b1 -> B1 :: b2 -> B2 ... od unless { c -> C }; DIn the example, condition c acts as a watchdog on the iteration that precedes it. Note that this is not necessarily equivalent to the construct: A; do :: b1 -> B1 :: b2 -> B2 ... :: c -> break od; C; Dfrom standard Promela, if B1 or B2 are non-empty. In the first version of the example, execution of the iteration can be interrupted at any point inside each option sequence. In the second version, execution can only be interrupted at the start of the option sequences. The unless operator can be used in hierarchical proofs, in refinement proofs, and as a general escape mechanism. 2.1.3 d_stepd_step is a deterministic alternative to atomic, that can be supported more efficiently in the verifiers. For long code segments with deterministic local computations, the use of d_step instead of atomic can reduce the time requirements of a verification. Syntax: d_step { ... }Semantics: Equal to atomic sequences, with these two differences: a d_step sequence must be completely deterministic, and it may not contain goto jumps that have targets outside the sequence, nor labels that can be jumped to from outside the sequence. Example: d_step { /* initialize an array */ i = 0; do :: i < N -> buf[i] = i; i++ :: i >= N -> break od; skip /* skip is needed here */ }The execution of this sequence will take one single step in the verifiers produced by Spin. The d_step construct can be seen as a mechanism to define an indivisible statement in the language at the user-level, and thus to extend the semantics of Promela itself. 2.1.4 Sorted SendIn addition to the standard synchronous and asynchronous message passing primitives there are now two new types of operations on message channels: sorted send and random receive. We first discuss the sorted send operation. Syntax: qname!!msg,...Semantics: The sorted send operation will insert the message into the channel immediately ahead of the oldest message in the channel that succeeds it in numerical order (instead of in FIFO order). To determine the numerical order, all message fields are significant. Sorted send operations and the default FIFO send operations may be mixed. The sorted send operation can be exploited by, for instance, listing an appropriate message field (e.g., a sequence number) as the first field of each message. Much administrative work with reshuffling messages to place them in some other order than the default order of arrival can thus be avoided. 2.1.5 Random ReceiveThe random receive operation is the logical counterpart of the sorted send operation. Syntax: qname??msg,...Semantics: A random receive operation is executable if it is executable for any message that is currently buffered in a message channel (instead of only for the oldest message in the channel). FIFO and sorted receive operations may be mixed, and can be combined with both FIFO send and sorted send operations. Applying sorted send and random receives together can be used to implement channels that buffer messages as sets. By storing the sets in numerical order, a significant reduction in the number of reachable states of a verification model can be obtained. 2.1.6 Hidden DataSpin version 2 supports a new qualifier for data objects: hidden. Syntax: hidden type_name variable_name, ...Semantics: The value stored in a hidden variable is always undefined. A hidden data object will not be stored inside the state vector, and is therefore not part of the stored states. This type of qualification is sometimes useful when a `scratch' variable is needed, e.g. a write-only variable, that never carries meaningful values. Example: chan q = [8] of { byte }; hidden byte a; ... do :: q?a /* flush the channel */ :: empty(q) -> break odThere is also a predefined data-object of type hidden (i.e., it need not be, or rather: it may not be, declared), called: _ (i.e., underscore). It is a write-only variable, that can be used to store scratch values. A related new keyword from Version 3.0 is show. This keyword can also be prefixed to variable declarations, just like hidden, but it does not affect the semantics of of the model. It affects only the way in which data can be displayed in message sequence charts through Xspin or through Spin option -M (see Section 4). 2.1.7 StructuresSpin versions 2 and later support user-defined data types in the form of named structures. A Promela typedef definition can be used to introduce a new name for a list of data objects of predefined, or earlier defined, types. The new typename can then be used to declare and instantiate new data objects, which can be used in any context in the obvious ways. Example: typedef Field { short f; byte g }; typedef Msg { byte a[3]; int fld1; Field fld2; chan p[3]; bit b }; byte p; Msg foo; chan q = [2] of { byte, Msg }; init { q!p,foo; q?p,foo } 2.1.8 Conditional ExpressionsConditional expressions, analogous to the C-syntax expr?expr:expr, are now supported. To avoid parsing conflicts, though, the syntax is different from C. Syntax: (expr1 -> expr2 : expr3)where the braces around the conditional expression are always required.
Semantics:
Example: chan q[3] = [0] of { mtype }; sender: q[cond2 -> 1 : 2]!msg -> ... receiver: q[cond1 -> 1 : 0]?msg -> ...The example shows a simple way to implement conditional rendez-vous, as for instance defined in ADA. Two dummy rendez-vous channels (q[0] and q[2]) are used to deflect handshake attempts that should fail. The handshake can only successfully complete (on q[1]) if both cond1 at the receiver side and cond2 at the sender side hold. 2.1.9 Active ProctypesIn earlier versions of Spin there was one predefined initial process, named init. The init process was the only process that could be active in the initial system state of a verification. In Spin version 2 there is a new keyword active that can be prefixed to any proctype definition. If the keyword is present, an instance of that proctype will be active in the initial system state. Multiple instantiations of the same proctype can be specified with an optional array suffix of the new keyword (separated from it by white space). Example: active proctype A() { ... } active [4] proctype B() { ... }Processes instantiated through the active prefix in the initial system state cannot be passed arguments. Nonetheless, it is legal to declare a list of formal parameters for such processes to allow for argument passing in additional instantiations with run statements. In this case, in all copies of the processes instantiated through the active prefix, the formal parameters are initialized to zero. A process can find out what its instantiation number is through the new predefined local variable _pid (see also Section 2.2.2). As before, process instantiation numbers begin at 1 for the first process run, and count up. At any point in time, only the process with the highest instantiation number can die (i.e., the most recently created child). Processes instantiation numbers can be recycled by the verifier. A never claim, if defined, always carries a zero or negative instantiation number. 2.2 New Predefined Variables and Functions2.2.1 Support for Partial Order ReductionsPartial order reductions can only be applied to asynchronous send and receive operations if the processes that use these operations follow specific rules of usage, that must be asserted with the new keywords xr and xs. For example, the assertions xr q1; xs q2;claim that process that executes these assertions is the only process that will receive messages from channel q1, and the only process that will send messages to channel q2. If an exclusive usage assertion turns out to be invalid, Spin will report this during verifications as the violation of a formal correctness requirement. The partial order reduction algorithm can take advantage of the presence of the assertions by optimizing the reduction algorithm (nonetheless without losing its ability to detect and report all cases in which an assertion of this type could be violated). See [HP94] for more details. Four additional functions on channels are predefined. They are given with their equivalents in terms of the existing function len, assuming that the size of the channel inspected here is QSZ (as defined by the user). nfull(q) len(q) < QSZ nempty(q) len(q) > 0 full(q) len(q) == QSZ empty(q) len(q) == 0Using the functions nempty(q) and nfull(q) instead of the alternatives above can be exploited by the partial order reduction techniques. The two additional functions empty(q) and full(q) have no similar benefit, but are included for symmetry. It causes a syntax error to circumvent the rules by attempting a construction such as !empty(q). For the partial order reductions, any other test on the contents of a channel, such as q?[msg] or len(q), counts as both a read and a write access of the channel q, which may violate an earlier xr or xs assertion.
Restrictions:
2.2.2 Variables and FunctionsThere are two additional predefined variables (_pid and _last), and two more predefined functions (enabled() and pc_value()). _pid is a predefined local variable that holds the instantiation number of a process. Example: active [3] proctype A() { printf("hi, i am process number: %d\n", _pid) }_last is a predefined global variable that holds the instantiation number of the process that performed the last step in the current execution sequence. It is not part of the state vector unless it is explicitly used in a specification. The additional state information present in this variable will cause an increase of the number of reachable states. The initial value of _last is zero. Example: never { /* claim that it is not possible for process 1 * to execute precisely every other step forever */ accept: do :: _last != 1 -> _last == 1 od }enabled(pid) is a predefined boolean function that returns true if the process with instantiation number pid can perform an executable operation in its current state. The use of enabled(pid) is restricted to never claims (to avoid the obvious potential causal loops), and it is further restricted to models that do not contain synchronous rendez-vous operations. Example: never { /* claim that it is not possible for process 1 * to remain enabled without ever executing */ accept: do :: _last != 1 && enabled(1) od }pc_value(pid) is a predefined function that returns the current state number of the process with instantiation number pid. The correspondence between the state numbers reported by pc_value and statements or line numbers in the Promela source can be checked with runtime option -d, as explained in Section 1.3. The use of this function is also restricted to never claims. Example: never { do :: pc_value(1) <= pc_value(2) && pc_value(2) <= pc_value(3) && pc_value(3) <= pc_value(4) && pc_value(4) <= pc_value(5) od }The claim above is an attempt to enforce a symmetry reduction among five processes. This particular attempt is flawed in that it does not preserve safety and liveness properties. (There are alternative ways of accomplishing such reductions, but as it stands we do not know if they can be enforced in a similar way with never claims.) 2.3 Changes in SemanticsIn Spin Version 2.0, two small changes were made in the semantics of Promela programs. (Version 3.0 contains no further changes.) 2.3.1 Blocking Atomic SequencesUntil now it was considered an error if an atomic sequence contained any statement that could block the execution of the sequence. This caused much confusion and complicates modeling needlessly. Starting with Spin version 2, it is legal for an atomic sequence to block. If a process inside an atomic sequence blocks, control shifts non-deterministically to another process. If the statement later becomes executable, control can return to the process and the atomic execution of the remainder of the sequence resumed. This change in semantics makes it relatively easy to model, for instance, co-routines where control does not pass from one process to another until and unless the running process blocks. 2.3.2 Rendez-Vous OperationsIt is no longer allowed for a process to perform a rendez-vous handshake with itself, by placing the send and receive half of the rendez-vous in subsequent statements. Of course, it should never have been legal, but the verifiers produced by previous versions of Spin silently allowed it. 2.4 Changes in Syntax2.4.1 Use of MtypesStarting with Spin version 1.6.0 (August 1994) it is legal, and recommended, to use mtype as a data type definition inside channel declarations. It allows the simulator to interpret message fields more predictably either symbolically (if defined as an mtype) or numerically (if defined otherwise). Starting with version 2.7.8 mtype can also be used as a full first class data-type, just like bit, byte, short, and int. Variables of type mtype can be assigned symbolic values from the range declared in a standard mtype range definition (i.e.: mtype = { ... }; ). The value range of an mtype variable (global or local) equals to that of a byte variable (i.e., 0..255). Example: mtype = { full, empty, half_full }; mtype glass = empty; 2.4.2 Remote ReferencingThe adoption of the partial order reduction technique has inspired a revision of the use of remote referencing. It is no longer legal to reference the local variables of a process from within another process, or from within a never claim. No expressiveness is lost, since a local variable can always be made visible to all processes, and to the claim, by promoting it to a global variable. The only valid type of remote referencing that remains is to poll the control state of a process. The syntax for this has changed. The expression: procname[pid]@labelis true if and only if the process with instantiation number pid, of proctype procname, is currently in the state that was marked with label. The main, and perhaps the only, use of this construct is in never claims. 2.4.3 A Few More C-ismsThe use of var++ and var--, as abbreviations of respectively var = var + 1 and var = var - 1, is now supported. 3. Changes in XspinXspin requires a standard X-11 windows environment, and a local installation of the Tcl/Tk toolset. On a Unix system, Xspin is started with the name of a file containing a Promela specification as an argument (or optionally without arguments). For instance as follows: $ xspin H4 Spin Version 2.0 -- 1 January 1995 xspin:The program begins by checking that the correct version of Spin is available (version 2.0 or later), prints the version number on the standard output, and opens the file. If successful, Xspin creates an X-window on the display that offers a graphical interface to virtually all the functionality of Spin. Throughout the use of Xspin, a log of all actions performed is maintained on the standard output. It is handy to have this log visible during a session with Xspin. Syntax errors, unexpected events, time-consuming actions such as background compilations and verification runs, can be tracked only in the log. All entries in the log are prefixed by xspin: , to avoid confusion. In the example above, Xspin logged as the first action performed the successful opening of the file H4. In Version 3, the log has become a standard part of the main xspin interface, so it is guaranteed to be always visible.
The main display of Xspin is text window that displays the file just opened.
The file name itself is shown in the title bar.
The view in the text window can be changed in three different ways:
with the scroll bar, by typing a line number (followed by a
There are several buttons in the title bar of the Xspin display.
We will discuss these separately in the following subsections.
The file menu gives a choice of five actions:
Clear, Load/Open, ReOpen, Save, and Quit.
Clear will remove the contents of the text window.
The help menu gives a quick online review of the main usage
of Spin and Xspin, and contains some hints on the setting of the parameters
and options during verifications and simulations.
The current entries in this menu are:
Promela Usage,
Xspin Usage,
Simulation,
Verification,
FSM Views,
LTL Formulae,
and Reducing Complexity.
Starting with Xspin version 3.0, there is a syntax check option.
Pressing it will cause Xspin to invoke Spin (version 3.0 or later)
to perform only a syntax check on the model. It does so by
generating the pan.c file, but it will not continue with
a compilation of this file when no syntax errors are found.
The result of the check is displayed in a separate window, and
lines in the source that contain syntax errors are highlighted.
Clicking the Simulate button in Xspin brings up
the simulate options panel.
The main choice provided here is to perform either a random simulation
or a guided simulation.
A guided simulation can only be performed if a verification run was
done first, and that verification run revealed an error in the protocol.
The error trail can then be followed with a guided simulation.
Xspin will know where to find the files, and will complain appropriately
if they do not exist.
The tersest display mode would be to select a Time Sequence.
The time sequence shows one column per process, with the actions of each
process printed in the corresponding column.
Each row is prefixed by the process instantiation number and the line
number within the specification that contains the source line executed.
Selecting the option One Window per Process will cause the creation of
a separate display window for each running process (the windows are created
in a lazy fashion: not until a process executes its first statement in the trace).
The last option One Trace per Process similarly creates one window
per process, and shows slightly more information, mostly for debugging purposes.
If the Variable Values Panel is selected, a separate window is
maintained with all local and global variable values.
If the Selected Variables suboption is chosen, all variables
of which the declaration is prefixed with the keyword show in
the specification itself will be included in the MSC displays.
Clicking the Verify button brings up the verify panel.
The panel gives visual control over most of the options that
Spin provides for performing automated verifications.
The initial settings are chosen in such a way that they will
provide a reasonable starting point for most applications.
A first verification run, therefore, can in most cases safely
be performed by hitting the Run button in the lower
right of the panel, without changing any of the default settings.
When a verification run completes, Xspin will attempt to provide
hints about ways to proceed, based on the results obtained.
No hints are provided when a clean run is performed, i.e., a complete
exhaustive search, that did not reveal any errors.
The default hint in cases like these is to consider whether or not
the properties that were proven are the correct ones, and whether or
not other properties still remain to be proven.
In particular, proving liveness properties (properties of infinite behaviors
as manifested by execution cycles) requires a separate verification run
with the appropriate options selected in the Correctness Properties
section of the validator panel.
In the default verification run only safety properties (State Properties)
are proven.
Brings up a panel with an entry box where an LTL formula can be
entered in standard LTL syntax. The formula is translated into
a never claim when a the return key is pressed, or the
Translate/Convert button is selected, and can be saved into
a file.
See the Help menu for this option for more details.
After selecting one of the proctypes that are part of
the Promela specification, Xspin will produce and compile an executable
verifier, and use the state machine output from the -d option
to display a bubble-chart of its local states and transitions.
Moving the cursor over a state (i.e., a circle) will display the
corresponding source line number and, simultaneously, highlight
that line in the main text display window.
Clicking at an edge will display the source
text that corresponds to that edge.
A state can be moved to a new location on the
display with the left or middle mouse button down.
The graph can be saved and printed with standard X utilities
for (partial) screen dumps (e.g., with the grab option
of the program xv), or converted into Postscript and then printed.
If Xspin detects that the graph layout program DOT
is installed, an additional button is enabled that
allows the state graph to be redrawn with that program (recommended).
See the README.html file for details on the distribution
of DOT.
The most important changes that were made in Version 3.0 are summarized
below. Other, more minor, extensions, such as the addition of the
Syntax Check option in Xspin, the extension of the -t
option, or the new hints for frugal data-typing,
have been mentioned in the main text.
A new option to basic Spin allows one to generate a standard
Postscript file that contains the message sequence chart for
a simulation. So far, this output could only be created with
help from Xspin. Especially for long simulation trails (e.g., error
trails produced with the verifier) Xspin can become quite slow when
it attempts to build the message sequence charts. This has been
improved a little in Xspin itself, but it is always much faster to
use basic Spin to generate the Postscript files.
For example,
A plain ASCII approximation of a message sequence chart can be generated
with Spin option -c. It can be used just like option -M
as shown above, except that the output appears on the standard output.
For example:
Some users have reported problems with non-standard
quoting conventions on some systems that complicate
the use of Spin's option -f. In version 3.0 there
is a new option -F that takes a file-name argument,
from which the formula will be read. For example:
The inspiration for adding event trace definitions to Spin can be
found in one of Spin's predecessors, from 1984, which was called trace.
In trace, event trace defintions were specified
with the keyword assert [H85,H87] (no longer free for this
purpose in Spin).
The current implementation of event traces matches the one from [H85,H87].
Their semantics, purpose, intended use are described below.
A simple example of an event trace definition that specifies
the correctness requirement that send operations on the channel
q1 alternate with receive operations on the
channel q2, and furthermore that all send operations on
q1 are (claimed to be) exclusively messages with value a,
and all receive operations on channel q2 are exclusively
messages with value b.
Recall that a system state, for the purposes of verification with Spin,
is a stable value assignment to variables, process-states, and message channels,
that can be tested in boolean propositions.
The transitions of a never claim are labeled with boolean propositions
(expressions) that must evaluate to true in system states.
The transitions of an event trace are labeled directly with monitored
events that must occur in system transitions in the partial order that is
stipulated in the trace definition.
An event trace automaton, just like a never claim automaton, has a
current state, but it only executes transitions if a monitored event
occurs in the system. (I.e., it does not execute synchronously with
the system, as a never claim is required to do.)
This keyword has no semantic content, but only serves to
allow Xspin (and Spin's Postscript output option -M) to
determine which variables should be tracked and included
in message sequence chart displays.
The value of any variable of which the declaration is prefixed
with the keyword show is updated in these displays.
The method of use is identical to that for the keyword hidden
(section 2.1.6).
The symbolic names true and false are now
recognized by the Spin parser as predefined constants with
values 1 and 0 respectively.
The Spin parser no longer rejects the use of an atomic
sequence that is contained within another atomic
or d_step sequence. They are accepted as redundant,
but harmless.
One of the main new additions to Spin version 3.0 is a new
state compression algorithm that is based on the representation
of the state space by a minimized automaton, much like a BDD.
Instead of storing states explicitly, Spin constructs and updates
a recognizer for states, and keeps it in minimal form.
To enable the option, compile the verifier in pan.c with
the directive -DMA=N, where N is the maximum
length of the state vector you expect. The run will abort if
the guess for the state vector size is too small (and will
run somewhat inefficiently if it is too large).
The new algorithm, and its performance, is described in detail in [HP97].
The automaton based representation can be considerably smaller
than an exhaustive state space representation, but it can also
be considerably more time consuming. Both these features imply
that a checkpoint update and recovery option is both possible and
desirable.
To enable checkpointing, compile pan.c with the directive
-DW_XPT. (By default this writes out a checkpoint file
after every multiple of one million states stored. To restart an aborted
run from a checkpoint file, recompile pan.c with directive
-DR_XPT.)
As may be expected, the creation and updating of the checkpoint files
slows down the verification process.
Process death is a conditionally safe action for the
enforcement of the partial order reduction rules from [HP94].
The safety condition has two parts:
The two conditions imply that the process death action can not enable
the execution of run statements, but it can enable other
process deaths (i.e., of another process that now become youngest).
The sequence of process death operations remains fixed to the reverse
order of creation. i.e., process death operations cannot be reordered.
The change has the desirable effect that a process death is forceed
as quickly as possible. Allowing process death to be postponed
arbitrarily long tends to create articifial execution scenarios
where the number of active processes can grow without bound.
This change partly reverses a decision made earlier in Spin version 2.8.5.
Compatibility with Spin versions from 2.8.5-2.9.7 on this issue can
be restored by compiling pan.c with -DGLOB_ALPHA .
Spin is intended to be both a testbed for the development
and evaluation of new verification techniques, and
it is meant to present a robust and reliable environment
for performing verifications of concurrent systems.
If the system is to live up to its promise, therefore, it
will continue to evolve. Users can subscribe to a mailing
list that will announce all new releases of the software.
(See the README.html file from the distribution.)
Apart from further algorithmic improvements, it is also
anticipated that the language Promela will mature
further towards a more complete systems specification language.
The existing version of Spin is meant to provide a stable foundation
for all future work. None of the existing functionality is likely
to be affected by future revisions, and will continue to be supported.
The design and implementation of the Spin model checker is based on
contributions, ideas, and inspiration from many friends and colleagues
over a long period of time, most notably
Costas Courcoubetis,
Peter Van Eijk,
Michael Ferguson,
Rob Gerth,
Patrice Godefroid,
Doug McIlroy,
Doron Peled,
Rob Pike,
Anuj Puri,
Jim Reeds,
Moshe Vardi,
Pierre Wolper,
and Mihalis Yannakakis.
[AD94] R. Alur and D. L. Dill,
``A theory of timed automata,''
Theoretical Computer Science, 126, pp. 183-235, 1994.
[BCG86] G. Berry, P. Couronne and G. Gonthier,
``Synchronous Programming of Reactive Systems: An Introduction to ESTEREL,''
Proc. 1st Franco-Japanese Symp. on Programming of Future Generation Computers,
1986, Tokyo. pp. 35-56. Ed. K. Fuchi, M. Nivat. North Holland Publ.
[PC95] C-T. Chou, and D. Peled,
``Verifying a Model-Checking Algorithm,''
Proc. TACAS'96, Tools and Algorithms for the Construction and Analysis of Systems,
Passau, Germany, March 1996.
LNCS 1055, Springer Verlag, 1995.
[C74] Y. Choueka, ``Theories of automata on @omega@-tapes: a simplified approach,''
Journal of Computer and System Science 8 (1974), 117-141.
[ClEm81] E. M. Clarke and E. A. Emerson,
``Characterizing properties of parallel programs as fixpoints,''
7th Int. Coll. on Automata, Languages and Programming. LNCS 85, 1981.
[CVWY92] C. Courcoubetis, M. Vardi, P. Wolper, M. Yannakakis, ``Memory
efficient algorithms for the verification of temporal properties,''
Formal Methods in Systems Design I, 1992, pp. 275-288.
[GH93] P. Godefroid and G. J. Holzmann,
``On the verification of temporal properties,''
Proc. IFIP/WG6.1 Symp. on Protocols Specification, Testing, and Verification,
PSTV93, Liege, Belgium, June 1993.
[Haj78] J. Hajek, ``Automatically verified data transfer protocols,''
Proc. 4th ICCC, 1978, Kyoto, pp. 749-756.
[Hal93] N. Halbwachs, ``Synchronous programming of reactive systems,''
Kluwer Academic Publishers, 1993.
[Har87] D. Harel,
``Statecharts: A visual formalism for complex systems,''
Science of Computer Programming vol 8, 1987, pp 231-274.
[H81] G. J. Holzmann,
``PAN - a protocol specification analyzer,''
Bell Laboratories Technical Memorandum, TM81-11271-5, May 1981.
[H83] G. J. Holzmann, R. A. Beukers,
``The PANDORA Protocol Development System,''
Proc. 3rd Int. Conf on Protocol Specification, Testing, and Verification, INWG/IFIP,
Eds. H. Rudin and C. West,
pp. 357--369, North Holland Publ. Co., June, 1983.
[H85] G. J. Holzmann,
``Tracing protocols,'' AT&T Techn. Journal, Vol 64, No. 10, Dec. 1985.
[H87] G. J. Holzmann,
``Automated protocol validation in Argos,
assertion proving, scatter searching,''
IEEE Trans. on Software Eng., Vol SE-13, No 6, June 1987, pp. 683-696.
[H88] G. J. Holzmann, ``An improved reachability analysis technique,''
Software Practice and Experience, Vol. 18, No. 2, pp. 137-161, Feb. 1988.
[H89] G. J. Holzmann, J. Patti,
``Validating SDL Specifications: An Experiment,''
Proc. 9th Int. Conf on Protocol Specification, Testing, and Verification, INWG/IFIP,
Ed. C. Vissers and E. Brinksma,
Twente, Neth., June, 1989.
[H91] G. J. Holzmann, ``Design and Validation of Computer
Protocols,'' Prentice Hall, 1991.
[HP94] G. J. Holzmann and D. Peled, ``An improvement in
formal verification,''
Proc. 7th Int. Conf. on Formal Description Techniques,
FORTE94, Berne, Switzerland. October 1994.
[GPVW95] R. Gerth, D. Peled, M. Vardi, P. Wolper, ``Simple on-the-fly
automatic verification of linear temporal logic,''
Proc. PSTV95 Conference, Warsaw Poland, 1995.
[H95] G. J. Holzmann, ``An analysis of bitstate searching,''
Proc. IFIP/WG6.1 Symp. on Protocols Specification, Testing, and Verification,
PSTV95, Warsaw, Poland, June 1995.
[HPY96] G. J. Holzmann, D. Peled, and M. Yannakakis, ``On nested depth-first
search,''
Proc. 2nd Spin Workshop, American Mathematical Society, DIMACS/32.
October 1996.
[H97a] G. J. Holzmann, ``State compression in Spin,''
Proc. 3rd Spin Workshop, Twente University, April 1997.
[H97b] G. J. Holzmann, ``The model checker Spin,''
IEEE Trans. on Software Engineering, Vol. 23, No. 5.
[HP97] G. J. Holzmann and A. Puri, ``A minimized automaton representation
of reachable states,''
Technical report, submitted for publication.
[H98] G. J. Holzmann, ``The Verification of Concurrent Systems,''
Course Notes 1994-1996. (To be published).
[KR88] B. W. Kernighan and D. M. Ritchie, ``The C Programming
Language,'' 2nd Edition, Prentice Hall, 1988.
[PM88] S. K. Park and K. W. Miller,
``Random number generators: good ones are hard to find,''
Comm. of the ACM, Vol 31, No. 10, Oct. 1988, pp. 1192-1201.
[P94] D. A. Peled, ``Combining partial order reductions with
on-the-fly model checking,''
Proc. 6th Int. Conf. on Computer Aided Verification,
CAV94, Stanford, Ca., June 1994.
[Qu82] J. P. Queille,
``Le systeme C\ësar: description,
sp\ëcification et analyse des applications r\ëparties,''
Ph.D. Thesis, June 1982, Computer Science Dept.,
Univ. Grenoble, France.
[W78] C. H. West, ``General Technique for Communications
Protocol Validation,''
IBM Journal of Research and Development, Vol 22, No. 4, p. 393, 1978.
There are four directives that can be used for
compiling the Spin sources itself. These should never
be needed by Spin users, only (once) by someone
recompiling and installing Spin from its sources.
The remaining tables give optional directives for compiling
the verifiers that are generated by Spin. Traditionally these
are stored in a file named pan.c (with a number of
dependent files).
Usage of the directives below is
always optional, and typically of the form:
|