convert from svn repository: remove tags directory
[lttv.git] / trunk / verif / Spin / Doc / Book.Errata
CommitLineData
0b55f123 1Errata for `Design and Validation of Computer Protocols'
2[trivial typos not listed]
3
4CHAPTER 2, page 26 - Example of a Shorter Error Scenario
5============================================================
6
7A duplicate message can be accepted after even a single
8transmission error occurs. E.g.:
9
10 (A) (B)
11 ~ ~
12 | |
13 | ack 'z' /-----------<---------+
14 +-----------/ |
15accept(z) | |
16 +-----------\ ack 'a' -> err |
17 | \----------->--------+
18 | |
19 | nak 'z' /-----------<--------+
20 +------------/ |
21accept(z) | |
22
23
24CHAPTER 3, page 61/62 - Revised CRC-Algorithm
25(Bits renumbered in more standard right to left order.)
26============================================================
27
28The following C program, by Don Mitchell of AT&T Bell
29Laboratories, generates a lookup table for an arbitrary
30checksum polynomial. Input for the routine is an octal
31number, specified as an argument, that encodes the generator
32polynomial.
33In the version of the program shown here, compliments of Ned
34W. Rhodes, Software Systems Group, bits are numbered from
35zero to r-1, with bit zero corresponding to the right-most
36bit, and r the degree of the generator polynomial. (In
37Mitchell's original algorithm the bits in the message and
38generator polynomial were reversed.) The r-th bit itself is
39omitted from the code word, since it is implicit in the
40length. Using this program takes two separate steps.
41First, the program is compiled and run to generate the
42lookup tables. Then the checksum generation routine can be
43compiled, with the precalculated lookup tables in place. On
44a UNIX system, the program is compiled as
45
46 $ cc -o crc_init crc_init.c
47
48Lookup tables for the two most popular CRC-polynomials can
49now be produced as follows:
50
51 $ crc_init 0100005 > crc_16.h
52 $ crc_init 010041 > crc_ccitt.h
53
54This is the text of crc_init.c:
55
56
57 main(argc, argv)
58 int argc; char *argv[];
59 {
60 unsigned long crc, poly;
61 int n, i;
62
63 sscanf(argv[1], "%lo", &poly);
64 if (poly & 0xffff0000)
65 { fprintf(stderr, "polynomial is too large\n");
66 exit(1);
67 }
68
69 printf("/*\n * CRC 0%o\n */\n", poly);
70 printf("static unsigned short crc_table[256] = {\n");
71 for (n = 0; n < 256; n++)
72 { if (n % 8 == 0) printf(" ");
73 crc = n << 8;
74 for (i = 0; i < 8; i++)
75 { if (crc & 0x8000)
76 crc = (crc << 1) ^ poly;
77 else
78 crc <<= 1;
79 crc &= 0xFFFF;
80 }
81 if (n == 255) printf("0x%04X ", crc);
82 else printf("0x%04X, ", crc);
83 if (n % 8 == 7) printf("\n");
84 }
85 exit(0);
86 }
87
88The table can now be used to generate checksums:
89
90 unsigned short
91 cksum(s, n)
92 register unsigned char *s;
93 register int n;
94 {
95 register unsigned short crc=0;
96
97 while (n-- > 0)
98 crc = crc_table[(crc>>8 ^ *s++) & 0xff] ^ (crc<<8);
99
100 return crc;
101 }
102
103
104CHAPTER 4, page 81 - Typo
105============================================================
106
107old< Taking the modulo M effect into account, this becomes:
108 valid(m) = ( 0 < p - m <= W ) || ( 0 < p - M - m <= W )
109
110new> Taking the modulo M effect into account (p is always
111 smaller than M), this becomes:
112 valid(m) = ( 0 < p - m <= W ) || ( 0 < p + M - m <= W )
113
114ERROR, Page 83, Figure 4.14
115===========================
116
117should not "accept:i" if (a==e) is false
118
119
120CHAPTER 5, error/typos
121===========================
122
123Page 96, bottom
124
125The mutual exclusion algorithm attributed to Dekker is
126really a simplication of Dekker's algorithm that is known
127as Peterson's algorithm.
128Dekker's original solution is modeled in Promela like this:
129
130#define true 1
131#define false 0
132#define Aturn 1
133#define Bturn 0
134
135bool x, y, t;
136
137proctype A()
138{
139 do
140 :: x = true;
141 if
142 :: y == true && t == Bturn ->
143 x = false;
144 (t == Aturn)
145 :: y == false ->
146 break
147 fi
148 od;
149
150 /* critical section */
151
152 t = Bturn;
153 x = false
154}
155
156proctype B()
157{
158 do
159 :: y = true;
160 if
161 :: x == true && t == Aturn ->
162 y = false;
163 (t == Bturn)
164 :: x == false ->
165 break
166 fi
167 od;
168
169 /* critical section */
170
171 t = Aturn;
172 y = false
173}
174
175init { run A(); run B() }
176
177===========================
178
179Page 98, last paragraph
180
181old> "If the receive operation tries to retrieve more parameters
182 than are available, the value of the extra parameters is undefined;
183 if it receives fewer than the number of parameters that was sent,
184 the extra information is lost."
185new> "It is always an error if the receive operation tries to retrieve
186 a different number of parameters than the corresponding channel
187 declaration specifies."
188
189===========================
190
191Page 99, last line of "init", middle of page:
192
193old< qname!qforb
194
195new> qname[0]!qforb
196
197Page 100, delete last line on page:
198
199old< byte name; /* delete */
200
201Page 103, in the Dijkstra example:
202
203old< chan sema = [0] of { bit };
204
205new> chan sema = [0] of { mtype };
206
207Page 108, "init" section, top of page:
208
209old< chan Ain = [2] of { byte };
210 chan Bin = [2] of { byte };
211 chan Aout = [2] of { byte };
212 chan Bout = [2] of { byte };
213
214new> chan Ain = [2] of { byte, byte };
215 chan Bin = [2] of { byte, byte };
216 chan Aout = [2] of { byte, byte };
217 chan Bout = [2] of { byte, byte };
218
219===========================
220
221Page 107, last sentence of first paragraph Section 5.12:
222
223old< discussed in Section 2.4.
224new> discussed in Section 2.3.
225
226===========================
227
228Page 110, exercise 5-3:
229
230old< Revise the two programs from Section 5.6
231new> Revise the two programs from Section 5.8
232
233
234CHAPTER 6
235
236
237TYPO, page 117
238=======================
239old< chan sema[0] of {bit};
240new> chan sema = [0] of {bit};
241
242SERIOUS OMISSION, Section 6.4, page 116-117:
243=================================================
244The treatment of formalizing system invariants in a 1-statement
245monitor process is correct only if the model does not contain
246any timeout statements.
247If it does, the statements in the model that would be executed
248after a timeout expires are not checked (since assert is always
249executable, it would always be executed before the timeout expires
250under default timeout heuristics used in spin).
251there are two possible solutions:
252
253- disable the default timeout heuristics for a fully exhaustive
254 search for all possible choices of timeouts (brute force)
255 to do this, include a single line
256 #define timeout skip
257 as the first line of your model - and nothing else has to change
258
259- use a safer formalization of the system invariant, using a never claim.
260 the simples formalization is:
261 never { do :: assert(invariant) od }
262 which checks the truth of the invariant for every reachable state,
263 independent of timeouts.
264 another way would be to use the implicit matching behavior of a never
265 claim, without an explicit assertion:
266 never
267 { do
268 :: (invariant) /* things are fine, the invariant holds */
269 :: !(invariant) -> break /* invariant fails - match */
270 od
271 }
272
273CLARIFICATION, page 118, Section 6.5
274====================================
275The validator SPIN does not enforce the second criterion
276for a proper endstate, i.e., the emptiness of all channels.
277It does enforce the revised first criterion from the bottom
278of page 118.
279
280TYPO, page 121 middle:
281=================================================
282
283old< never { do :: skip od -> P -> !Q }
284
285new> never { do :: skip :: break od -> P -> !Q }
286
287ADDED EXPLANATIONS (throughout page 121 and onw.):
288=================================================
289
290A terminating claim is matched, and the corresponding correctness
291property thereby violated, if and when the claim body terminates.
292
293A non-terminating claim is matched, and the corresponding
294correctness property violated, if and when an acceptance cycle
295is detected.
296
297SPECIFYING TEMPORAL CLAIMS
298
299The body of a temporal claim is defined just like PROMELA
300proctype bodies. This means that all control flow struc-
301tures, such as if-fi selections, do-od repetitions, and
302goto jumps, are allowed. There is, however, one important
303difference:
304
305 Every statement inside a temporal claim is (interpreted
306 as) a boolean condition.
307
308Specifically, this means that the statements inside temporal
309claims should be free of side-effects. For reference, the
310PROMELA statements with side-effects are: assignments,
311assertions, sends, receives, and printf statements.
312
313Temporal claims are used to express system
314behaviors that are considered undesirable or illegal. We
315say that a temporal claim is matched if the undesirable
316behavior can be realized, and thus our correctness claim can
317be violated. The most useful application of temporal claims
318is in combination with acceptance labels. There are then
319two ways to match a temporal claim, depending on whether the
320undesirable behavior defines terminating or cyclic execution
321sequences.
322
323 For a terminating execution sequence, a temporal claim
324 is matched only when it can terminate (reaches the
325 closing curly brace) That is, the claim can be violated
326 if the closing curly brace of the PROMELA body of the
327 claim is reachable.
328
329 For a cyclic execution sequence, the claim is matched
330 only when an explicit acceptance cycle exists. The
331 acceptance labels within temporal claims are user
332 defined, there are no defaults. This means that in the
333 absence of acceptance labels no cyclic behavior can be
334 matched by a temporal claim. It also means that to
335 check a cyclic temporal claim, acceptance labels should
336 only occur within the claim and not elsewhere in the
337 PROMELA code.
338
339ERROR, page 124, top
340=======================
341old< :: len(receiver) == 0
342
343new> :: skip /* allow any time delay */
344
345ERROR, page 125, top
346=======================
347the claim can of course always be violated (== matched),
348whether timeout is redefined or not.
349
350CHAPTER 7
351
352ERROR, page 139, bottom
353=======================
354old< Pr(Burst >= 17) = 0.08 . e ^ { -0.08 . 17 } = 0.007
355
356new> Pr(Burst >= 17) = 0.009 . e ^ { -0.009 . 17 } = 0.007
357
358ERROR, page 156, middle
359=======================
360old< flow_to_dll[n]!sync_ack,0
361new> flow_to_dll[n]!sync_ack,m
362 (and move the new line up to precede: "m=0;")
363
364old< flow_to_ses[n]!sync_ack,0
365new> flow_to_ses[n]!sync_ack,m
366
367old< To avoid circularity, the synchronization messages
368 do not carry sequence numbers.
369new> The sync_ack message echos the session number of the
370 sync message.
371
372ERROR, page 156, bottom
373=======================
374old< || (0<p-m-M && p-m-M<=W));
375new> || (0<p-m+M && p-m+M<=W));
376
377
378CHAPTER 11
379
380ERROR, page 224, algorithm "analyze()"
381======================================
382old< q = element from W;
383new> q = last element from W;
384
385further down:
386=============
387old< If states are stored in set W in first-in first-out order,
388 the algorithm performs a breadth-first search of the state space tree.
389new> If states are stored in set W in first-in last-out (i.e., stack)
390 order, the algorithm performs a depth-first search of the state space tree.
391
392further down:
393=============
394old< If states are stored in first-in last-out (i.e., stack)
395 < order, this changes into a depth-first search.
396
397new> If states are stored and removed in first-in first-out
398 order, this changes into a breadth-first search
399 (element q must be deleted upon retrieval from set W in
400 this type of algorithm).
401
402Page 227, top
403=============
404old< q = element from W;
405new> q = last element from W;
406
407Page 237, bottom
408================
409old< after removing states 4, 3, and 2 from the stack...
410new> after removing states 4, and 3 from the stack...
411
412CHAPTER 13
413
414Page 315, 2nd para in 13.9
415==========================
416The first two sentences of this paragraph are incorrect.
417At the low end, just 1 state would be stored in the hash-array,
418taking up 2 bits of storage out of N available bits; at the
419high end, all N bits would be set at the end of the run, and
420(allowing overlaps) we cannot have seen more than N states.
421This leads to a possible range of values for the hash factor
422of N/2 >= hf >= 1
423For full state space storage the hash factor is meaningless.
424
425CHAPTER 14
426
427Page 331, lines 86, 88, and 94
428==============================
429See the corrections described for CHAPTER 7, page 156.
430
431APPENDIX C
432==============================
433
434Page 387-388
435The syntax of remote referencing has changed in SPIN Version 2.0.
436Remote referencing to local variables is no longer allowed
437(page 387, 5th line from below).
438The syntax for referencing the state of another process has changed
439from (page 388, 3rd line):
440 same[2]:here
441to:
442 same[2]@here
443
444=end errata=
This page took 0.038437 seconds and 4 git commands to generate.