Annotation of researchv10dc/vol2/spin/spin.ms_o, revision 1.1

1.1     ! root        1: .so ../ADM/mac
        !             2: .XX spin 429 "Spin \(em A Protocol Analyzer"
        !             3: .nr dP 2
        !             4: .nr dV 3p
        !             5: .EQ
        !             6: delim @@
        !             7: .EN
        !             8: .de IH \" makes a bold italic sub heading
        !             9: .NH 2
        !            10: \\$1
        !            11: ..
        !            12: .ds P \\s-2PROMELA\\s0
        !            13: .ds S \fISpin\fP
        !            14: .ds s \fIspin\fP
        !            15: .TL
        !            16: Spin \(em A Protocol Analyzer
        !            17: .AU "MH 2C-521" 6335
        !            18: Gerard J. Holzmann
        !            19: .AI
        !            20: .MH
        !            21: .AB
        !            22: \*S is a tool for analyzing the logical consistency of
        !            23: concurrent systems, specifically of data communication protocols.
        !            24: The system is described in a modeling language called \*P.
        !            25: The language allows for the dynamic creation of concurrent processes.
        !            26: Communication via message channels can be defined to be synchronous
        !            27: (i.e., rendez-vous), or asynchronous (i.e., buffered).
        !            28: .PP
        !            29: Given a model system specified in \*P, \*s
        !            30: can either perform random simulations of the system's execution
        !            31: or it can generate a C program that performs a fast exhaustive
        !            32: validation of the system state space.
        !            33: During simulations and validations \*s checks for the absence of deadlocks,
        !            34: unspecified receptions, and unexecutable code.
        !            35: The validator can also be used to verify the correctness of
        !            36: system invariants, and it can find non-progress execution cycles.
        !            37: .PP
        !            38: The validator is setup to be extremely fast and to use
        !            39: only a minimal amount of memory.
        !            40: The exhaustive validations performed by \*s are conclusive,
        !            41: They establish with certainty whether or not a given behavior
        !            42: is error-free.
        !            43: Very large validation runs, that can ordinarily not be
        !            44: performed with automated techniques, can be
        !            45: done in \*s with a novel ``bit state space'' technique.
        !            46: With this method the state space is collapsed to a single
        !            47: bit per system state stored, with minimal side-effects.
        !            48: .PP
        !            49: The first part of this memo gives an introduction to \*P,
        !            50: the second part discusses the usage of \*s, and
        !            51: the third part contains a brief reference manual for \*P.
        !            52: In the appendix an example is used to illustrate the construction
        !            53: of a basic \*P model for \*s validations.
        !            54: .AE
        !            55: .2C
        !            56: .NH
        !            57: Introduction to \*P
        !            58: .PP
        !            59: \*P is a validation modeling language.
        !            60: It provides a vehicle for making abstractions of protocols
        !            61: (or distributed systems in general) that suppress details
        !            62: that are unrelated to process interaction.
        !            63: The intended use of \*s is to validate fractions of process
        !            64: behavior, that for one reason or another is considered suspect.
        !            65: The relevant behavior is modeled in \*P and validated.
        !            66: A complete validation is therefore typically performed in a series of steps,
        !            67: with the construction of increasingly detailed \*P models.
        !            68: Each model can be validated with \*s under different types of
        !            69: assumptions about the environment (e.g., message loss, message
        !            70: duplications etc).
        !            71: Once the correctness of a model has been established with \*s, that
        !            72: fact can be used in the construction and validation of all
        !            73: subsequent models.
        !            74: .PP
        !            75: \*P programs consist of \f2processes\f1,
        !            76: message \f2channels\f1, and \f2variables\f1.
        !            77: Processes are global objects.
        !            78: Message channels and variables can be declared either globally
        !            79: or locally within a process.
        !            80: Processes specify behavior; channels and global variables
        !            81: define the environment in which the processes run.
        !            82: .IH Executability
        !            83: .PP
        !            84: In \*P there is no difference between conditions and
        !            85: statements, even isolated boolean conditions can be used as statements.
        !            86: The execution of every statement is conditional on its
        !            87: .I executability .
        !            88: Statements are either executable or blocked.
        !            89: The executability is the basic means of synchronization.
        !            90: A process can wait for an event to happen by waiting
        !            91: for a statement to become executable.
        !            92: For instance, instead of writing a busy wait loop:
        !            93: .P1 0
        !            94: while (a != b)
        !            95:        skip    /* wait for a==b */
        !            96: .P2
        !            97: one can achieve the same effect in \*P with the statement
        !            98: .P1 0
        !            99: (a == b)
        !           100: .P2
        !           101: A condition can only be executed (passed) when it holds.
        !           102: If the condition does not hold, execution blocks until it does.
        !           103: .PP
        !           104: Variables are used to store either global information about the
        !           105: system as a whole, or information local to one specific process,
        !           106: depending on where the declaration for the variable is placed.
        !           107: The declarations
        !           108: .P1 0
        !           109: bool flag;
        !           110: int state;
        !           111: byte msg;
        !           112: .P2
        !           113: define variables that can store integer values in
        !           114: three different ranges.
        !           115: The scope of a variable is global if it is declared outside all
        !           116: process declarations, and local if it is declared within a process
        !           117: declaration.
        !           118: .IH "Data Types"
        !           119: .PP
        !           120: Table 1 summarizes the basic data types, sizes,
        !           121: and the corresponding value ranges (on a DEC VAX computer).
        !           122: .KS
        !           123: .SP .5
        !           124: .ps -1
        !           125: .vs -2
        !           126: .TS
        !           127: center;
        !           128: l l l l
        !           129: lFCW n r c.
        !           130: =
        !           131: Name   Size (bits)     Usage   Range
        !           132: _
        !           133: bit    1       unsigned        0..1
        !           134: bool   1       unsigned        0..1
        !           135: byte   8       unsigned        0..255
        !           136: short  16      signed  @-2 sup 15@..@{2 sup 15} - 1@
        !           137: int    32      signed  @-2 sup 31@..@{2 sup 31} - 1@
        !           138: _
        !           139: .TE
        !           140: .ps +1
        !           141: .vs +2
        !           142: .SP .5
        !           143: .ce
        !           144: \fBTable 1.\fP Data Types
        !           145: .SP
        !           146: .KE
        !           147: The names
        !           148: .CW bit
        !           149: and
        !           150: .CW bool
        !           151: are synonyms for a single bit of information.
        !           152: A
        !           153: .CW byte
        !           154: is an unsigned quantity that can store a value between
        !           155: .CW 0
        !           156: and
        !           157: .CW 255 .
        !           158: .CW short s
        !           159: and
        !           160: .CW int s
        !           161: are signed quantities that
        !           162: differ only in the range of values they can hold.
        !           163: .IH "Array Variables"
        !           164: .PP
        !           165: Variables can be declared as arrays.
        !           166: For instance,
        !           167: .P1 0
        !           168: byte state[N]
        !           169: .P2
        !           170: declares an array of
        !           171: .CW N
        !           172: bytes that can be accessed in statements such as
        !           173: .P1 0
        !           174: state[0] = state[3] + 5 * state[3*2/n]
        !           175: .P2
        !           176: where
        !           177: .CW n
        !           178: is a constant or a variable declared elsewhere.
        !           179: The index to an array can be any expression that
        !           180: determines a unique integer value.
        !           181: The effect of an index value outside the range
        !           182: .CW "0 .. N-1"
        !           183: is undefined; most likely it will cause a runtime error.
        !           184: .PP
        !           185: So far we have seen examples of variable declarations
        !           186: and of two types of statements: boolean conditions and
        !           187: assignments.
        !           188: Declarations and assignments are always \f2executable\f1.
        !           189: Conditions are only executable when they hold.
        !           190: .IH "Process Types"
        !           191: .PP
        !           192: The state of a variable or of a message channel
        !           193: can only be changed or inspected by processes.
        !           194: The behavior of a process is defined in a
        !           195: .CW proctype
        !           196: declaration.
        !           197: The following, for instance, declares a process with one local variable
        !           198: .CW state .
        !           199: .P1 0
        !           200: proctype A()
        !           201: {      byte state;
        !           202: 
        !           203:        state = 3
        !           204: }
        !           205: .P2
        !           206: The process type is named
        !           207: .CW A .
        !           208: The body of the declaration is enclosed in curly braces.
        !           209: The declaration body consists of a list of zero or more
        !           210: declarations of local variables and/or statements.
        !           211: The declaration above contains one local variable declaration
        !           212: and a single statement: an assignment of the
        !           213: value 3 to variable
        !           214: .CW state .
        !           215: .PP
        !           216: The semicolon is a statement \f2separator\f1 (not a statement terminator,
        !           217: hence there is no semicolon after the last statement).
        !           218: \*P accepts two different statement separators:
        !           219: .CW `->'
        !           220: (arrow) and
        !           221: .CW `;' .
        !           222: The two statement separators are equivalent.
        !           223: The arrow is sometimes used as an informal way to indicate a causal
        !           224: relation between two statements.
        !           225: Consider the following example.
        !           226: .P1 0
        !           227: byte state = 2;
        !           228: 
        !           229: proctype A()
        !           230: {      (state == 1) -> state = 3
        !           231: }
        !           232: .P3
        !           233: proctype B()
        !           234: {      state = state \- 1
        !           235: }
        !           236: .P2
        !           237: In this example we declared two types of processes,
        !           238: .CW A
        !           239: and
        !           240: .CW B .
        !           241: Variable
        !           242: .CW state
        !           243: is now a global, initialized to the value two.
        !           244: Process type
        !           245: .CW A
        !           246: contains two statements, separated by an arrow.
        !           247: In the example, process declaration
        !           248: .CW B
        !           249: contains a single statement that decrements
        !           250: the value of the state variable by one.
        !           251: Since the assignment is always executable,
        !           252: processes of type
        !           253: .CW B
        !           254: can always complete without delay.
        !           255: Processes of type
        !           256: .CW A ,
        !           257: however, are delayed at the condition until
        !           258: the variable
        !           259: .CW state
        !           260: contains the proper value.
        !           261: ......
        !           262: .IH "Process Instantiation"
        !           263: .PP
        !           264: A
        !           265: .CW proctype
        !           266: definition only declares process behavior, it
        !           267: does not execute it.
        !           268: Initially, in the \*P model, just one process will be executed:
        !           269: a process of type
        !           270: .CW init ,
        !           271: that must be declared explicitly in every \*P specification.
        !           272: The smallest possible \*P specification, therefore, is:
        !           273: .P1 0
        !           274: init { skip }
        !           275: .P2
        !           276: where
        !           277: .CW skip
        !           278: is a dummy, null statement.
        !           279: More interestingly, however,
        !           280: the initial process can initialize global variables,
        !           281: and instantiate processes.
        !           282: An
        !           283: .CW init
        !           284: declaration for the above system, for instance, could look as follows.
        !           285: .P1 0
        !           286: init
        !           287: {      run A(); run B()
        !           288: }
        !           289: .P2
        !           290: .PP
        !           291: .CW run
        !           292: is used as a unary operator that takes the name of a process type (e.g.
        !           293: .CW A ).
        !           294: It is executable only if a process of
        !           295: the type specified can be instantiated.
        !           296: It is unexecutable if this cannot be done,
        !           297: for instance if too many processes are already running.
        !           298: .PP
        !           299: The
        !           300: .CW run
        !           301: statement can pass parameter values of all basic
        !           302: data types to the new process.
        !           303: The declarations are then written, for instance, as follows:
        !           304: .P1 0
        !           305: proctype A(byte state; short foo)
        !           306: {
        !           307:        (state == 1) -> state = foo
        !           308: }
        !           309: .P3
        !           310: init
        !           311: {
        !           312:        run A(1, 3)
        !           313: }
        !           314: .P2
        !           315: Data arrays or process types can not be passed as parameters.
        !           316: As we will see below, there is just one other data type that
        !           317: can be used as a parameter: a message channel.
        !           318: .PP
        !           319: .CW Run
        !           320: statements can be used in any process to spawn new processes,
        !           321: not just in the initial process.
        !           322: Processes are created with the
        !           323: .CW run
        !           324: statements.
        !           325: An executing process disappears again when it terminates
        !           326: (i.e., reaches the end of the body of its
        !           327: process type declaration), but not before all processes
        !           328: that it started have terminated.
        !           329: .PP
        !           330: With the
        !           331: .CW run
        !           332: statement we can create any number of copies of the process types
        !           333: .CW A
        !           334: and
        !           335: .CW B .
        !           336: If, however, more than one concurrent process is allowed to both read and
        !           337: write the value of a global variable a well-known set of problems
        !           338: can result; for example see |reference(dijkstra concurrent).
        !           339: Consider, for instance, the following system of
        !           340: two processes, sharing access to the global variable
        !           341: .CW state .
        !           342: .P1 0
        !           343: byte state = 1;
        !           344: 
        !           345: proctype A()
        !           346: {      (state==1) -> state = state+1
        !           347: }
        !           348: .P3
        !           349: proctype B()
        !           350: {      (state==1) -> state = state\-1
        !           351: }
        !           352: .P3
        !           353: init
        !           354: {      run A(); run B()
        !           355: }
        !           356: .P2
        !           357: If one of the two processes completes before its competitor has
        !           358: started, the other process will block forever on the initial condition.
        !           359: If both pass the condition simultaneously, both will complete, but
        !           360: the resulting value of
        !           361: .CW state
        !           362: is unpredictable.
        !           363: It can be any of the values
        !           364: .CW 0 ,
        !           365: .CW 1 ,
        !           366: or
        !           367: .CW 2 .
        !           368: .PP
        !           369: Many solutions to this problem have been considered, ranging from
        !           370: an abolishment of global variables to the provision of special
        !           371: machine instructions that can guarantee an indivisible test and
        !           372: set sequence on a shared variable.
        !           373: The example below was one of the first solutions published.
        !           374: It is due to the Dutch mathematician Dekker.
        !           375: It grants two processes mutually exclusion access to an arbitrary
        !           376: .I
        !           377: critical section
        !           378: .R
        !           379: in their code, by manipulation three additional global variables.
        !           380: The first four lines in the \*P specification
        !           381: below are C-style macro definitions.
        !           382: The first two macros define
        !           383: .CW true
        !           384: to be a constant value equal to
        !           385: .CW 1
        !           386: and
        !           387: .CW false
        !           388: to be a constant
        !           389: .CW 0 .
        !           390: Similarly,
        !           391: .CW Aturn
        !           392: and
        !           393: .CW Bturn
        !           394: are defined as constants.
        !           395: .P1 0
        !           396: #define true   1
        !           397: #define false  0
        !           398: #define Aturn  false
        !           399: #define Bturn  true
        !           400: 
        !           401: bool x, y, t;
        !           402: .P3
        !           403: 
        !           404: proctype A()
        !           405: {      x = true;
        !           406:        t = Bturn;
        !           407:        (y == false || t == Aturn);
        !           408:        /* critical section */
        !           409:        x = false
        !           410: }
        !           411: .P3
        !           412: proctype B()
        !           413: {      y = true;
        !           414:        t = Aturn;
        !           415:        (x == false || t == Bturn);
        !           416:        /* critical section */
        !           417:        y = false
        !           418: }
        !           419: .P3
        !           420: init
        !           421: {      run A(); run B()
        !           422: }
        !           423: .P2
        !           424: The algorithm can be executed repeatedly and is independent of
        !           425: the relative speeds of the two processes.
        !           426: .IH "Atomic Sequences"
        !           427: .PP
        !           428: In \*P there is also another way to avoid the \f2test and set\f1
        !           429: problem:
        !           430: .CW atomic
        !           431: sequences.
        !           432: By prefixing a sequence of statements enclosed in curly
        !           433: braces with the keyword
        !           434: .CW atomic
        !           435: the user can indicate that the sequence is to be executed
        !           436: as one indivisible unit, non-interleaved with any other
        !           437: processes.
        !           438: It causes a run-time error if any statement, other than
        !           439: the first statement, blocks in an atomic sequence.
        !           440: This is how we can use atomic sequences to protect the
        !           441: concurrent access to the global variable
        !           442: .CW state
        !           443: in the earlier example.
        !           444: .P1 0
        !           445: byte state = 1;
        !           446: 
        !           447: proctype A()
        !           448: {      atomic {
        !           449:          (state==1) -> state = state+1
        !           450:        }
        !           451: }
        !           452: .P3
        !           453: proctype B()
        !           454: {      atomic {
        !           455:          (state==1) -> state = state\-1
        !           456:        }
        !           457: }
        !           458: .P3
        !           459: init
        !           460: {      run A(); run B()
        !           461: }
        !           462: .P2
        !           463: In this case the final value of
        !           464: .CW state
        !           465: is guaranteed to be zero, though during the execution of
        !           466: .CW A
        !           467: and
        !           468: .CW B
        !           469: the intermediate value can be either
        !           470: .CW 0
        !           471: or
        !           472: .CW 2 .
        !           473: .PP
        !           474: Atomic sequences can be an important tool in reducing
        !           475: the complexity of validation models.
        !           476: Note that atomic sequence restricts the amount of
        !           477: interleaving that is allowed in a distributed system.
        !           478: Otherwise untractable models can be made tractable
        !           479: by, for instance, labeling all manipulations of local variables
        !           480: with atomic sequences.
        !           481: The reduction in complexity can be dramatic.
        !           482: .IH "Message Passing"
        !           483: .PP
        !           484: Message channels are used to model the transfer of data
        !           485: from one process to another.
        !           486: They are declared either locally or globally,
        !           487: for instance as follows:
        !           488: .P1 0
        !           489: chan qname[16] of { short }
        !           490: .P2
        !           491: This declares a channel that can store up
        !           492: to 16 messages of type
        !           493: .CW short .
        !           494: Channel names can be passed from one process to another via
        !           495: channels or as parameters in process instantiations.
        !           496: If the messages to be passed by the channel have more than
        !           497: one field, the declaration may look as follows:
        !           498: .P1 0
        !           499: chan qname[16] of { byte, int, chan, byte }
        !           500: .P2
        !           501: This time each message in the channel stores up to
        !           502: sixteen messages, each consisting of two 8-bit values,
        !           503: one 32-bit value, and a channel name.
        !           504: .PP
        !           505: .Tm !  S
        !           506: .Tm ?  S
        !           507: The statement
        !           508: .P1 0
        !           509: qname!expr
        !           510: .P2
        !           511: sends the value of expression
        !           512: .CW expr
        !           513: to the channel that we just created, that is:
        !           514: it appends the value to the tail of the channel.
        !           515: .P1 0
        !           516: qname?msg
        !           517: .P2
        !           518: receives the message, it retrieves it from the head of the channel,
        !           519: and stores it in a variable
        !           520: .CW msg .
        !           521: The channels pass messages in first-in-first-out order.
        !           522: In the above cases only a single value
        !           523: is passed through the channel.
        !           524: If more than one value is to be transferred per message,
        !           525: they are specified in a comma separated list
        !           526: .P1 0
        !           527: qname!expr1,expr2,expr3
        !           528: qname?var1,var2,var3
        !           529: .P2
        !           530: If more parameters are sent per message then the message channel
        !           531: can store, the redundant parameters are lost without warning.
        !           532: If fewer parameters are sent then the message channel can store,
        !           533: the value of the remaining parameters is undefined.
        !           534: Similarly, if the receive operation tries to retrieve more
        !           535: parameters than available, the value of the extra parameters is
        !           536: undefined; if it receives fewer than the number of parameters
        !           537: that was sent, the extra information is lost.
        !           538: .PP
        !           539: By convention, the first message field is often
        !           540: used to specify the message type (i.e. a constant).
        !           541: An alternative, and equivalent, notation for the
        !           542: send and receive operations is therefore to specify the
        !           543: message type, followed by a list of message fields
        !           544: enclosed in braces.
        !           545: In general:
        !           546: .P1 0
        !           547: qname!expr1(expr2,expr3)
        !           548: qname?var1(var2,var3)
        !           549: .P2
        !           550: .PP
        !           551: The send operation is executable only when the channel addressed is not full.
        !           552: The receive operation, similarly, is only executable
        !           553: when the channel is non empty.
        !           554: Optionally, some of the arguments of the receive operation
        !           555: can be constants:
        !           556: .P1 0
        !           557: qname?cons1,var2,cons2
        !           558: .P2
        !           559: in this case, a further condition on the executability of the
        !           560: receive operation is that the value of all message fields that are
        !           561: specified as constants match the value of the corresponding fields
        !           562: in the message that is at the head of the channel.
        !           563: Again, nothing bad will happen if a statement happens to be non-executable.
        !           564: The process trying to execute it will be delayed until the
        !           565: statement, or, more likely, an alternative statement, becomes executable.
        !           566: .PP
        !           567: Here is an example that uses some of the mechanisms introduced
        !           568: so far.
        !           569: .P1 0
        !           570: proctype A(chan q1)
        !           571: {      chan q2;
        !           572:        q1?q2;
        !           573:        q2!123
        !           574: }
        !           575: .P3
        !           576: proctype B(chan qforb)
        !           577: {      int x;
        !           578:        qforb?x;
        !           579:        printf("x = %d\n", x)
        !           580: }
        !           581: .P3
        !           582: init {
        !           583:        chan qname[1] of { chan };
        !           584:        chan qforb[1] of { int };
        !           585:        run A(qname);
        !           586:        run B(qforb);
        !           587:        qname!qforb
        !           588: }
        !           589: .P2
        !           590: The value printed will be
        !           591: .CW 123 .
        !           592: .PP
        !           593: A predefined function
        !           594: .CW len(qname)
        !           595: returns the number of messages currently
        !           596: stored in channel
        !           597: .CW qname .
        !           598: Note that if
        !           599: .CW len
        !           600: is used as a statement, rather than on
        !           601: the right hand side of an assignment, it will be unexecutable if
        !           602: the channel is empty: it returns a zero result, which by definition
        !           603: means that the statement is temporarily unexecutable.
        !           604: Composite conditions such as
        !           605: .P1 0
        !           606: (qname?var == 0)
        !           607: .P2
        !           608: or
        !           609: .P1 0
        !           610: (a > b && qname!123)
        !           611: .P2
        !           612: are invalid in \*P (note that these conditions can not be evaluated
        !           613: without side-effects).
        !           614: For a receive statement there is an alternative, using square
        !           615: brackets around the clause behind the question mark.
        !           616: .P1 0
        !           617: qname?[ack,var]
        !           618: .P2
        !           619: is evaluated as a condition.
        !           620: It returns
        !           621: .CW 1
        !           622: if the corresponding receive statement
        !           623: .P1 0
        !           624: qname?ack,var
        !           625: .P2
        !           626: is executable, i.e., if there is indeed a message
        !           627: .CW ack
        !           628: at the head of the channel.
        !           629: It returns
        !           630: .CW 0
        !           631: otherwise.
        !           632: In neither case has the evaluation of a statement such as
        !           633: .P1 0
        !           634: qname?[ack,var]
        !           635: .P2
        !           636: any side-effects: the receive is evaluated, not executed.
        !           637: .PP
        !           638: Note carefully that in non-atomic sequences of two statements such as
        !           639: .P1 0
        !           640: (len(qname) < MAX) -> qname!msgtype
        !           641: .P2
        !           642: or
        !           643: .P1 0
        !           644: qname?[msgtype] -> qname?msgtype
        !           645: .P2
        !           646: the second statement is not \f2necessarily\f1 executable
        !           647: after the first one has been executed.
        !           648: There may be race conditions if access to the channels
        !           649: is shared between several processes.
        !           650: In the first case
        !           651: another process can send a message to channel
        !           652: .CW qname
        !           653: just after this process determined that the channel was not full.
        !           654: In the second case, the other process can steal away the
        !           655: message just after our process determined its presence.
        !           656: .IH "Rendez-Vous Communication"
        !           657: .PP
        !           658: So far we have talked about asynchronous communication between processes
        !           659: via message channels, declared in statements such as
        !           660: .P1 0
        !           661: chan qname [N] of { byte }
        !           662: .P2
        !           663: where
        !           664: .CW N
        !           665: is a positive constant that defines the buffer size.
        !           666: A logical extension is to allow for the declaration
        !           667: .P1 0
        !           668: chan port [0] of { byte }
        !           669: .P2
        !           670: to define a rendez-vous port that can pass single byte messages.
        !           671: The channel size is zero, that is, the channel
        !           672: .CW port
        !           673: can pass, but can not store messages.
        !           674: Message interactions via such rendez-vous ports are
        !           675: by definition synchronous.
        !           676: Consider the following example.
        !           677: .P1 0
        !           678: #define msgtype 33
        !           679: 
        !           680: chan name [0] of { byte, byte };
        !           681: 
        !           682: proctype A()
        !           683: {      name!msgtype(124);
        !           684:        name!msgtype(121)
        !           685: }
        !           686: .P3
        !           687: proctype B()
        !           688: {      byte state;
        !           689:        name?msgtype(state)
        !           690: }
        !           691: .P3
        !           692: init
        !           693: {      atomic { run A(); run B() }
        !           694: }
        !           695: .P2
        !           696: Channel
        !           697: .CW name
        !           698: is a global rendez-vous port.
        !           699: The two processes will synchronously execute their first statement:
        !           700: a handshake on message
        !           701: .CW msgtype
        !           702: and a transfer of the value 124 to local variable
        !           703: .CW state .
        !           704: The second statement in process
        !           705: .CW A
        !           706: will be unexecutable,
        !           707: because there is no matching receive operation in process
        !           708: .CW B .
        !           709: .PP
        !           710: If the channel
        !           711: .CW name
        !           712: is defined  with a non-zero buffer capacity,
        !           713: the behavior is different.
        !           714: If the buffer size is at least 2, the process of type
        !           715: .CW A
        !           716: can complete its execution, before its peer even starts.
        !           717: If the buffer size is 1, the sequence of events is as follows.
        !           718: The process of type
        !           719: .CW A
        !           720: can complete its first send action, but it blocks on the
        !           721: second, because the channel is now filled to capacity.
        !           722: The process of type
        !           723: .CW B
        !           724: can then retrieve the first message and complete.
        !           725: At this point
        !           726: .CW A
        !           727: becomes executable again and completes,
        !           728: leaving its last message as a residual in the channel.
        !           729: .PP
        !           730: Rendez-vous communication is binary: only two processes,
        !           731: a sender and a receiver, can be synchronized in a
        !           732: rendez-vous handshake.
        !           733: We will see an example of a way to exploit this to
        !           734: build a semaphore below.
        !           735: But first, let us introduce a few more control flow structures
        !           736: that may be useful.
        !           737: .NH 2
        !           738: Control Flow
        !           739: .PP
        !           740: Between the lines, we have already introduced three ways of
        !           741: defining control flow: concatenation of statements
        !           742: within a process, parallel execution of processes, and
        !           743: atomic sequences.
        !           744: There are three other control flow constructs in \*P to be discussed.
        !           745: They are case selection,
        !           746: repetition, and
        !           747: unconditional jumps.
        !           748: .NH 3
        !           749: Case Selection
        !           750: .PP
        !           751: The simplest construct is the selection structure.
        !           752: Using the relative values of two variables
        !           753: .CW a
        !           754: and
        !           755: .CW b
        !           756: to choose between two options, for instance, we can write:
        !           757: .P1 0
        !           758: if
        !           759: :: (a != b) -> option1
        !           760: :: (a == b) -> option2
        !           761: fi
        !           762: .P2
        !           763: The selection structure contains two execution sequences,
        !           764: each preceded by a double colon.
        !           765: Only one sequence from the list will be executed.
        !           766: A sequence can be selected only if its first statement is executable.
        !           767: The first statement is therefore called a \f2guard\f1.
        !           768: .PP
        !           769: In the above example the guards are mutually exclusive, but they
        !           770: need not be.
        !           771: If more than one guard is executable, one of the corresponding sequences
        !           772: is selected nondeterministically.
        !           773: If all guards are unexecutable the process will block until at least
        !           774: one of them can be selected.
        !           775: There is no restriction on the type of statements that can be used
        !           776: as a guard.
        !           777: The following example, for instance, uses input statements.
        !           778: .P1 0
        !           779: #define a 1
        !           780: #define b 2
        !           781: 
        !           782: chan ch[1] of { byte };
        !           783: 
        !           784: proctype A()
        !           785: {      ch!a
        !           786: }
        !           787: .P3
        !           788: proctype B()
        !           789: {      ch!b
        !           790: }
        !           791: .P3
        !           792: proctype C()
        !           793: {      if
        !           794:        :: ch?a
        !           795:        :: ch?b
        !           796:        fi
        !           797: }
        !           798: .P3
        !           799: init
        !           800: {      atomic { run A(); run B(); run C() }
        !           801: }
        !           802: .P2
        !           803: The example defines three processes and one channel.
        !           804: The first option in the selection structure of the process
        !           805: of type
        !           806: .CW C
        !           807: is executable if the channel contains
        !           808: a message
        !           809: .CW a ,
        !           810: where
        !           811: .CW a
        !           812: is a constant with value
        !           813: .CW 1 ,
        !           814: defined in a macro definition at the start of the program.
        !           815: The second option is executable if it contains a message
        !           816: .CW b ,
        !           817: where, similarly,
        !           818: .CW b
        !           819: is a constant.
        !           820: Which message will be available depends on the unknown
        !           821: relative speeds of the processes.
        !           822: .PP
        !           823: A process of the following type will either increment
        !           824: or decrement the value of variable
        !           825: .CW count
        !           826: once.
        !           827: .P1 0
        !           828: byte count;
        !           829: 
        !           830: proctype counter()
        !           831: {
        !           832:        if
        !           833:        :: count = count + 1
        !           834:        :: count = count \- 1
        !           835:        fi
        !           836: }
        !           837: .P2
        !           838: .NH 3
        !           839: Repetition
        !           840: .PP
        !           841: A logical extension of the selection structure is
        !           842: the repetition structure.
        !           843: We can modify the above program as follows, to obtain
        !           844: a cyclic program that randomly changes the value of
        !           845: the variable up or down.
        !           846: .P1 0
        !           847: byte count;
        !           848: 
        !           849: proctype counter()
        !           850: {
        !           851:        do
        !           852:        :: count = count + 1
        !           853:        :: count = count \- 1
        !           854:        :: (count == 0) -> break
        !           855:        od
        !           856: }
        !           857: .P2
        !           858: .PP
        !           859: Only one option can be selected for execution at a time.
        !           860: After the option completes, the execution of the structure
        !           861: is repeated.
        !           862: The normal way to terminate the repetition structure is
        !           863: with a
        !           864: .CW break
        !           865: statement.
        !           866: In the example, the loop can be
        !           867: broken when the count reaches zero.
        !           868: Note, however, that it need
        !           869: not terminate since the other two options always remain executable.
        !           870: To force termination we could modify the program as follows.
        !           871: .P1 0
        !           872: proctype counter()
        !           873: {
        !           874:        do
        !           875:        :: (count != 0) ->
        !           876:                if
        !           877:                :: count = count + 1
        !           878:                :: count = count \- 1
        !           879:                fi
        !           880:        :: (count == 0) -> break
        !           881:        od
        !           882: }
        !           883: .P2
        !           884: .NH 3
        !           885: Unconditional Jumps
        !           886: .PP
        !           887: Another way to break the loop is with an unconditional jump:
        !           888: the infamous
        !           889: .CW goto
        !           890: statement.
        !           891: This is illustrated in the following implementation of Euclid's algorithm for
        !           892: finding the greatest common divisor of two non-zero, positive numbers:
        !           893: .P1 0
        !           894: proctype Euclid(int x, y)
        !           895: {
        !           896:        do
        !           897:        :: (x >  y) -> x = x \- y
        !           898:        :: (x <  y) -> y = y \- x
        !           899:        :: (x == y) -> goto done
        !           900:        od;
        !           901: done:
        !           902:        skip
        !           903: }
        !           904: .P2
        !           905: The
        !           906: .CW goto
        !           907: in this example jumps to a label named
        !           908: .CW done .
        !           909: A label can only appear before a statement.
        !           910: Above we want to jump to the end of the program.
        !           911: In this case a dummy statement
        !           912: .CW skip
        !           913: is useful: it is a place holder that
        !           914: is always executable and has no effect.
        !           915: The
        !           916: .CW goto
        !           917: is also always executable.
        !           918: .PP
        !           919: The following example specifies a filter that receives
        !           920: messages from a channel
        !           921: .CW in
        !           922: and divides them over two channels
        !           923: .CW large
        !           924: and
        !           925: .CW small
        !           926: depending on the values attached.
        !           927: The constant
        !           928: .CW N
        !           929: is defined to be
        !           930: .CW 128
        !           931: and
        !           932: .CW size
        !           933: is defined to be
        !           934: .CW 16
        !           935: in the two macro definitions.
        !           936: .P1 0
        !           937: #define N    128
        !           938: #define size  16
        !           939: .P3
        !           940: 
        !           941: chan in    [size] of { short };
        !           942: chan large [size] of { short };
        !           943: chan small [size] of { short };
        !           944: .P3
        !           945: 
        !           946: proctype split()
        !           947: {      short cargo;
        !           948: 
        !           949:        do
        !           950:        :: in?cargo ->
        !           951:                if
        !           952:                :: (cargo >= N) ->
        !           953:                        large!cargo
        !           954:                :: (cargo <  N) ->
        !           955:                        small!cargo
        !           956:                fi
        !           957:        od
        !           958: }
        !           959: .P3
        !           960: init
        !           961: {      run split()
        !           962: }
        !           963: .P2
        !           964: A process type that merges the two streams back into one, most
        !           965: likely in a different order, and writes it back
        !           966: into the channel
        !           967: .CW in
        !           968: could be specified as follows.
        !           969: .P1 0
        !           970: proctype merge()
        !           971: {      short cargo;
        !           972: 
        !           973:        do
        !           974:        ::      if
        !           975:                :: large?cargo
        !           976:                :: small?cargo
        !           977:                fi;
        !           978:                in!cargo
        !           979:        od
        !           980: }
        !           981: .P2
        !           982: If we now modify the
        !           983: .CW init
        !           984: process as follows, the
        !           985: split and merge processes could busily perform their
        !           986: duties forever on.
        !           987: .P1 0
        !           988: init
        !           989: {      in!345; in!12; in!6777;
        !           990:        in!32;  in!0;
        !           991:        run split();
        !           992:        run merge()
        !           993: }
        !           994: .P2
        !           995: .PP
        !           996: As a final example, consider the following implementation of
        !           997: a Dijkstra semaphore, using binary rendez-vous communication.
        !           998: .P1 0
        !           999: #define p      0
        !          1000: #define v      1
        !          1001: 
        !          1002: chan sema[0] of { bit };
        !          1003: .P3
        !          1004: proctype dijkstra()
        !          1005: {      byte count = 1;
        !          1006: 
        !          1007:        do
        !          1008:        :: (count == 1) \->
        !          1009:                sema!p; count = 0
        !          1010:        :: (count == 0) \->
        !          1011:                sema?v; count = 1
        !          1012:        od      
        !          1013: }
        !          1014: .P3
        !          1015: proctype user()
        !          1016: {      do
        !          1017:        :: sema?p;
        !          1018:           /*     critical section */
        !          1019:           sema!v;
        !          1020:           /* non-critical section */
        !          1021:        od
        !          1022: }
        !          1023: .P3
        !          1024: init
        !          1025: {      run dijkstra();
        !          1026:        run user();
        !          1027:        run user();
        !          1028:        run user()
        !          1029: }
        !          1030: .P2
        !          1031: The semaphore guarantees that only one of the user processes
        !          1032: can enter its critical section at a time.
        !          1033: It does not necessarily prevent the monopolization of
        !          1034: the access to the critical section by one of the processes.
        !          1035: .IH "Modeling Procedures and Recursion"
        !          1036: .PP
        !          1037: Procedures can be modeled as processes, even recursive ones.
        !          1038: The return value can be passed back to the calling process
        !          1039: via a global variable, or via a message.
        !          1040: The following program illustrates this.
        !          1041: .P1 0
        !          1042: proctype fact(int n; chan p)
        !          1043: {      chan child[1] of { int };
        !          1044:        int result;
        !          1045: 
        !          1046:        if
        !          1047:        :: (n <= 1) -> p!1
        !          1048:        :: (n >= 2) ->
        !          1049:                run fact(n-1, child);
        !          1050:                child?result;
        !          1051:                p!n*result
        !          1052:        fi
        !          1053: }
        !          1054: init
        !          1055: {      chan child [1] of { int };
        !          1056:        int result;
        !          1057: 
        !          1058:        run fact(7, child);
        !          1059:        child?result;
        !          1060:        printf("result: %d\n", result)
        !          1061: }
        !          1062: .P2
        !          1063: The process
        !          1064: .I "fact(n, p)"
        !          1065: recursively calculates the factorial of
        !          1066: .I n ,
        !          1067: communicating the result via a message to its parent process
        !          1068: .I p .
        !          1069: .IH "Timeouts"
        !          1070: .PP
        !          1071: We have already discussed two types of statement
        !          1072: with a predefined meaning in \*P:
        !          1073: .CW skip ,
        !          1074: and
        !          1075: .CW break .
        !          1076: Another predefined statement is
        !          1077: .CW timeout .
        !          1078: The
        !          1079: .CW timeout
        !          1080: models a special condition that allows a process to
        !          1081: abort the waiting for a condition that may never become true, e.g.
        !          1082: an input from an empty channel.
        !          1083: The timeout keyword is a modeling feature in \*P that provides an
        !          1084: escape from a hang state.
        !          1085: The timeout condition becomes true only when no other
        !          1086: statements within the distributed system is executable.
        !          1087: Note that we deliberately abstract from absolute timing
        !          1088: considerations, which is crucial in validation work,
        !          1089: and we do not specify how the timeout should be implemented.
        !          1090: A simple example is the following process that will send
        !          1091: a reset message to a channel named \f2guard\f1 whenever the
        !          1092: system comes to a standstill.
        !          1093: .P1 0
        !          1094: proctype watchdog()
        !          1095: {
        !          1096:        do
        !          1097:        :: timeout -> guard!reset
        !          1098:        od
        !          1099: }
        !          1100: .P2
        !          1101: .IH "Assertions"
        !          1102: .PP
        !          1103: Another important language construct in \*P that
        !          1104: needs little explanation is the
        !          1105: .CW assert
        !          1106: statement.
        !          1107: Statements of the form
        !          1108: .P1 0
        !          1109: assert(any_boolean_condition)
        !          1110: .P2
        !          1111: are always executable.
        !          1112: If the boolean condition specified holds, the statement has no effect.
        !          1113: If, however, the condition does not necessarily hold,
        !          1114: the statement will produce an error report during validations with \*s.
        !          1115: .NH 2
        !          1116: More Advanced Usage
        !          1117: .PP
        !          1118: The modeling language has a few features that specifically address
        !          1119: the validation aspects.
        !          1120: It shows up in the way labels are used, in the
        !          1121: semantics of the \*P
        !          1122: .CW timeout
        !          1123: statement, and in the usage of a few
        !          1124: special types of statements, such as
        !          1125: \f(CWassert\f1, \f(CWblock\f1,
        !          1126: and \f(CWhang\f1, that we discuss next.
        !          1127: .NH 3
        !          1128: End-State Labels
        !          1129: .PP
        !          1130: When \*P is used as a validation language the user must
        !          1131: be able to make very specific assertions about the behavior
        !          1132: that is being modeled.
        !          1133: In particular, if a \*P is checked for the presence of
        !          1134: deadlocks, the validator must be able to distinguish a normal \f2end state\f1
        !          1135: from an abnormal one.
        !          1136: .PP
        !          1137: A normal end state could be a state in which every \*P process
        !          1138: that was instantiated has properly reached the end of the
        !          1139: defining program body, and all message channels are empty.
        !          1140: But, not all \*P process are, of course, meant to reach the
        !          1141: end of their program body.
        !          1142: Some may very well linger in an \f(CWIDLE\f1
        !          1143: state, or they may sit patiently in a loop
        !          1144: ready to spring into action when new input arrives.
        !          1145: .PP
        !          1146: To make it clear to the validator that these alternate end states
        !          1147: are legal, and do not constitute a deadlock, a \*P model can use
        !          1148: end state labels.
        !          1149: For instance, if by adding a label to the process type
        !          1150: \f(CWdijkstra()\f1, from section 1.9:
        !          1151: .P1
        !          1152: proctype dijkstra()
        !          1153: {      byte count = 1;
        !          1154: 
        !          1155: end:   do
        !          1156:        :: (count == 1) \->
        !          1157:                sema!p; count = 0
        !          1158:        :: (count == 0) \->
        !          1159:                sema?v; count = 1
        !          1160:        od      
        !          1161: }
        !          1162: .P2
        !          1163: we indicate that it is not an error if, at the end of an
        !          1164: execution sequence, a process of type \f(CWdijkstra()\f1
        !          1165: has not reached its closing curly brace, but waits in the loop.
        !          1166: Of course, such a state could still be part of a deadlock state, but
        !          1167: if so, it is not caused by this particular process.
        !          1168: (It will still be reported if any one of the other processes
        !          1169: in not in a valid end-state).
        !          1170: .PP
        !          1171: There may be more than one end state label per validation model.
        !          1172: If so, all labels that occur within the same process body must
        !          1173: be unique.
        !          1174: The rule is that every label name that \f2starts\f1 with the three
        !          1175: character sequence \f(CW"end"\f1
        !          1176: is an endstate label.
        !          1177: So it is perfectly valid to use variations such as
        !          1178: \f(CWenddne\f1, \f(CWend0\f1, \f(CWend_appel\f1, etc.
        !          1179: .NH 3
        !          1180: Progress-State Labels
        !          1181: .PP
        !          1182: In the same spirit as the end state labels, the user can also
        !          1183: define \f2progress state\f1 labels.
        !          1184: In this case, a progress state labels will mark a state that
        !          1185: \f2must\f1 be executed for the protocol to make progress.
        !          1186: Any infinite cycle in the protocol execution that does not
        !          1187: pass through at least one of these progress states, is a
        !          1188: potential starvation loop.
        !          1189: In the
        !          1190: .CW dijkstra
        !          1191: example, for instance, we can label the
        !          1192: successful passing of a semaphore test as ``progress'' and
        !          1193: ask a validator to make sure that there is no cycle in the
        !          1194: protocol execution where at least one process succeeds in
        !          1195: passing the semaphore guard.
        !          1196: If more than one state carries a progress label,
        !          1197: variations with a common prefix are again valid:
        !          1198: \f(CWprogress0\f1, \f(CWprogress_foo\f1, etc.
        !          1199: .KF
        !          1200: .P1
        !          1201: proctype dijkstra()
        !          1202: {      byte count = 1;
        !          1203: 
        !          1204: end:   do
        !          1205:        :: (count == 1) ->
        !          1206: progress:      sema!p; count = 0
        !          1207:        :: (count == 0) ->
        !          1208:                sema?v; count = 1
        !          1209:        od      
        !          1210: }
        !          1211: .P2
        !          1212: .KE
        !          1213: .PP
        !          1214: .CW "spin -a"
        !          1215: generates analyzers that support (after compilation) a
        !          1216: .CW -l
        !          1217: option, which makes the analyzer use a fast search for non-progress loops,
        !          1218: instead of the default search for deadlocks.
        !          1219: The
        !          1220: .CW -l
        !          1221: search completely avoids the expense of a
        !          1222: full construction of all strongly
        !          1223: connected components in the reachability graph
        !          1224: (the conventional method for doing loop analysis).
        !          1225: The expense is therefore never more than about
        !          1226: twice the time and memory requirements of
        !          1227: a default search for deadlocks.
        !          1228: .IH "Message Type Definitions"
        !          1229: .PP
        !          1230: We have seen how variables are declared and how constants
        !          1231: can be defined using C-style macros.
        !          1232: As a mild form of syntactic sugar, \*P also allows for
        !          1233: message type definitions that look as follows:
        !          1234: .P1 0
        !          1235: mtype = {
        !          1236:        ack, nak, err,
        !          1237:        next, accept
        !          1238: }
        !          1239: .P2
        !          1240: This is a preferred way of specifying the message types since
        !          1241: it abstracts from the specific values to be used, and it makes
        !          1242: the names of the constants available to an implementation,
        !          1243: which can improve error reporting.
        !          1244: .IH "Pseudo Statements"
        !          1245: .PP
        !          1246: We have now discussed all the basic types of statements defined in \*P:
        !          1247: assignments, conditions, send and receive,
        !          1248: .CW assert ,
        !          1249: .CW timeout ,
        !          1250: .CW goto ,
        !          1251: .CW break
        !          1252: and
        !          1253: .CW skip .
        !          1254: Note that
        !          1255: .CW chan ,
        !          1256: .CW len 
        !          1257: and
        !          1258: .CW run
        !          1259: are not really statements but unary operators that can be used in
        !          1260: conditions and assignments.
        !          1261: .PP
        !          1262: The
        !          1263: .CW skip
        !          1264: statement was mentioned in passing as a statement that can be
        !          1265: a useful filler to satisfy syntax requirements, but that really
        !          1266: has no effect.
        !          1267: It is formally not part of the language but a \f2pseudo-statement\f1,
        !          1268: merely a synonym of another statement with the same effect: a
        !          1269: simple condition of a constant value
        !          1270: .CW (1) .
        !          1271: In the same spirit two other pseudo-statements are predefined.
        !          1272: They are called
        !          1273: .CW block
        !          1274: and
        !          1275: .CW halt .
        !          1276: The first is a stop statement that is never executable: the
        !          1277: opposite of
        !          1278: .CW skip .
        !          1279: It is modeled as another condition
        !          1280: .CW (0) .
        !          1281: The
        !          1282: .CW halt
        !          1283: statement aborts the execution of the system of processes
        !          1284: whenever it is executed.
        !          1285: It is equivalent to an assertion that will always fail:
        !          1286: .CW assert(0) .
        !          1287: .IH Example
        !          1288: .PP
        !          1289: Here is a simple example of a (flawed) protocol, modeled in \*P.
        !          1290: .P1 0
        !          1291: mtype = {
        !          1292:        ack, nak, err, next, accept
        !          1293: }
        !          1294: 
        !          1295: .P3
        !          1296: proctype transfer(chan in,out,chin,chout)
        !          1297: {      byte o, i;
        !          1298: 
        !          1299:        in?next(o);
        !          1300: .P3
        !          1301:        do
        !          1302:        :: chin?nak(i) ->
        !          1303:                        out!accept(i);
        !          1304:                        chout!ack(o)
        !          1305: .P3
        !          1306:        :: chin?ack(i) ->
        !          1307:                        out!accept(i);
        !          1308:                        in?next(o);
        !          1309:                        chout!ack(o)
        !          1310: .P3
        !          1311:        :: chin?err(i) ->
        !          1312:                        chout!nak(o)
        !          1313:        od
        !          1314: }
        !          1315: 
        !          1316: .P3
        !          1317: init
        !          1318: {      chan AtoB[1] of { byte, byte };
        !          1319:        chan BtoA[1] of { byte, byte };
        !          1320: .P3
        !          1321:        chan Ain [2] of { byte };
        !          1322:        chan Bin [2] of { byte };
        !          1323: .P3
        !          1324:        chan Aout[2] of { byte };
        !          1325:        chan Bout[2] of { byte };
        !          1326: .P3
        !          1327:        atomic {
        !          1328:          run transfer(Ain,Aout, AtoB,BtoA);
        !          1329:          run transfer(Bin,Bout, BtoA,AtoB)
        !          1330:        };
        !          1331: .P3
        !          1332:        AtoB!err(0)
        !          1333: }
        !          1334: .P2
        !          1335: The channels
        !          1336: .CW Ain
        !          1337: and
        !          1338: .CW Bin
        !          1339: are to be filled with
        !          1340: token messages of type
        !          1341: .CW next
        !          1342: and arbitrary values (e.g.
        !          1343: ASCII character values) by unspecified background processes:
        !          1344: the users of the transfer service.
        !          1345: Similarly, these user processes
        !          1346: can read received data from the channels
        !          1347: .CW Aout
        !          1348: and
        !          1349: .CW Bout .
        !          1350: The channels and processes are initialized in a single
        !          1351: atomic statement, and started with the dummy
        !          1352: .CW err
        !          1353: message.
        !          1354: .NH
        !          1355: Introduction to Spin
        !          1356: .PP
        !          1357: Given a model system specified in \*P, \*s
        !          1358: can either perform random simulations of the system's execution
        !          1359: or it can generate a C program that performs a fast exhaustive
        !          1360: validation of the system state space.
        !          1361: The validator can check, for instance, if user specified system
        !          1362: invariants may be violated during a protocol's execution.
        !          1363: .PP
        !          1364: If \*s is invoked without any options it performs a random simulation.
        !          1365: With option
        !          1366: .CW -n\fIN
        !          1367: the seed for the simulation is set explicitly to the integer value
        !          1368: .I N .
        !          1369: .PP
        !          1370: The options
        !          1371: .CW pglrs
        !          1372: controls the amount of information output from the simulation run.
        !          1373: Every line of output normally contains a reference to the source
        !          1374: line in the specification that caused it.
        !          1375: .IP \f(CW-p\f1
        !          1376: Shows the state changes of the \*P
        !          1377: processes at every time step.
        !          1378: .IP \f(CW-g\f1
        !          1379: Shows the current value of global variables at every time step.
        !          1380: .IP \f(CW-l\f1
        !          1381: Shows the current value of local variables, after the
        !          1382: process that owns them has changed state.
        !          1383: It is best used in combination with option
        !          1384: .CW -p .
        !          1385: .IP \f(CW-r\f1
        !          1386: Shows all message receive events.
        !          1387: It shows the process performing the receive, its name and number,
        !          1388: the source line number, the message parameter number (there is
        !          1389: one line for each parameter), the message type and the message
        !          1390: channel number and name.
        !          1391: .IP \f(CW-s\f1
        !          1392: Shows all message send events.
        !          1393: .LP
        !          1394: \*S understands four other options:
        !          1395: .IP \f(CW-a\f1
        !          1396: Generates a protocol specific analyzer.
        !          1397: The output is written into a set of C files, named
        !          1398: .CW pan.[cbhmt] ,
        !          1399: that can be compiled to produce the analyzer
        !          1400: (which is then executed to perform the analysis).
        !          1401: To guarantee an exhaustive exploration of the state space, the
        !          1402: program can be compiled simply as
        !          1403: .RS
        !          1404: .IP
        !          1405: .P1
        !          1406: $ cc -o run pan.c
        !          1407: .P2
        !          1408: .RE
        !          1409: .IP
        !          1410: For larger systems this may, however, exhaust the available memory
        !          1411: on the machine used.
        !          1412: Large to very large systems can still be analyzed by using a
        !          1413: memory efficient bit state space method by
        !          1414: .RS
        !          1415: .IP
        !          1416: .P1
        !          1417: $ cc -DBITSTATE -o run pan.c
        !          1418: .P2
        !          1419: .RE
        !          1420: .IP
        !          1421: An indication of the coverage of such a search can be derived from the
        !          1422: .I "hash factor"
        !          1423: (see below).
        !          1424: The generated executable analyzer, named
        !          1425: .CW run
        !          1426: above, has its own set of options that can be seen by typing
        !          1427: .CW "run -?"
        !          1428: (see also below in ``The Analyzer'').
        !          1429: .IP \f(CW-m\f1
        !          1430: can be used to change the default semantics of send actions.
        !          1431: Normally, a send operation is only executable if the target channel
        !          1432: is non-full.
        !          1433: This imposes an implicit synchronization that can not always
        !          1434: be justified.
        !          1435: Option \f(CW-m\f1 causes send actions to be always executable.
        !          1436: Messages sent to a channel that is full are then dropped.
        !          1437: If this option is combined with \f(CW-a\f1 the semantics of send
        !          1438: in the analyzers generated is similarly altered, and the validations
        !          1439: will take the effects of this type of message loss into consideration.
        !          1440: .IP \f(CW-q\f1
        !          1441: causes \*s to peruse the model for obviously atomicable
        !          1442: sequences, and to label them appropriately, in an effort to
        !          1443: reduce the complexity of large validation runs.
        !          1444: Typically, the user can do better by hand (by being more
        !          1445: daring than \*s can be in this case).
        !          1446: .IP \f(CW-t\f1
        !          1447: is a trail-hunting option.
        !          1448: If the analyzer finds a violation of an assertion, a deadlock or
        !          1449: an unspecified reception, it writes an error trail into a file
        !          1450: named
        !          1451: .CW pan.trail .
        !          1452: The trail can be inspected in detail by invoking \*s with the
        !          1453: .CW -t
        !          1454: option.
        !          1455: In combination with the options
        !          1456: .CW pglrs
        !          1457: different views of the error sequence are then easily obtained.
        !          1458: .PP
        !          1459: For brevity, other features of \*s are not discussed here.
        !          1460: For details see|reference(holzmann spinbook), for a hint of
        !          1461: what else is available, see ``Digging Deeper'' at the end of this manual.
        !          1462: .IH "The Simulator"
        !          1463: .PP
        !          1464: Consider the following example protocol, that we will store in a
        !          1465: file named
        !          1466: .CW lynch .
        !          1467: .P1 0
        !          1468:    1  #define MIN      9
        !          1469:    2  #define MAX      12
        !          1470:    3  #define FILL     99
        !          1471:    4  
        !          1472:    5  mtype = { ack, nak, err }
        !          1473:    6  
        !          1474: .P3
        !          1475:    7  proctype transfer(chan chin, chout)
        !          1476:    8  {        byte o, i, last_i=MIN;
        !          1477:    9  
        !          1478:   10   o = MIN+1;
        !          1479: .P3
        !          1480:   11   do
        !          1481:   12   :: chin?nak(i) ->
        !          1482:   13           assert(i == last_i+1);
        !          1483:   14           chout!ack(o)
        !          1484: .P3
        !          1485:   15   :: chin?ack(i) ->
        !          1486:   16           if
        !          1487:   17           :: (o <  MAX) -> o = o+1
        !          1488:   18           :: (o >= MAX) -> o = FILL
        !          1489:   19           fi;
        !          1490:   20           chout!ack(o)
        !          1491: .P3
        !          1492:   21   :: chin?err(i) ->
        !          1493:   22           chout!nak(o)
        !          1494:   23   od
        !          1495:   24  }
        !          1496:   25  
        !          1497: .P3
        !          1498:   26  proctype channel(chan in, out)
        !          1499:   27  {        byte md, mt;
        !          1500:   28   do
        !          1501:   29   :: in?mt,md ->
        !          1502:   30           if
        !          1503:   31           :: out!mt,md
        !          1504:   32           :: out!err,0
        !          1505:   33           fi
        !          1506:   34   od
        !          1507:   35  }
        !          1508:   36  
        !          1509: .P3
        !          1510:   37  init
        !          1511:   38  {        chan AtoB[1] of { byte, byte };
        !          1512:   39   chan BtoC[1] of { byte, byte };
        !          1513:   40   chan CtoA[1] of { byte, byte };
        !          1514:   41   atomic {
        !          1515:   42           run transfer(AtoB, BtoC);
        !          1516:   43           run channel(BtoC, CtoA);
        !          1517:   44           run transfer(CtoA, AtoB)
        !          1518:   45   };
        !          1519:   46   AtoB!err,0;     /* start */
        !          1520:   47   hang
        !          1521:   48  }
        !          1522: .P2
        !          1523: The protocol uses three message types: \f2ack\f1, \f2nak\f1, and
        !          1524: a special type \f2err\f1 that is used to model message distortions
        !          1525: on the communication channel between the two transfer processes.
        !          1526: The behavior of the channel is modeled explicitly with a channel
        !          1527: process.
        !          1528: There is also an
        !          1529: .CW assert
        !          1530: statement that claims a (faulty) invariant
        !          1531: relation between two local variables in the transfer processes.
        !          1532: .PP
        !          1533: Running \*s without options gives us a random simulation that
        !          1534: will only provide output when execution terminates, or if
        !          1535: a \f2printf\f1 statement is encountered.
        !          1536: In this case:
        !          1537: .P1 0
        !          1538: $ spin lynch
        !          1539: spin: "lynch" line 13: assertion violated
        !          1540: #processes: 4
        !          1541: proc  3 (transfer)     line 11 (state 15)
        !          1542: proc  2 (channel)      line 28 (state 6)
        !          1543: proc  1 (transfer)     line 13 (state 3)
        !          1544: proc  0 (:init:)       line 48 (state 6)
        !          1545: 4 processes created
        !          1546: $ 
        !          1547: .P2
        !          1548: There are no \f2printf\f1's in the specification, but execution
        !          1549: halts on an assertion violation.
        !          1550: Curious to find out more, we can repeat the run with more verbose
        !          1551: output, e.g. printing all receive events.
        !          1552: The result of that run is shown in Figure 1.
        !          1553: Most output will be self-explanatory.
        !          1554: .PP
        !          1555: The above simulation run ends in the same assertion violation.
        !          1556: Since the simulation resolves nondeterministic choices in a
        !          1557: random manner, this need not always be the case.
        !          1558: To force a reproducible run, the option
        !          1559: .CW -n\fIN
        !          1560: can be used.
        !          1561: For instance:
        !          1562: .P1 0
        !          1563: $ spin -r -n100 lynch
        !          1564: .P2
        !          1565: will seed the random number generator with the integer value 100
        !          1566: and is guaranteed to produce the same output each time it is executed.
        !          1567: .PP
        !          1568: The other options can add still more output to the simulation run,
        !          1569: but the amount of text can quickly become overwhelming.
        !          1570: An easy solution is to filter the output through \f2grep\f1.
        !          1571: For instance, if we are only interested in the behavior of the
        !          1572: channel process in the above example, we say:
        !          1573: .P1 0
        !          1574: $ spin -n100 -r lynch | grep "proc  2"
        !          1575: .P2
        !          1576: The results are shown in Figure 1.
        !          1577: .1C
        !          1578: .KF
        !          1579: .nf
        !          1580: .ps -2
        !          1581: .vs -3p
        !          1582: .ft CW
        !          1583: .TS
        !          1584: box expand;
        !          1585: l
        !          1586: l.
        !          1587:       $ spin -r lynch
        !          1588:       proc  1 (transfer) line  21, Recv err,0  <- queue 1 (chin)
        !          1589:       proc  2 (channel)  line  29, Recv nak,10 <- queue 2 (in)
        !          1590:       proc  3 (transfer) line  12, Recv nak,10 <- queue 3 (chin)
        !          1591:       proc  1 (transfer) line  15, Recv ack,10 <- queue 1 (chin)
        !          1592:       \&...
        !          1593:       proc  1 (transfer) line  15, Recv ack,12 <- queue 1 (chin)
        !          1594:       proc  2 (channel)  line  29, Recv ack,99 <- queue 2 (in)
        !          1595:       proc  3 (transfer) line  15, Recv ack,99 <- queue 3 (chin)
        !          1596:       proc  1 (transfer) line  15, Recv ack,99 <- queue 1 (chin)
        !          1597:       proc  2 (channel)  line  29, Recv ack,99 <- queue 2 (in)
        !          1598:       proc  3 (transfer) line  21, Recv err,0  <- queue 3 (chin)
        !          1599:       proc  1 (transfer) line  12, Recv nak,99 <- queue 1 (chin)
        !          1600:       spin: "lynch" line 13: assertion violated
        !          1601:       #processes: 4
        !          1602:       proc  3 (transfer) line 11 (state 15)
        !          1603:       proc  2 (channel)  line 28 (state 6)
        !          1604:       proc  1 (transfer) line 13 (state 3)
        !          1605:       proc  0 (:init:)   line 48 (state 6)
        !          1606:       4 processes created
        !          1607:       $ spin -n100 -r lynch | grep "proc  2"
        !          1608:       proc  2 (channel) line 29, Recv nak,10 <- queue 2 (in)
        !          1609:       proc  2 (channel) line 29, Recv ack,11 <- queue 2 (in)
        !          1610:       proc  2 (channel) line 29, Recv ack,12 <- queue 2 (in)
        !          1611:       proc  2 (channel) line 28 (state 6)
        !          1612: .TE
        !          1613: .fi
        !          1614: .ps +2
        !          1615: .vs +3p
        !          1616: .SP .5
        !          1617: .ce
        !          1618: \fBFigure 1.\fR  Simulation Run Output
        !          1619: .SP .5
        !          1620: .KE
        !          1621: .2C
        !          1622: ......
        !          1623: .IH "The Analyzer"
        !          1624: .PP
        !          1625: The simulation runs can be useful in quick debugging of
        !          1626: new designs, but by simulation alone we can not prove
        !          1627: that the system is really error free.
        !          1628: A validation of even very large models can be performed with the
        !          1629: .CW -a
        !          1630: and
        !          1631: .CW -t
        !          1632: options of \*s.
        !          1633: .PP
        !          1634: An exhaustive state space searching program for a protocol
        !          1635: model is generated as follows, producing five files, named \f2pan.[bchmt]\f1.
        !          1636: .P1 0
        !          1637: $ spin -a lynch
        !          1638: .P3
        !          1639: $ wc pan.[bchmt]
        !          1640: .P3
        !          1641:      92     326    2041 pan.b
        !          1642: .P3
        !          1643:     854    2502   17524 pan.c
        !          1644: .P3
        !          1645:     147     576    3475 pan.h
        !          1646: .P3
        !          1647:     307    1230    7493 pan.m
        !          1648: .P3
        !          1649:     177     548    3997 pan.t
        !          1650: .P3
        !          1651:    1577    5182   34530 total
        !          1652: .P2
        !          1653: The details are none too interesting: \f2pan.c\f1 contains
        !          1654: most of the C code for the analysis of the protocol.
        !          1655: File \f2pan.t\f1 contains a transition matrix that encodes
        !          1656: the protocol control flow; \f2pan.b\f1 and \f2pan.m\f1 contain
        !          1657: C code for forward and backward transitions and
        !          1658: \f2pan.h\f1 is a general header file.
        !          1659: The program can be compiled in two different ways: with a full
        !          1660: state space or with a bit state space.
        !          1661: .IH "Exhaustive Search"
        !          1662: .PP
        !          1663: The best method, that works up to system state spaces of
        !          1664: roughly 100,000 states, is to use the
        !          1665: default compilation of the program:
        !          1666: .P1 0
        !          1667: $ cc -o run pan.c
        !          1668: .P2
        !          1669: The executable program \f2run\f1 can now be executed to perform
        !          1670: the validation.
        !          1671: The validation is truly exhaustive: it tests all possible
        !          1672: event sequences in all possible orders.
        !          1673: It should, of course, find the same assertion violation.
        !          1674: .P1 0
        !          1675: $ run
        !          1676: assertion violated (i == last_i + 1))
        !          1677: pan: aborted
        !          1678: pan: wrote pan.trail
        !          1679: search interrupted
        !          1680: vector 64 byte, depth reached 56
        !          1681:       61 states, stored
        !          1682:        5 states, linked
        !          1683:        1 states, matched
        !          1684: hash conflicts: 0 (resolved)
        !          1685: (size 2^18 states, stack frames: 0/5)
        !          1686: .P2
        !          1687: The first line of the output announces the assertion violation
        !          1688: and attempts to give a first indication of the invariant that
        !          1689: was violated.
        !          1690: The violation was found after 61 states had been generated.
        !          1691: Hash "conflicts" gives the number
        !          1692: of hash collisions that happened during access to the state space.
        !          1693: As indicated,
        !          1694: all collisions are resolved in full search mode, since all states are
        !          1695: placed in a linked list.
        !          1696: The most relevant piece of output in this case, however, is on the
        !          1697: third line which tells us that a trail file was created that can
        !          1698: be used in combination with the simulator to recreate the error
        !          1699: sequence.
        !          1700: We can now say, for instance
        !          1701: .P1 0
        !          1702: $ spin -t -r lynch | grep "proc  2"
        !          1703: .P2
        !          1704: to determine the cause of the error.
        !          1705: Note carefully that the validator is guaranteed to find the
        !          1706: assertion violation if it is feasible.
        !          1707: If an exhaustive search does not report such a violation, it is
        !          1708: certain that \f2no\f1 execution execution sequence exists that can
        !          1709: violate the assertion.
        !          1710: .IH Options
        !          1711: .PP
        !          1712: The executable analyzer that is generated comes with a modest
        !          1713: number of options that can be checked as follows
        !          1714: .P1 0
        !          1715: $ run -?
        !          1716: -cN stop at Nth error (default=1)
        !          1717: -l  find non-progress loops
        !          1718: -mN max depth N (default=10k)
        !          1719: -wN hash table of 2^N entries (default=18)
        !          1720: .P2
        !          1721: Using a zero as an argument to the first option
        !          1722: forces the state space search to continue,
        !          1723: even if errors are found.
        !          1724: An overview of unexecutable (unreachable) code is given with every
        !          1725: complete run: either the default run if it did not find any
        !          1726: errors, or the run with option
        !          1727: .CW -c0 .
        !          1728: In this case the output is:
        !          1729: .P1 0
        !          1730: $ run -c0
        !          1731: assertion violated (i == (last_i + 1))
        !          1732: assertion violated (i == (last_i + 1))
        !          1733: assertion violated (i == (last_i + 1))
        !          1734: assertion violated (i == (last_i + 1))
        !          1735: assertion violated (i == (last_i + 1))
        !          1736: .P3
        !          1737: vector 64 byte, depth reached 60, errors: 5
        !          1738:      165 states, stored
        !          1739:        5 states, linked
        !          1740:       26 states, matched
        !          1741: hash conflicts: 1 (resolved)
        !          1742: (size 2^18 states, stack frames: 0/6)
        !          1743: 
        !          1744: unreached code :init: (proc 0):
        !          1745:        reached all 9 states
        !          1746: unreached code channel (proc 1):
        !          1747:         line 35 (state 9),
        !          1748:        reached: 8 of 9 states
        !          1749: unreached code transfer (proc 2):
        !          1750:         line 24 (state 18),
        !          1751:        reached: 17 of 18 states
        !          1752: .P2
        !          1753: There were five assertion violations, and some 165 unique
        !          1754: system states were generated.
        !          1755: Each state description (the \f2vector size\f1) took up 64 bytes
        !          1756: of memory; the longest non-cyclic execution sequence was 60.
        !          1757: There is one unreachable state both in the channel process and in
        !          1758: the transfer process.
        !          1759: In both cases the unreachable state is the control flow point
        !          1760: just after the do-loop in each process.
        !          1761: Note that both loops are indeed meant to be non-terminating.
        !          1762: .PP
        !          1763: The \f(CW-l\f1 option will cause the analyzer to search for
        !          1764: non-progress loops rather than deadlocks or assertion violations.
        !          1765: The option is explained in the section on ``More Advanced Usage.''
        !          1766: .PP
        !          1767: The executable analyzer has two other options.
        !          1768: By default the search depth is restricted to a rather
        !          1769: arbitrary 10,000 steps.
        !          1770: If the depth limit is reached, the search is truncated, making
        !          1771: the validation less than exhaustive.
        !          1772: To make certain that the search is exhaustive, make sure that the
        !          1773: "depth reached" notice is within the maximum search depth, and
        !          1774: if not, repeat the analysis with an explicit
        !          1775: .CW -m
        !          1776: argument.
        !          1777: .PP
        !          1778: The
        !          1779: .CW -m
        !          1780: option can of course also be used to truncate
        !          1781: the search explicitly, in an effort to find the shortest possible
        !          1782: execution sequence that violates a given assertion.
        !          1783: Such a truncated search, however, is not guaranteed to find every
        !          1784: possible violation, even within the search depth.
        !          1785: .PP
        !          1786: The last option
        !          1787: .CW -w\fIN
        !          1788: can only affect the run time, not
        !          1789: the scope, of an analysis with a full state space.
        !          1790: This "hash table width" should normally be set equal to,
        !          1791: or preferably higher than,
        !          1792: the logarithm of the expected number of unique system states generated
        !          1793: by the analyzer.
        !          1794: (If it is set too low, the number of hash collisions will increase
        !          1795: and slow down the search.)
        !          1796: The default
        !          1797: .I N
        !          1798: of 18 handles up to 262,144 system states, which should
        !          1799: suffice for almost all applications of a full state space analysis.
        !          1800: .IH "Bit State Space Analysis"
        !          1801: .PP
        !          1802: It can easily be calculated what the memory requirements of an analysis
        !          1803: with a full state space are|reference(holzmann atttj).
        !          1804: If, as in the example we have used, the protocol requires 64 bytes
        !          1805: of memory to encode one system state, and we have a total of 2MB
        !          1806: of memory available for the search, we can store up to 32,768 states.
        !          1807: The analysis fails if there are more reachable states in the
        !          1808: system state space.
        !          1809: So far, \*s is the \f2only\f1 validation system that can avoid this trap.
        !          1810: All other existing automated validation system (irrespective on
        !          1811: which formalism they are based) simply run out of memory and
        !          1812: abort their analysis without returning a useful answer to the user.
        !          1813: .PP
        !          1814: The coverage of a conventional analysis goes down rapidly when
        !          1815: the memory limit is hit, i.e. if there are
        !          1816: twice as many states in the full state space than we can store,
        !          1817: the effective coverage of the search is only 50% and so on.
        !          1818: \*S does substantially better in those cases by using the bit state
        !          1819: space storage method|reference(holzmann atttj).
        !          1820: The bit state space can be included by compiling the analyzer as follows:
        !          1821: .P1 0
        !          1822: $ cc -DBITSTATE -o run pan.c
        !          1823: .P2
        !          1824: The analyzer compiled in this way
        !          1825: should of course find the same assertion violation again:
        !          1826: .P1 0
        !          1827: $ run
        !          1828: assertion violated (i == ((last_i + 1))
        !          1829: pan: aborted
        !          1830: pan: wrote pan.trail
        !          1831: search interrupted
        !          1832: vector 64 byte, depth reached 56
        !          1833:       61 states, stored
        !          1834:        5 states, linked
        !          1835:        1 states, matched
        !          1836: hash factor: 67650.064516
        !          1837: (size 2^22 states, stack frames: 0/5)
        !          1838: $ 
        !          1839: .P2
        !          1840: In fact, for small to medium size problems there is very little
        !          1841: difference between the full state space method and the bit state
        !          1842: space method (with the exception that the latter is somewhat
        !          1843: faster and uses substantially less memory).
        !          1844: The big difference comes for larger problems.
        !          1845: The last two lines in the output are useful in estimating
        !          1846: the \f2coverage\f1 of a large run.
        !          1847: The maximum number of states that the bit state space can
        !          1848: accommodate is written on the last line (here @2 sup 22@ bytes or about 32 million
        !          1849: bits = states).
        !          1850: The line above it gives the \f2hash factor\f1: roughly
        !          1851: equal to the maximum number of states divided by the actual
        !          1852: number of states.
        !          1853: A large hash factor (larger than 100) means, with high reliability,
        !          1854: a coverage of 99% or 100%.
        !          1855: As the hash factor approaches 1 the coverage approaches 0%.
        !          1856: .PP
        !          1857: Note carefully that the analyzer realizes a partial coverage \f2only\f1
        !          1858: in cases where traditional validators are either unable to perform a
        !          1859: search, or realize a far smaller coverage.
        !          1860: In \f2no\f1 case will \*s produce an answer that is less reliable than
        !          1861: that produced by other automated validation systems (quite on the contrary).
        !          1862: .PP
        !          1863: The object of a bit state validation is to achieve a hash factor
        !          1864: larger than 100 by allocating the maximum amount of memory
        !          1865: for the bit state space.
        !          1866: For the best result obtainable: use the
        !          1867: .CW -w\fIN
        !          1868: option to size the state space to precisely the amount
        !          1869: of real (not virtual) memory available on your machine.
        !          1870: By default,
        !          1871: .I N
        !          1872: is 22, corresponding to a state space of 4MB.
        !          1873: For example, if your machine has 128MB of real memory, you can use
        !          1874: .CW -w27
        !          1875: to analyze systems with up to a billion reachable states.
        !          1876: .SP 2
        !          1877: .NH
        !          1878: \*P Reference Manual
        !          1879: .PP
        !          1880: This section describes the language \*P proper.
        !          1881: As much as possible, the presentation follows the example
        !          1882: from the
        !          1883: .CW C
        !          1884: reference manuals|reference(cbook).
        !          1885: It does not cover possible restrictions or extensions of
        !          1886: specific implementations.
        !          1887: The current implementation of \*s, for instance,
        !          1888: has an extra keyword
        !          1889: .CW printf ,
        !          1890: to access the corresponding
        !          1891: .UX
        !          1892: library function.
        !          1893: .IH "Lexical Conventions"
        !          1894: .PP
        !          1895: There are five classes of tokens: identifiers, keywords, constants,
        !          1896: operators and statement separators.
        !          1897: Blanks, tabs, newlines, and comments serve only to separate tokens.
        !          1898: If more than one interpretation is possible, a token is
        !          1899: taken to be the longest string of characters that can
        !          1900: constitute a token.
        !          1901: .ix lexical conventions
        !          1902: .ix tokens
        !          1903: .IH Comments
        !          1904: .PP
        !          1905: Any string started with
        !          1906: .CW /*
        !          1907: and terminated with
        !          1908: .CW */
        !          1909: is a comment.
        !          1910: Comments may not be nested.
        !          1911: .ix comments
        !          1912: .IH Identifiers
        !          1913: .PP
        !          1914: An identifier is a single letter, period, or underscore
        !          1915: followed by zero or more letters, digits, periods, or underscores.
        !          1916: .ix identifiers
        !          1917: .IH Keywords
        !          1918: .PP
        !          1919: The following identifiers are reserved for use as keywords:
        !          1920: .ix keywords
        !          1921: .KS
        !          1922: .ft CW
        !          1923: .ps -1
        !          1924: .vs -1
        !          1925: .TS
        !          1926: center;
        !          1927: l l l.
        !          1928: assert bit     block
        !          1929: bool   break   byte
        !          1930: chan   do      fi
        !          1931: goto   halt    if
        !          1932: init   int     len
        !          1933: mtype  od      of
        !          1934: proctype       run     short
        !          1935: skip   timeout
        !          1936: .ps +1
        !          1937: .vs +1
        !          1938: .TE
        !          1939: .KE
        !          1940: .IH Constants
        !          1941: .PP
        !          1942: A constant is a sequence of digits representing a decimal integer.
        !          1943: There are no floating point numbers in \*P.
        !          1944: .ix constants
        !          1945: Symbolic names for constants can be defined in two ways.
        !          1946: The first method is to use a C-style macro definition
        !          1947: .P1 0
        !          1948: #define        NAME    value
        !          1949: .P2
        !          1950: The second method is to use the keyword
        !          1951: .CW mtype
        !          1952: (see ``declarations'' below).
        !          1953: .IH Expressions
        !          1954: .PP
        !          1955: The following operators can be used to build expressions.
        !          1956: .ix expressions
        !          1957: .ix operators
        !          1958: .KS
        !          1959: .TS
        !          1960: center;
        !          1961: lFCW.
        !          1962: + \- * \/ %
        !          1963: > >= < <= == != !
        !          1964: && ||
        !          1965: & | ~ >> <<
        !          1966: .TE
        !          1967: .KE
        !          1968: .PP
        !          1969: Most operators are binary.
        !          1970: The logical negation \f2!\f1 and the minus \f2\-\f1
        !          1971: operator can be both unary and binary, depending on context.
        !          1972: Expressions are used, for instance, in assignments of the type
        !          1973: .CW "a = expression" ,
        !          1974: with
        !          1975: .CW a
        !          1976: a variable.
        !          1977: .ix assignment
        !          1978: There is also one unary operator that applies to message channels:
        !          1979: .P1 0
        !          1980: len
        !          1981: .P2
        !          1982: It measures the number of messages an existing channel holds.
        !          1983: There is one unary operator that is used for process instantiations:
        !          1984: .P1 0
        !          1985: run
        !          1986: .P2
        !          1987: And, finally, there are two binary operators
        !          1988: .P1 0
        !          1989: ! ?
        !          1990: .P2
        !          1991: which are used for sending and receiving messages (see below).
        !          1992: .IH Declarations
        !          1993: .PP
        !          1994: .ix declarations
        !          1995: Processes, channels, and variables must be declared before they can be used.
        !          1996: Variables and channels can be declared either locally,
        !          1997: within a process, or globally.
        !          1998: A process can only be declared globally in a
        !          1999: .CW proctype
        !          2000: declaration.
        !          2001: Local declarations may appear anywhere in a process body.
        !          2002: .IH Variables
        !          2003: .PP
        !          2004: .ix variables
        !          2005: .ix local variables
        !          2006: .ix global variables
        !          2007: .ix initializers
        !          2008: A variable declaration is started by a keyword indicating the
        !          2009: basic data type of the variable,
        !          2010: .CW bit ,
        !          2011: .CW bool ,
        !          2012: .CW byte ,
        !          2013: .CW short ,
        !          2014: or
        !          2015: .CW int ,
        !          2016: followed
        !          2017: by one or more identifiers, optionally followed by
        !          2018: an initializer.
        !          2019: .P1 0
        !          2020: byte name1, name2 = 4, name3
        !          2021: .P2
        !          2022: By default all variables are initialized to zero.
        !          2023: An initializer, if specified, must be a constant.
        !          2024: The table below summarizes the width and attributes of each
        !          2025: basic data type.
        !          2026: .KS
        !          2027: .ps -1
        !          2028: .vs -2
        !          2029: .TS
        !          2030: center;
        !          2031: l l l
        !          2032: lFCW n r.
        !          2033: =
        !          2034: Name   Size (bits)     Usage
        !          2035: _
        !          2036: bit    1       unsigned
        !          2037: bool   1       unsigned
        !          2038: byte   8       unsigned
        !          2039: short  16      signed
        !          2040: int    32      signed
        !          2041: _
        !          2042: .TE
        !          2043: .ps +1
        !          2044: .vs +2
        !          2045: .KE
        !          2046: The names \f2bit\f1 and \f2bool\f1
        !          2047: are synonyms for a single bit of
        !          2048: information.
        !          2049: A \f2byte\f1 is an unsigned quantity that can store a value between
        !          2050: 0 and 255.
        !          2051: \f2Short\f1s and \f2int\f1s are signed quantities that
        !          2052: differ only in the range of values they can hold.
        !          2053: .PP
        !          2054: An array of variables is declared as follows:
        !          2055: .P1 0
        !          2056: int name1[N]
        !          2057: .P2
        !          2058: where
        !          2059: .CW N
        !          2060: is a constant.
        !          2061: An array can have a just a single constant as an initializer.
        !          2062: If specified it is used to initialize all elements of the array.
        !          2063: .PP
        !          2064: Symbolic names for constants, e.g. message types,
        !          2065: can, optionally, be defined in a declaration
        !          2066: of the type
        !          2067: .P1 0
        !          2068: mtype = { namelist }
        !          2069: .P2
        !          2070: where
        !          2071: .CW namelist
        !          2072: is a comma separated list of symbolic names.
        !          2073: .IH "Message Channels"
        !          2074: .PP
        !          2075: A message channel can be declared, for instance, as follows:
        !          2076: .ix channels
        !          2077: .P1 0
        !          2078: chan name[N] of { short, short }
        !          2079: .P2
        !          2080: where
        !          2081: .CW N
        !          2082: is a constant that specifies the maximum number of messages
        !          2083: that can be stored in the channel.
        !          2084: A list of one or more data types (or the channel type
        !          2085: .CW chan )
        !          2086: enclosed in curly braces defines the type of the messages that can
        !          2087: be passed through the channel.
        !          2088: All channels are initialized to be empty.
        !          2089: .IH Processes
        !          2090: .PP
        !          2091: .ix process
        !          2092: A process declaration starts with the keyword
        !          2093: .CW proctype
        !          2094: followed by a name, a list of formal parameters
        !          2095: enclosed in round braces, and
        !          2096: a sequence of statements and local
        !          2097: variable declarations.
        !          2098: The body of process declaration is enclosed in curly braces.
        !          2099: .P1 0
        !          2100: proctype name( /* parameter decls */ )
        !          2101: {
        !          2102:        /* statements */
        !          2103: }
        !          2104: .P2
        !          2105: .IH Statements
        !          2106: .PP
        !          2107: .ix statements
        !          2108: .ix gotos
        !          2109: .ix labels
        !          2110: .ix skip
        !          2111: There are twelve types of statements:
        !          2112: .KS
        !          2113: .TS
        !          2114: center;
        !          2115: a a a.
        !          2116: .ft CW
        !          2117: .ps -1
        !          2118: .vs -1
        !          2119: assertion      assignment      atomic
        !          2120: break  declaration     expression
        !          2121: goto   receive selection
        !          2122: repetition     send    timeout
        !          2123: .ft
        !          2124: .ps +1
        !          2125: .vs +1
        !          2126: .TE
        !          2127: .KE
        !          2128: Each statement may be preceded by a label: a name followed by a colon.
        !          2129: A statement can only be passed if it is executable.
        !          2130: To determine its executability the statement can be evaluated:
        !          2131: if evaluation returns a zero value the statement is blocked.
        !          2132: In all other cases the statement is executable and can be passed.
        !          2133: The act of passing the statement after a successful evaluation is
        !          2134: called the ``execution'' of the statement.
        !          2135: There are also three so-called \fIpseudo\fR-statements, which are
        !          2136: really syntactic equivalents of specific variants of some of the
        !          2137: above statements
        !          2138: They are
        !          2139: .P1
        !          2140: skip   block   halt
        !          2141: .P2
        !          2142: equivalent to two conditions and an assert statement, respectively:
        !          2143: .P1
        !          2144: 1      0       assert(0).
        !          2145: .P2
        !          2146: .CW skip ,
        !          2147: therefore, is a null statement; it is always executable.
        !          2148: It has no effect when executed, but may be needed
        !          2149: to satisfy syntax requirements.
        !          2150: .CW block ,
        !          2151: is never executable.
        !          2152: The evaluation of an assertion statement
        !          2153: .CW assert(condition)
        !          2154: has no effect if the condition holds, but aborts the
        !          2155: running process if evaluation of the condition returns a
        !          2156: zero result (the boolean value ``false'').
        !          2157: .CW halt ,
        !          2158: therefore, effectively stops the execution of the system.
        !          2159: .PP
        !          2160: .CW goto
        !          2161: statements can be used to transfer control to any labeled statement
        !          2162: within the same process or procedure.
        !          2163: They also are always executable.
        !          2164: Assignments have been discussed above, they are
        !          2165: always executable.
        !          2166: A declaration is also always executable.
        !          2167: Expressions are only executable if they return a non-zero value.
        !          2168: That is, the expression \(CW0\fR (zero) is never executable, and
        !          2169: similarly \(CW1\fR always is executable.
        !          2170: Below we consider the remaining statements: selection, repetition,
        !          2171: send, receive, break, timeout, and atomic statements.
        !          2172: .IH Selection
        !          2173: .PP
        !          2174: .ix if statement
        !          2175: .ix case selection
        !          2176: .ix nondeterminism
        !          2177: A selection statement is started with the keyword
        !          2178: .CW if ,
        !          2179: followed by
        !          2180: a list of one or more `options' and terminated with the keyword
        !          2181: .CW fi .
        !          2182: Every `option' is started with the flag \f(CW::\fR followed by any sequence
        !          2183: of statements.
        !          2184: One and only one option from a selection statement will
        !          2185: be selected for execution.
        !          2186: The first statement of an option determines
        !          2187: whether the option can be selected or not.
        !          2188: If more than one option is executable, one will be selected at random.
        !          2189: Note that this randomness makes the language a nondeterministic one.
        !          2190: .IH "Repetition and Break"
        !          2191: .PP
        !          2192: .ix do statement
        !          2193: .ix repetition
        !          2194: A repetition or
        !          2195: .CW do
        !          2196: statement is similar to a selection statement, but is executed
        !          2197: repeatedly until either a
        !          2198: .CW break
        !          2199: statement is executed or a
        !          2200: .CW goto
        !          2201: jump will transfer control outside the cycle.
        !          2202: The keywords of the repetition statement are
        !          2203: .CW do
        !          2204: and
        !          2205: .CW od
        !          2206: instead of the
        !          2207: .CW if
        !          2208: and
        !          2209: .CW fi
        !          2210: of selection.
        !          2211: The
        !          2212: .CW break
        !          2213: statement will terminate the innermost repetition
        !          2214: statement in which it is executed.
        !          2215: The use of a \(CWbreak\fR statement outside a
        !          2216: repetition statement is illegal.
        !          2217: ......
        !          2218: .IH "Atomic Sequences"
        !          2219: .PP
        !          2220: The keyword
        !          2221: .CW atomic
        !          2222: introduces an atomic sequence of statements, that is
        !          2223: to be executed as one indivisible step.
        !          2224: The syntax is as follows
        !          2225: .P1 0
        !          2226: atomic { sequence }
        !          2227: .P2
        !          2228: Logically the sequence of statements is now equivalent
        !          2229: to one single statement.
        !          2230: It is a run-time error if any statement that is part of an
        !          2231: atomic sequence is found to be unexecutable.
        !          2232: The safest is therefore to include only assignments and
        !          2233: local conditions in atomic sequences, but no sends or receives.
        !          2234: Labeling local computations as atomic can bring an important
        !          2235: reduction of the complexity of a validation model.
        !          2236: For the lazy, \*s has an option (\f(CW-q\f1) that tries to find
        !          2237: the most obvious ``atomicable'' sequences in the code,
        !          2238: but the user can often do better by hand.
        !          2239: .IH Send
        !          2240: .PP
        !          2241: .ix i/o statements
        !          2242: .ix send
        !          2243: The syntax of a send statement is:
        !          2244: .P1 0
        !          2245: expr1!expr2
        !          2246: .P2
        !          2247: where
        !          2248: .CW expr1
        !          2249: returns the identity of a channel, e.g. obtained from a
        !          2250: .CW chan
        !          2251: operation, and
        !          2252: .CW expr2
        !          2253: returns a value to be appended to the channel.
        !          2254: The send statement is not executable (blocks) if the addressed channel is full
        !          2255: or does not exist.
        !          2256: .ix value transfer
        !          2257: If more than one value is to be passed from sender to receiver, the expressions
        !          2258: are written in a comma separated list:
        !          2259: .P1 0
        !          2260: expr1!expr2,expr3,expr4
        !          2261: .P2
        !          2262: Equivalently, this may be written
        !          2263: .P1 0
        !          2264: expr1!expr2(expr3,expr4) .
        !          2265: .P2
        !          2266: .IH Receive
        !          2267: .PP
        !          2268: .ix i/o statements
        !          2269: .ix receive
        !          2270: .ix value transfer
        !          2271: The syntax of the receive statement is:
        !          2272: .P1 0
        !          2273: expr1?name
        !          2274: .P2
        !          2275: where
        !          2276: .CW expr1
        !          2277: returns the name of a channel and
        !          2278: .CW name
        !          2279: is a variable or a constant.
        !          2280: If a constant is specified the receive statement is only executable
        !          2281: if the channel exists and
        !          2282: the oldest message stored in the channel contains the same value.
        !          2283: If a variable is specified, the receive statement is executable
        !          2284: if the channel exists and contains any message at all.
        !          2285: The variable in that case will receive the value of the message
        !          2286: that is retrieved.
        !          2287: If more than one value is sent per message, the receive statement
        !          2288: also take a comma separated list of variables and constants
        !          2289: .P1 0
        !          2290: expr1?name1,name2,...
        !          2291: .P2
        !          2292: which again is syntactically equivalent to
        !          2293: .P1 0
        !          2294: expr1?name1(name2,...)
        !          2295: .P2
        !          2296: Each constant in this list puts an extra condition on the
        !          2297: executability of the receive: it must be matched by the
        !          2298: value of the corresponding message field of the
        !          2299: message to be retrieved.
        !          2300: The variable fields retrieve the values of the corresponding
        !          2301: message fields on a receive.
        !          2302: .PP
        !          2303: Placing square brackets around the clause after the `?'
        !          2304: in the receiver operation converts it into a condition,
        !          2305: that is true only if the corresponding receive operation
        !          2306: is executable.
        !          2307: It can be used freely in any type of composite boolean condition,
        !          2308: and it has no side-effects when evaluated.
        !          2309: .PP
        !          2310: A last type of operation allowed on channels is
        !          2311: .P1 0
        !          2312: len(expr)
        !          2313: .P2
        !          2314: where
        !          2315: .CW expr
        !          2316: returns the identity of an instantiated channel.
        !          2317: The operation returns the number of messages in
        !          2318: the channel specified, or zero if the channel does not exist.
        !          2319: .IH Timeout
        !          2320: .PP
        !          2321: The timeout condition is a modeling feature that by definition becomes true
        !          2322: only if no statement in any of the running processes is executable.
        !          2323: It has no effect when executed.
        !          2324: .IH "Macros and Include Files"
        !          2325: .PP
        !          2326: .ix macros
        !          2327: .ix include files
        !          2328: .ix preprocessor
        !          2329: The source text of a specification is processed by the C|reference(cbook)
        !          2330: preprocessor for macro-expansion and file inclusions.
        !          2331: .NH
        !          2332: Summary
        !          2333: .PP
        !          2334: In the first part of this memo
        !          2335: we have introduced a notation for modeling concurrent
        !          2336: systems, including but not limited to asynchronous
        !          2337: data communication protocols, in a language named \*P.
        !          2338: The language has several unusual features.
        !          2339: All communication between processes takes
        !          2340: place via either messages or shared variables.
        !          2341: Both synchronous and asynchronous communication
        !          2342: are modeled as two special cases of a general message
        !          2343: passing mechanism.
        !          2344: Every statement in \*P can potentially model delay: it is
        !          2345: either executable or not, in most cases depending on the state
        !          2346: of the environment of the running process.
        !          2347: Process interaction and process coordination is thus at
        !          2348: the very basis of the language.
        !          2349: More about the design of \*P, of the validator \*s, and
        !          2350: its application to protocol design, can be found in |reference(holzmann spinbook).
        !          2351: .PP
        !          2352: \*P is deliberately a validation modeling language, not a programming language.
        !          2353: There are, for instance, no elaborate abstract data types,
        !          2354: or more than a few basic types of variable.
        !          2355: A validation model is an abstraction of a protocol implementation.
        !          2356: The abstraction maintains the essentials of the process interactions,
        !          2357: so that it can be studied in isolation.
        !          2358: It suppresses implementation and programming detail.
        !          2359: .PP
        !          2360: The syntax of \*P expressions, declarations, and assignments
        !          2361: is loosely based on the language
        !          2362: .CW C |reference(cbook).
        !          2363: The language was influenced significantly by the ``guarded command languages''
        !          2364: of E.W. Dijkstra |reference(dijkstra guarded) and C.A.R. Hoare
        !          2365: |reference(hoare csp).
        !          2366: There are, however, important differences.
        !          2367: Dijkstra's language had no primitives for process interaction.
        !          2368: Hoare's language was based exclusively on synchronous
        !          2369: communication.
        !          2370: Also in Hoare's language, the type
        !          2371: of statements that could appear in the guards of an option was
        !          2372: restricted.
        !          2373: The semantics of the selection and cycling statements
        !          2374: in \*P is also rather different from other guarded
        !          2375: command languages: the statements are not aborted when all guards
        !          2376: are false but they block: thus providing the required synchronization.
        !          2377: .PP
        !          2378: With minimal effort \*s allows the user to generate sophisticated
        !          2379: analyzers from \*P validation models.
        !          2380: Both the \*s software itself, and the analyzers it can generate,
        !          2381: are written in ANSII C and are portable across
        !          2382: .UX
        !          2383: systems.
        !          2384: They can be scaled to fully exploit the physical limitations
        !          2385: of the host computer, and deliver within those
        !          2386: limits the best possible analyses that can be realized
        !          2387: with the current state of the art in protocol analysis.
        !          2388: .NH
        !          2389: References
        !          2390: .LP
        !          2391: |reference_placement
        !          2392: .af H1 A
        !          2393: .nr H1 1
        !          2394: .nr H2 0
        !          2395: .SH
        !          2396: Appendix: Building A Validation Suite
        !          2397: .PP
        !          2398: The first order of business in using \*s for
        !          2399: a validation is the construction of a
        !          2400: faithful model in \*P of the problem at hand.
        !          2401: The language is deliberately kept small.
        !          2402: The purpose of the modeling is to extract those
        !          2403: aspects of the system that are relevant to the
        !          2404: coordination problem being studied.
        !          2405: All other details are suppressed.
        !          2406: Formally: the model is a reduction of the
        !          2407: system that needs to be equivalent to the full system
        !          2408: only with respect to the properties that are being validated.
        !          2409: Once a model has been constructed, it becomes
        !          2410: the basis for the construction of a series of,
        !          2411: what we may call, ``validation suites'' that
        !          2412: are used to verify its properties.
        !          2413: To build a validation suite we can prime the
        !          2414: model with assertions.
        !          2415: The assertions can formalize invariant relations
        !          2416: about the values of variables or about allowable
        !          2417: sequences of events in the model.
        !          2418: .NH 2
        !          2419: An Example
        !          2420: .PP
        !          2421: As a first example we take the following solution
        !          2422: to the mutual exclusion problem, discussed earlier,
        !          2423: published in 1966 by H. Hyman in the Communications of the ACM.
        !          2424: It was listed, in pseudo Algol, as follows.
        !          2425: .P1 0
        !          2426:   1 \f3Boolean array\f2 b(0;1) \f3integer\f2 k, i,\f(CW
        !          2427:   2 \f3comment\f2 process i, with i either 0 or 1;\f(CW
        !          2428:   3 \f2C0:     b(i) := \f3false\f2;\f(CW
        !          2429:   4 \f2C1:     \f3if\f2 k != i \f3then begin\f2\f(CW
        !          2430:   5 \f2C2:     \f3if\f2 not (b(1-i) \f3then go to\f2 C2;\f(CW
        !          2431:   6    \f3else\f2 k := i; \f3go to\f2 C1 \f3end\f2;\f(CW
        !          2432:   7    \f3else\f2 critical section;\f(CW
        !          2433:   8    \f2b(i) := \f3true\f2;\f(CW
        !          2434:   9    \f2remainder of program;\f(CW
        !          2435:  10    \f3go to\f2 C0;\f(CW
        !          2436:  11    \f3end\f(CW
        !          2437: .P2
        !          2438: The solution, as Dekker's earlier solution, is for two processes,
        !          2439: numbered 0 and 1.
        !          2440: Suppose we wanted to prove that Hyman's solution truly
        !          2441: guaranteed mutually exclusive access to the critical section.
        !          2442: Our first task is to build a model of the solution in \*P.
        !          2443: While we're at it, we can pick some more useful names for
        !          2444: the variables that are used.
        !          2445: .P1 0
        !          2446:    1  bool want[2];    /* Bool array b */
        !          2447:    2  bool turn;       /* integer    k */
        !          2448:    3  
        !          2449: .P3
        !          2450:    4  proctype P(bool i)
        !          2451:    5  {
        !          2452:    6   want[i] = 1;
        !          2453: .P3
        !          2454:    7   do
        !          2455:    8   :: (turn != i) ->
        !          2456:    9           (!want[1-i]);
        !          2457:   10           turn = i
        !          2458: .P3
        !          2459:   11   :: (turn == i) ->
        !          2460:   12           break
        !          2461:   13   od;
        !          2462: .P3
        !          2463:   14   skip; /* critical section */
        !          2464:   15   want[i] = 0
        !          2465:   16  }
        !          2466: .P3
        !          2467:   17  
        !          2468: .P3
        !          2469:   18  init { run P(0); run P(1) }
        !          2470: .P2
        !          2471: We can generate, compile, and run a validator for this
        !          2472: model, to see if there are any major problems, such as
        !          2473: a global system deadlock.
        !          2474: .P1 0
        !          2475: $ spin -a hyman0
        !          2476: $ cc pan.c
        !          2477: $ a.out
        !          2478: full statespace search for:
        !          2479: assertion violations and invalid endstates
        !          2480: vector 20 byte, depth reached 19, errors: 0
        !          2481:       79 states, stored
        !          2482:        0 states, linked
        !          2483:       38 states, matched       total: 117
        !          2484: hash conflicts: 4 (resolved)
        !          2485: (size 2^18 states, stack frames: 3/0)
        !          2486: 
        !          2487: unreached code _init (proc 0):
        !          2488:        reached all 3 states
        !          2489: unreached code P (proc 1):
        !          2490:        reached all 12 states
        !          2491: .P2
        !          2492: The model passes this first test.
        !          2493: What we are really interested in, however, is if
        !          2494: the algorithm guarantees mutual exclusion.
        !          2495: There are several ways to proceed.
        !          2496: The simplest is to just add enough information
        !          2497: to the model that we can express the correctness
        !          2498: requirement in a \*P assertion.
        !          2499: .P1 0
        !          2500:    1  bool want[2];
        !          2501:    2  bool turn;
        !          2502:    3  byte cnt;
        !          2503:    4  
        !          2504: .P3
        !          2505:    5  proctype P(bool i)
        !          2506:    6  {
        !          2507: .P3
        !          2508:    7   want[i] = 1;
        !          2509: .P3
        !          2510:    8   do
        !          2511:    9   :: (turn != i) ->
        !          2512:   10           (!want[1-i]);
        !          2513:   11           turn = i
        !          2514: .P3
        !          2515:   12   :: (turn == i) ->
        !          2516:   13           break
        !          2517:   14   od;
        !          2518:   15   skip; /* critical section */
        !          2519: .P3
        !          2520:   16   cnt = cnt+1;
        !          2521:   17   assert(cnt == 1);
        !          2522:   18   cnt = cnt-1;
        !          2523:   19   want[i] = 0
        !          2524:   20  }
        !          2525: .P3
        !          2526:   21  
        !          2527: .P3
        !          2528:   22  init { run P(0); run P(1) }
        !          2529: .P2
        !          2530: We have added a global variable
        !          2531: .CW cnt
        !          2532: that is incremented upon each access to the
        !          2533: critical section, and decremented upon each exit
        !          2534: from it.
        !          2535: The maximum value that this variable should ever
        !          2536: have is 1, and it can only have this value when
        !          2537: a process is inside the critical section.
        !          2538: .P1 0
        !          2539: $ spin -a hyman1
        !          2540: $ cc pan.c
        !          2541: $ a.out
        !          2542: assertion violated (cnt==1)
        !          2543: pan: aborted (at depth 15)
        !          2544: pan: wrote pan.trail
        !          2545: full statespace search for:
        !          2546: assertion violations and invalid endstates
        !          2547: search was not completed
        !          2548: vector 20 byte, depth reached 25, errors: 1
        !          2549:      123 states, stored
        !          2550:        0 states, linked
        !          2551:       55 states, matched       total: 178
        !          2552: hash conflicts: 42 (resolved)
        !          2553: (size 2^18 states, stack frames: 3/0)
        !          2554: .P2
        !          2555: The validator claims that the assertion can be violated.
        !          2556: We can use the error trail to check it with \*s's \f(CW-t\f1 option:
        !          2557: .P1 0
        !          2558: $ spin -t -p hyman1
        !          2559: proc  0 (_init)        line 24 (state 2)
        !          2560: proc  0 (_init)        line 24 (state 3)
        !          2561: .P3
        !          2562: proc  2 (P)    line 8 (state 7)
        !          2563: proc  2 (P)    line 9 (state 2)
        !          2564: .P3
        !          2565: proc  2 (P)    line 10 (state 3)
        !          2566: proc  2 (P)    line 11 (state 4)
        !          2567: .P3
        !          2568: proc  1 (P)    line 8 (state 7)
        !          2569: proc  1 (P)    line 12 (state 5)
        !          2570: .P3
        !          2571: proc  1 (P)    line 15 (state 10)
        !          2572: proc  2 (P)    line 8 (state 7)
        !          2573: .P3
        !          2574: proc  2 (P)    line 12 (state 5)
        !          2575: proc  2 (P)    line 15 (state 10)
        !          2576: .P3
        !          2577: proc  2 (P)    line 16 (state 11)
        !          2578: proc  2 (P)    line 17 (state 12)
        !          2579: .P3
        !          2580: proc  2 (P)    line 18 (state 13)
        !          2581: proc  1 (P)    line 16 (state 11)
        !          2582: .P3
        !          2583: proc  1 (P)    line 17 (state 12)
        !          2584: spin: "hyman1" line 17: assertion violated
        !          2585: .P3
        !          2586: step 17, #processes: 3
        !          2587:                want[0] = 1
        !          2588:                _p[0] = 12
        !          2589:                turn[0] = 1
        !          2590:                cnt[0] = 2
        !          2591: .P3
        !          2592: proc  2 (P)    line 18 (state 13)
        !          2593: proc  1 (P)    line 17 (state 12)
        !          2594: proc  0 (_init)        line 24 (state 3)
        !          2595: 3 processes created
        !          2596: .P2
        !          2597: Here is another way to catch the error.
        !          2598: We again lace the model with the information that
        !          2599: will allow us to count the number of processes
        !          2600: in the critical section.
        !          2601: .P1 0
        !          2602:    1  bool want[2];
        !          2603:    2  bool turn;
        !          2604:    3  byte cnt;
        !          2605:    4  
        !          2606: .P3
        !          2607:    5  proctype P(bool i)
        !          2608:    6  {
        !          2609:    7   want[i] = 1;
        !          2610: .P3
        !          2611:    8   do
        !          2612:    9   :: (turn != i) ->
        !          2613:   10           (!want[1-i]);
        !          2614:   11           turn = i
        !          2615: .P3
        !          2616:   12   :: (turn == i) ->
        !          2617:   13           break
        !          2618:   14   od;
        !          2619: .P3
        !          2620:   15   cnt = cnt+1;
        !          2621:   16   skip;   /* critical section */
        !          2622:   17   cnt = cnt-1;
        !          2623:   18   want[i] = 0
        !          2624:   19  }
        !          2625: .P3
        !          2626:   20  
        !          2627: .P3
        !          2628:   21  proctype monitor()
        !          2629:   22  {
        !          2630:   23   assert(cnt == 0 || cnt == 1)
        !          2631:   24  }
        !          2632: .P3
        !          2633:   25  
        !          2634: .P3
        !          2635:   26  init {
        !          2636:   27   run P(0); run P(1); run monitor()
        !          2637:   28  }
        !          2638: .P2
        !          2639: The invariant condition on the value of counter
        !          2640: .CW cnt
        !          2641: is now place in a separate process
        !          2642: .CW monitor()
        !          2643: (the name is immaterial).
        !          2644: The extra process runs along with the two others.
        !          2645: It will always terminate in one step, but it
        !          2646: could execute that step at \f2any\f1 time.
        !          2647: The systems modeled by \*P and validated by \*s
        !          2648: are completely asynchronous.
        !          2649: That means that the validation of \*s take into
        !          2650: account \f2all\f1 possible relative timings of
        !          2651: the three processes.
        !          2652: In a full validation, the assertion therefore
        !          2653: can be evaluated at any time during the lifetime
        !          2654: of the other two processes.
        !          2655: If the validator reports that it is not violated
        !          2656: we can indeed conclude that there is no execution
        !          2657: sequence at all (no way to select relative speeds for
        !          2658: the three processes) in which the assertion can be
        !          2659: violated.
        !          2660: The setup with the monitor process is therefore an
        !          2661: elegant way to check the validity of a system invariant.
        !          2662: The validation produces:
        !          2663: .P1 0
        !          2664: $ spin -a hyman2
        !          2665: $ cc pan.c
        !          2666: $ a.out
        !          2667: assertion violated ((cnt==0)||(cnt==1))
        !          2668: pan: aborted (at depth 15)
        !          2669: pan: wrote pan.trail
        !          2670: full statespace search for:
        !          2671: assertion violations and invalid endstates
        !          2672: search was not completed
        !          2673: vector 24 byte, depth reached 26, errors: 1
        !          2674:      368 states, stored
        !          2675:        0 states, linked
        !          2676:      379 states, matched       total: 747
        !          2677: hash conflicts: 180 (resolved)
        !          2678: (size 2^18 states, stack frames: 4/0)
        !          2679: .P2
        !          2680: Because of the extra interleaving of the two processes
        !          2681: with a third monitor, the number of system states that
        !          2682: had to be searched has increased, but the error is again
        !          2683: correctly reported.
        !          2684: .br
        !          2685: .NE 8v
        !          2686: .NH 2
        !          2687: Another Example
        !          2688: .PP
        !          2689: Not always can a correctness requirement be cast in
        !          2690: terms of a global system invariant.
        !          2691: Here is an example that illustrates this.
        !          2692: It is a simple alternating bit protocol, modeling
        !          2693: the possibility of message loss, and distortion,
        !          2694: and extended with negative acknowledgements.
        !          2695: .P1 0
        !          2696:    1  #define MAX      5
        !          2697:    2  
        !          2698:    3  mtype = { mesg, ack, nak, err };
        !          2699:    4  
        !          2700: .P3
        !          2701:    5  proctype sender(chan in, out)
        !          2702:    6  {        byte o, s, r;
        !          2703:    7  
        !          2704:    8   o=MAX-1;
        !          2705:    9   do
        !          2706:   10   :: o = (o+1)%MAX; /* next msg */
        !          2707:   11  again: if
        !          2708:   12         :: out!mesg(o,s) /* send */
        !          2709:   13         :: out!err    /* distort */
        !          2710:   14         :: skip       /* or lose */
        !          2711:   15         fi;
        !          2712: .P3
        !          2713:   16         if
        !          2714:   17         :: timeout   -> goto again
        !          2715:   18         :: in?err    -> goto again
        !          2716:   19         :: in?nak(r) -> goto again
        !          2717:   20         :: in?ack(r) ->
        !          2718:   21           if
        !          2719:   22           :: (r == s) -> goto progress
        !          2720:   23           :: (r != s) -> goto again
        !          2721:   24           fi
        !          2722:   25         fi;
        !          2723:   26  progress:        s = 1-s /* toggle seqno */
        !          2724:   27   od
        !          2725:   28  }
        !          2726:   29  
        !          2727: .P3
        !          2728:   30  proctype receiver(chan in, out)
        !          2729:   31  {        byte i;         /* actual input   */
        !          2730:   32   byte s;         /* actual seqno   */
        !          2731:   33   byte es;        /* expected seqno */
        !          2732:   34   byte ei;        /* expected input */
        !          2733:   35  
        !          2734:   36   do
        !          2735:   37   :: in?mesg(i, s) ->
        !          2736:   38           if
        !          2737:   39           :: (s == es) ->
        !          2738:   40                   assert(i == ei);
        !          2739:   41  progress:                es = 1 - es;
        !          2740:   42                   ei = (ei + 1)%MAX;
        !          2741:   43                   if
        !          2742:   44   /* send,   */   :: out!ack(s)
        !          2743:   45   /* distort */   :: out!err
        !          2744:   46   /* or lose */   :: skip
        !          2745:   47                   fi
        !          2746: .P3
        !          2747:   48           :: (s != es) ->
        !          2748: .P3
        !          2749:   49                   if
        !          2750: .P3
        !          2751:   50   /* send,   */   :: out!nak(s)
        !          2752:   51   /* distort */   :: out!err
        !          2753:   52   /* or lose */   :: skip
        !          2754: .P3
        !          2755:   53                   fi
        !          2756: .P3
        !          2757:   54           fi
        !          2758:   55   :: in?err ->
        !          2759:   56           out!nak(s)
        !          2760: .P3
        !          2761:   57   od
        !          2762:   58  }
        !          2763:   59  
        !          2764: .P3
        !          2765:   60  init {
        !          2766: .P3
        !          2767:   61   chan s_r [1] of { byte,byte,byte };
        !          2768:   62   chan r_s [1] of { byte,byte,byte };
        !          2769: .P3
        !          2770:   63   atomic {
        !          2771: .P3
        !          2772:   64           run sender(r_s, s_r);
        !          2773:   65           run receiver(s_r, r_s)
        !          2774: .P3
        !          2775:   66   }
        !          2776: .P3
        !          2777:   67  }
        !          2778: .P2
        !          2779: To test the proposition that this protocol will
        !          2780: correctly transfer data, the model has already
        !          2781: been primed for the first validation runs.
        !          2782: First, the sender is setup to transfer an infinite
        !          2783: series of integers as messages, where the value
        !          2784: of the integers are incremented modulo
        !          2785: .CW MAX .
        !          2786: The value of
        !          2787: .CW MAX
        !          2788: is not really too interesting, as long as it is
        !          2789: larger than the range of the sequence numbers in
        !          2790: the protocol: in this case 2.
        !          2791: We want to verify that data that is sent can only be
        !          2792: delivered to the receiver without any deletions or reorderings,
        !          2793: despite the possibility of arbitrary message loss.
        !          2794: The assertion on line 40 verifies precisely that.
        !          2795: Note that if it were ever possible for the protocol to
        !          2796: fail to meet the above requirement, the assertion can be violated.
        !          2797: .PP
        !          2798: A first validation run reassures us that this is not possible.
        !          2799: .P1 0
        !          2800: $ spin -a ABP0
        !          2801: $ cc pan.c
        !          2802: $ a.out
        !          2803: full statespace search for:
        !          2804: assertion violations and invalid endstates
        !          2805: vector 40 byte, depth reached 131, errors: 0
        !          2806:      346 states, stored
        !          2807:        1 states, linked
        !          2808:      125 states, matched        total: 472
        !          2809: hash conflicts: 17 (resolved)
        !          2810: (size 2^18 states, stack frames: 0/25)
        !          2811: 
        !          2812: unreached code _init (proc 0):
        !          2813:        reached all 4 states
        !          2814: unreached code receiver (proc 1):
        !          2815:        line 58 (state 24)
        !          2816:        reached: 23 of 24 states
        !          2817: unreached code sender (proc 2):
        !          2818:        line 28 (state 27)
        !          2819:        reached: 26 of 27 states
        !          2820: .P2
        !          2821: But, be careful.
        !          2822: The result means that all data that is delivered, is
        !          2823: delivered in the correct order without deletions etc.
        !          2824: We did not check that the data \f2will\f1 necessarily be delivered.
        !          2825: It may be possible for sender and receiver to cycle
        !          2826: through a series of states, exchanges erroneous messages,
        !          2827: without ever making effective progress.
        !          2828: To check this, the state in the sender and in the receiver
        !          2829: process that unmistakingly signify progress, were labeled
        !          2830: as a ``progress states.''
        !          2831: (In fact, either one by itself would suffice.)
        !          2832: .PP
        !          2833: We should now be able to demonstrate the absence of
        !          2834: infinite execution cycles that do not pass through any
        !          2835: of these progress states.
        !          2836: We can use the same executable from the last run, but
        !          2837: this time we perform a loop-check.
        !          2838: .P1 0 
        !          2839: $  a.out -l
        !          2840: pan: non-progress cycle (at depth 6)
        !          2841: pan: wrote pan.trail
        !          2842: full statespace search for:
        !          2843: assertion violations and non-progress loops
        !          2844: search was not completed
        !          2845: vector 44 byte, depth reached 8, loops: 1
        !          2846:       12 states, stored
        !          2847:        1 states, linked
        !          2848:        0 states, matched       total: 13
        !          2849: hash conflicts: 0 (resolved)
        !          2850: (size 2^18 states, stack frames: 0/1)
        !          2851: .P2
        !          2852: There are non-progress cycles.
        !          2853: The first one encountered is dumped into the error trail
        !          2854: by the validator, and we can inspect it.
        !          2855: The results are shown in the first half of Figure 2.
        !          2856: The channel can distort or lose the message infinitely often;
        !          2857: true, but not too exciting as an error scenario.
        !          2858: To see how many non-progress cycles there are, we can use the \f(CW-c\f1 flag.
        !          2859: If we set its numeric argument to zero, only
        !          2860: a total count of all errors will be printed.
        !          2861: .P1 0
        !          2862: $ a.out -l -c0
        !          2863: full statespace search for:
        !          2864: assertion violations and non-progress loops
        !          2865: vector 44 byte, depth reached 137, loops: 92
        !          2866:      671 states, stored
        !          2867:        2 states, linked
        !          2868:      521 states, matched        total: 1194
        !          2869: hash conflicts: 39 (resolved)
        !          2870: (size 2^18 states, stack frames: 0/26)
        !          2871: .P2
        !          2872: There are 92 cases to consider, and we could look at each
        !          2873: one, using the \f(CW-c\f1 option (\f(CW-c1\f1, \f(CW-c2\f1, \f(CW-c3\f1, ...etc.)
        !          2874: But, we can make the job a little easier by at least
        !          2875: filtering out the errors caused by infinite message loss.
        !          2876: We label all loss events (lines 13, 43, and 48) as
        !          2877: progress states, using label names with the common 8-character
        !          2878: prefix ``progress,'' and look at the cycles that remain.
        !          2879: (Labels go behind the ``::'' flags.)
        !          2880: .P1 0
        !          2881: $ spin -a ABP1
        !          2882: $ cc pan.c
        !          2883: .P3
        !          2884: $ a.out -l
        !          2885: pan: non-progress cycle (at depth 133)
        !          2886: pan: wrote pan.trail
        !          2887: .P3
        !          2888: full statespace search for:
        !          2889: assertion violations and non-progress loops
        !          2890: search was not completed
        !          2891: .P3
        !          2892: vector 44 byte, depth reached 136, loops: 1
        !          2893: .P3
        !          2894:      148 states, stored
        !          2895:        2 states, linked
        !          2896:        2 states, matched        total: 152
        !          2897: .P3
        !          2898: hash conflicts: 0 (resolved)
        !          2899: (size 2^18 states, stack frames: 0/26)
        !          2900: .P2
        !          2901: This time, the trace reveals an honest and a serious bug in the protocol.
        !          2902: The second half of Figure 2 shows the trace-back.
        !          2903: .1C
        !          2904: .KF
        !          2905: .nf
        !          2906: .ps -2
        !          2907: .vs -3p
        !          2908: .ft CW
        !          2909: .TS
        !          2910: box expand;
        !          2911: l
        !          2912: l.
        !          2913:       $ spin -t -r -s ABP0
        !          2914:       <<<<<START OF CYCLE>>>>>
        !          2915:       proc  1 (sender)   line  13, Send err,0,0 -> queue 2 (out)
        !          2916:       proc  2 (receiver) line  55, Recv err,0,0 <- queue 2 (in)
        !          2917:       proc  2 (receiver) line  56, Send nak,0,0 -> queue 1 (out)
        !          2918:       proc  1 (sender)   line  19, Recv nak,0,0 <- queue 1 (in)
        !          2919:       spin: trail ends after 12 steps
        !          2920:       step 12, #processes: 3
        !          2921:                _p[0] = 6
        !          2922:       proc  2 (receiver)       line 36 (state 21)
        !          2923:       proc  1 (sender) line 11 (state 6)
        !          2924:       proc  0 (_init)  line 67 (state 4)
        !          2925:       3 processes created
        !          2926:       $ 
        !          2927:       $ spin -t -r -s ABP1
        !          2928:       \&...
        !          2929:       proc  2 (receiver) line  39, Recv mesg,0,0 <- queue 2 (in)
        !          2930:       proc  2 (receiver) line  47, Send err,0,0  -> queue 1 (out)
        !          2931:       proc  1 (sender)   line  20, Recv err,1,0  <- queue 1 (in)
        !          2932:       proc  1 (sender)   line  12, Send mesg,0,0 -> queue 2 (out)
        !          2933:       proc  2 (receiver) line  39, Recv mesg,0,0 <- queue 2 (in)
        !          2934:       proc  2 (receiver) line  52, Send nak,0,0  -> queue 1 (out)
        !          2935:       proc  1 (sender)   line  21, Recv nak,0,0  <- queue 1 (in)
        !          2936:       proc  1 (sender)   line  12, Send mesg,0,0 -> queue 2 (out)
        !          2937:       proc  2 (receiver) line  39, Recv mesg,0,0 <- queue 2 (in)
        !          2938:       proc  2 (receiver) line  52, Send nak,0,0  -> queue 1 (out)
        !          2939:       <<<<<START OF CYCLE>>>>>
        !          2940:       proc  1 (sender)   line  21, Recv nak,0,0  <- queue 1 (in)
        !          2941:       proc  1 (sender)   line  12, Send mesg,0,0 -> queue 2 (out)
        !          2942:       proc  2 (receiver) line  39, Recv mesg,0,0 <- queue 2 (in)
        !          2943:       proc  2 (receiver) line  52, Send nak,0,0  -> queue 1 (out)
        !          2944:       spin: trail ends after 226 steps
        !          2945:       \&...
        !          2946: .TE
        !          2947: .fi
        !          2948: .ps +2
        !          2949: .vs +3p
        !          2950: .SP .5
        !          2951: .ce
        !          2952: \fBFigure 2.\fR  Error Trails - Extended Alternating Bit Protocol
        !          2953: .SP .5
        !          2954: .KE
        !          2955: .2C
        !          2956: .PP
        !          2957: After a single positive acknowledgement is distorted
        !          2958: and transformed into an
        !          2959: .CW err
        !          2960: message, sender and receiver get caught in an infinite
        !          2961: cycle, where the sender will stubbornly repeat the last
        !          2962: message for which it did not receive an acknowledgement,
        !          2963: and the receiver, just as stubbornly, will reject that
        !          2964: message with a negative acknowledgment.
        !          2965: .NH 2
        !          2966: Digging Deeper
        !          2967: .PP
        !          2968: This manual can only give an outline of the
        !          2969: main features of \*s, and the more common
        !          2970: ways in which it can be used for validations.
        !          2971: There is a small number of \*s features that
        !          2972: have not been discussed here, but that may be useful
        !          2973: for tackling non-standard validation problems.
        !          2974: \*S, for instance, can give \*P processes access
        !          2975: to extra system information, such as the current
        !          2976: values of normally invisible local variables,
        !          2977: or the current execution states of remote processes.
        !          2978: With this extra information it may be easier in
        !          2979: some cases to build accurate assertions about
        !          2980: required system behavior.
        !          2981: .PP
        !          2982: \*S also allows for a straightforward validation of ``tasks.''
        !          2983: That is, if the user formalizes a task that is claimed to be
        !          2984: performed by the system, \*s can quickly either prove or
        !          2985: disprove that claim.
        !          2986: The tasks can be used directly to verify any
        !          2987: propositional temporal logic formula
        !          2988: on the behavior of a system.
        !          2989: .PP
        !          2990: \*S also allows the user to formalize ``reductions'' of
        !          2991: the system state space, which can be used
        !          2992: to restrict a search it to a user defined subset.
        !          2993: With this method it becomes trivial to verify quickly
        !          2994: whether or not a given error pattern is within the range of
        !          2995: behaviors of a system, even when a complete validation is
        !          2996: considered to be infeasible.
        !          2997: .PP
        !          2998: For details about these alternative uses of \*P and
        !          2999: the \*s software, refer to [5].

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.