1 /***** spin: pangen1.h *****/
3 /* Copyright (c) 1989-2005 by Lucent Technologies, Bell Laboratories. */
4 /* All Rights Reserved. This software is for educational purposes only. */
5 /* No guarantee whatsoever is expressed or implied by the distribution of */
6 /* this code. Permission is given to distribute this code provided that */
7 /* this introductory message is not removed and no monies are exchanged. */
8 /* Software written by Gerard J. Holzmann. For tool documentation see: */
9 /* http://spinroot.com/ */
10 /* Send all bug-reports and/or questions to: bugs@spinroot.com */
12 static char *Code2a[] = { /* the tail of procedure run() */
13 "#if defined(VERI) && !defined(NOREDUCE) && !defined(NP)",
19 " { printf(\"warning: for p.o. reduction to be valid \");",
20 " printf(\"the never claim must be stutter-invariant\\n\");",
21 " printf(\"(never claims generated from LTL \");",
22 " printf(\"formulae are stutter-invariant)\\n\");",
25 " UnBlock; /* disable rendez-vous */",
29 " { udmem *= 1024L*1024L;",
30 " SS = (uchar *) emalloc(udmem);",
31 " bstore = bstore_mod;",
34 " SS = (uchar *) emalloc(1L<<(ssize-3));",
38 "#if defined(FULLSTACK) && defined(BITSTATE)",
41 "#if defined(CNTRSTACK) && !defined(BFS)",
42 " LL = (uchar *) emalloc(1L<<(ssize-3));",
44 " stack = ( Stack *) emalloc(sizeof(Stack));",
45 " svtack = (Svtack *) emalloc(sizeof(Svtack));",
46 " /* a place to point for Pptr of non-running procs: */",
47 " noptr = (uchar *) emalloc(Maxbody * sizeof(char));",
50 " write(svfd, (uchar *) &vprefix, sizeof(int));",
53 " Addproc(VERI); /* never - pid = 0 */",
55 " active_procs(); /* started after never */",
57 " now._event = start_event;",
58 " reached[EVENT_TRACE][start_event] = 1;",
69 " if (--Nrun > 0 && HASH_CONST[++HASH_NR])",
70 " { printf(\"Run %%d:\\n\", HASH_NR);",
73 " memset(SS, 0, 1L<<(ssize-3));",
74 "#if defined(CNTRSTACK)",
75 " memset(LL, 0, 1L<<(ssize-3));",
77 "#if defined(FULLSTACK)",
78 " memset((uchar *) S_Tab, 0, ",
79 " maxdepth*sizeof(struct H_el *));",
81 " nstates=nlinks=truncs=truncs2=ngrabs = 0;",
82 " nlost=nShadow=hcmp = 0;",
84 " PUT=PROBE=ZAPS=Ccheck=Cholds = 0;",
89 "#ifdef HAS_PROVIDED",
90 "int provided(int, uchar, int, Trans *);",
95 "Printf(const char *fmt, ...)",
96 "{ /* Make sure the args to Printf",
97 " * are always evaluated (e.g., they",
98 " * could contain a run stmnt)",
99 " * but do not generate the output",
100 " * during verification runs",
101 " * unless explicitly wanted",
102 " * If this fails on your system",
103 " * compile SPIN itself -DPRINTF",
104 " * and this code is not generated",
109 " va_start(args, fmt);",
110 " vprintf(fmt, args);",
117 " va_start(args, fmt);",
118 " vprintf(fmt, args);",
124 "extern void printm(int);",
127 "#define getframe(i) &trail[i];",
129 "static long HHH, DDD, hiwater;",
130 "static long CNT1, CNT2;",
131 "static int stackwrite;",
132 "static int stackread;",
133 "static Trail frameptr;",
137 " if (CNT1 == CNT2)",
138 " return &trail[d];",
140 " if (d >= (CNT1-CNT2)*DDD)",
141 " return &trail[d - (CNT1-CNT2)*DDD];",
144 " && (stackread = open(stackfile, 0)) < 0)",
145 " { printf(\"getframe: cannot open %%s\\n\", stackfile);",
148 " if (lseek(stackread, d* (off_t) sizeof(Trail), SEEK_SET) == -1",
149 " || read(stackread, &frameptr, sizeof(Trail)) != sizeof(Trail))",
150 " { printf(\"getframe: frame read error\\n\");",
153 " return &frameptr;",
157 "#if !defined(SAFETY) && !defined(BITSTATE)",
158 "#if !defined(FULLSTACK) || defined(MA)",
159 "#define depth_of(x) A_depth /* an estimate */",
162 "depth_of(struct H_el *s)",
163 "{ Trail *t; int d;",
164 " for (d = 0; d <= A_depth; d++)",
165 " { t = getframe(d);",
166 " if (s == t->ostate)",
169 " printf(\"pan: cannot happen, depth_of\\n\");",
170 " return depthfound;",
177 "{ if (signoff) printf(\"--end of output--\\n\");",
183 "transmognify(char *s)",
185 " static char buf[2][2048];",
186 " int i, toggle = 0;",
188 " if (!s || strlen(s) > 2047) return s;",
189 " memset(buf[0], 0, 2048);",
190 " memset(buf[1], 0, 2048);",
191 " strcpy(buf[toggle], s);",
192 " while ((v = strstr(buf[toggle], \"{c_code\")))", /* assign v */
193 " { *v = '\\0'; v++;",
194 " strcpy(buf[1-toggle], buf[toggle]);",
195 " for (w = v; *w != '}' && *w != '\\0'; w++) /* skip */;",
196 " if (*w != '}') return s;",
198 " for (i = 0; code_lookup[i].c; i++)",
199 " if (strcmp(v, code_lookup[i].c) == 0",
200 " && strlen(v) == strlen(code_lookup[i].c))",
201 " { if (strlen(buf[1-toggle])",
202 " + strlen(code_lookup[i].t)",
203 " + strlen(w) > 2047)",
205 " strcat(buf[1-toggle], code_lookup[i].t);",
208 " strcat(buf[1-toggle], w);",
209 " toggle = 1 - toggle;",
211 " buf[toggle][2047] = '\\0';",
212 " return buf[toggle];",
215 "char * transmognify(char *s) { return s; }",
220 "add_src_txt(int ot, int tt)",
224 " for (t = trans[ot][tt]; t; t = t->nxt)",
225 " { printf(\"\\t\\t\");",
227 " q = transmognify(t->tp);",
228 " for ( ; q && *q; q++)",
230 " printf(\"\\\\n\");",
238 "{ static int wrap_in_progress = 0;",
242 " if (wrap_in_progress++) return;",
244 " printf(\"spin: trail ends after %%ld steps\\n\", depth);",
245 " if (onlyproc >= 0)",
246 " { if (onlyproc >= now._nr_pr) pan_exit(0);",
248 " z = (P0 *)pptr(II);",
249 " printf(\"%%3ld:\tproc %%d (%%s) \",",
250 " depth, II, procname[z->_t]);",
251 " for (i = 0; src_all[i].src; i++)",
252 " if (src_all[i].tp == (int) z->_t)",
253 " { printf(\" line %%3d\",",
254 " src_all[i].src[z->_p]);",
257 " printf(\" (state %%2d)\", z->_p);",
258 " if (!stopstate[z->_t][z->_p])",
259 " printf(\" (invalid end state)\");",
261 " add_src_txt(z->_t, z->_p);",
264 " printf(\"#processes %%d:\\n\", now._nr_pr);",
265 " if (depth < 0) depth = 0;",
266 " for (II = 0; II < now._nr_pr; II++)",
267 " { z = (P0 *)pptr(II);",
268 " printf(\"%%3ld:\tproc %%d (%%s) \",",
269 " depth, II, procname[z->_t]);",
270 " for (i = 0; src_all[i].src; i++)",
271 " if (src_all[i].tp == (int) z->_t)",
272 " { printf(\" line %%3d\",",
273 " src_all[i].src[z->_p]);",
276 " printf(\" (state %%2d)\", z->_p);",
277 " if (!stopstate[z->_t][z->_p])",
278 " printf(\" (invalid end state)\");",
280 " add_src_txt(z->_t, z->_p);",
283 " for (II = 0; II < now._nr_pr; II++)",
284 " { z = (P0 *)pptr(II);",
285 " c_locals(II, z->_t);",
295 " char fnm[512], *q;",
296 " char MyFile[512];",
298 " strcpy(MyFile, TrailFile);", /* avoid problem with non-writable strings */
301 " { sprintf(fnm, \"%%s%%d.%%s\", MyFile, whichtrail, tprefix);",
302 " fd = fopen(fnm, \"r\");",
303 " if (fd == NULL && (q = strchr(MyFile, \'.\')))",
304 " { *q = \'\\0\';", /* e.g., strip .pml on original file */
305 " sprintf(fnm, \"%%s%%d.%%s\", MyFile, whichtrail, tprefix);",
307 " fd = fopen(fnm, \"r\");",
309 " { printf(\"pan: cannot find %%s%%d.%%s or %%s\\n\", ",
310 " MyFile, whichtrail, tprefix, fnm);",
314 " { sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);",
315 " fd = fopen(fnm, \"r\");",
316 " if (fd == NULL && (q = strchr(MyFile, \'.\')))",
317 " { *q = \'\\0\';", /* e.g., strip .pml on original file */
318 " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);",
320 " fd = fopen(fnm, \"r\");",
322 " { printf(\"pan: cannot find %%s.%%s or %%s\\n\", ",
323 " MyFile, tprefix, fnm);",
327 " { printf(\"pan: cannot find trailfile %%s\\n\", fnm);",
333 "uchar do_transit(Trans *, short);",
339 " int i, t_id, lastnever=-1; short II;",
343 " fd = findtrail(); /* exits if unsuccessful */",
344 " while (fscanf(fd, \"%%ld:%%d:%%d\\n\", &depth, &i, &t_id) == 3)",
345 " { if (depth == -1)",
346 " printf(\"<<<<<START OF CYCLE>>>>>\\n\");",
349 " if (i > now._nr_pr)",
350 " { printf(\"pan: Error, proc %%d invalid pid \", i);",
351 " printf(\"transition %%d\\n\", t_id);",
356 " z = (P0 *)pptr(II);",
357 " for (t = trans[z->_t][z->_p]; t; t = t->nxt)",
358 " if (t->t_id == t_id)",
361 " { for (i = 0; i < NrStates[z->_t]; i++)",
362 " { t = trans[z->_t][i];",
363 " if (t && t->t_id == t_id)",
364 " { printf(\" Recovered at state %%d\\n\", i);",
368 " printf(\"pan: Error, proc %%d type %%d state %%d: \",",
369 " II, z->_t, z->_p);",
370 " printf(\"transition %%d not found\\n\", t_id);",
371 " for (t = trans[z->_t][z->_p]; t; t = t->nxt)",
372 " printf(\" t_id %%d -- case %%d, [%%s]\\n\",",
373 " t->t_id, t->forw, t->tp);",
374 " break; /* pan_exit(1); */",
377 " q = transmognify(t->tp);",
378 " if (gui) simvals[0] = \'\\0\';",
381 " trpt->tau |= 1;", /* timeout always possible */
382 " if (!do_transit(t, II))",
383 " { if (onlyproc >= 0 && II != onlyproc)",
385 " printf(\"pan: error, next transition UNEXECUTABLE on replay\\n\");",
386 " printf(\" most likely causes: missing c_track statements\\n\");",
387 " printf(\" or illegal side-effects in c_expr statements\\n\");",
390 " if (onlyproc >= 0 && II != onlyproc)",
394 " { printf(\"depth: %%3ld proc: %%3d trans: %%3d (%%d procs) \",",
395 " depth, II, t_id, now._nr_pr);",
396 " printf(\"forw=%%3d [%%s]\\n\", t->forw, q);",
399 " for (i = 0; i < now._nr_pr; i++)",
400 " { c_locals(i, ((P0 *)pptr(i))->_t);",
403 " if (strcmp(procname[z->_t], \":never:\") == 0)",
404 " { if (lastnever != (int) z->_p)",
405 " { for (i = 0; src_all[i].src; i++)",
406 " if (src_all[i].tp == (int) z->_t)",
407 " { printf(\"MSC: ~G %%d\\n\",",
408 " src_all[i].src[z->_p]);",
411 " if (!src_all[i].src)",
412 " printf(\"MSC: ~R %%d\\n\", z->_p);",
414 " lastnever = z->_p;",
417 " if (strcmp(procname[z->_t], \":np_:\") != 0)",
419 "sameas: if (no_rck) goto moveon;",
421 " { printf(\"%%ld: \", depth);",
422 " for (i = 0; i < II; i++)",
423 " printf(\"\\t\\t\");",
424 " printf(\"%%s(%%d):\", procname[z->_t], II);",
425 " printf(\"[%%s]\\n\", q?q:\"\");",
426 " } else if (!silent)",
427 " { if (strlen(simvals) > 0) {",
428 " printf(\"%%3ld: proc %%2d (%%s)\", ",
429 " depth, II, procname[z->_t]);",
430 " for (i = 0; src_all[i].src; i++)",
431 " if (src_all[i].tp == (int) z->_t)",
432 " { printf(\" line %%3d \\\"pan_in\\\" \",",
433 " src_all[i].src[z->_p]);",
436 " printf(\"(state %%d)\t[values: %%s]\\n\", z->_p, simvals);",
438 " printf(\"%%3ld: proc %%2d (%%s)\", ",
439 " depth, II, procname[z->_t]);",
440 " for (i = 0; src_all[i].src; i++)",
441 " if (src_all[i].tp == (int) z->_t)",
442 " { printf(\" line %%3d \\\"pan_in\\\" \",",
443 " src_all[i].src[z->_p]);",
446 " printf(\"(state %%d)\t[%%s]\\n\", z->_p, q?q:\"\");",
449 "moveon: z->_p = t->st;",
458 " for (i = 0; i < now._nr_pr; i++)",
459 " { z = (P0 *)pptr(i);",
460 " if (z->_t == (unsigned) pt)",
461 " return BASE+z->_pid;",
466 "void check_claim(int);",
472 "bstore_mod(char *v, int n) /* hasharray size not a power of two */",
473 "{ unsigned long x, y;",
474 " unsigned int i = 1;",
476 " d_hash((uchar *) v, n); /* sets j3, j4, K1, K2 */",
479 " { if (!(SS[x%%udmem]&(1<<y))) break;", /* take the hit in speed */
482 " printf(\"Old bitstate\\n\");",
486 " x = (x + K1 + i);", /* no mask, using mod */
487 " y = (y + j4) & 7;",
491 " if (rand()%%100 > RANDSTOR) return 0;",
494 " { SS[x%%udmem] |= (1<<y);",
495 " if (i == hfns) break;", /* done */
496 " x = (x + K1 + i);", /* no mask */
497 " y = (y + j4) & 7;",
501 " printf(\"New bitstate\\n\");",
510 "bstore_reg(char *v, int n) /* extended hashing, Peter Dillinger, 2004 */",
511 "{ unsigned long x, y;",
512 " unsigned int i = 1;",
514 " d_hash((uchar *) v, n); /* sets j1-j4 */",
517 " { if (!(SS[x]&(1<<y))) break;", /* at least one bit not set */
520 " printf(\"Old bitstate\\n\");",
524 " x = (x + j1 + i) & nmask;",
525 " y = (y + j4) & 7;",
529 " if (rand()%%100 > RANDSTOR) return 0;",
532 " { SS[x] |= (1<<y);",
533 " if (i == hfns) break;", /* done */
534 " x = (x + j1 + i) & nmask;",
535 " y = (y + j4) & 7;",
539 " printf(\"New bitstate\\n\");",
547 "unsigned long TMODE = 0666; /* file permission bits for trail files */",
550 "char snap[64], fnm[512];",
556 " char MyFile[512];",
558 " q = strrchr(TrailFile, \'/\');",
559 " if (q == NULL) q = TrailFile; else q++;",
560 " strcpy(MyFile, q); /* TrailFile is not a writable string */",
562 " if (iterative == 0 && Nr_Trails++ > 0)",
563 " sprintf(fnm, \"%%s%%d.%%s\",",
564 " MyFile, Nr_Trails-1, tprefix);",
566 " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);",
568 " if ((fd = creat(fnm, TMODE)) < 0)",
569 " { if ((q = strchr(MyFile, \'.\')))",
570 " { *q = \'\\0\';", /* strip .pml */
571 " if (iterative == 0 && Nr_Trails-1 > 0)",
572 " sprintf(fnm, \"%%s%%d.%%s\",",
573 " MyFile, Nr_Trails-1, tprefix);",
575 " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);",
577 " fd = creat(fnm, TMODE);",
580 " { printf(\"pan: cannot create %%s\\n\", fnm);",
581 " perror(\"cause\");",
583 " { printf(\"pan: wrote %%s\\n\", fnm);",
590 static char *Code2b[] = { /* breadth-first search option */
593 "#ifndef INLINE_REV",
594 "#define INLINE_REV",
597 "typedef struct SV_Hold {",
600 " struct SV_Hold *nxt;",
603 "typedef struct EV_Hold {",
604 " char *sv;", /* Mask */
605 " int sz;", /* vsize */
608 "#if VECTORSZ>32000",
615 " struct EV_Hold *nxt;",
618 "typedef struct BFS_Trail {",
623 " struct H_el *lstate;",
626 " struct BFS_Trail *nxt;",
629 "BFS_Trail *bfs_trail, *bfs_bot, *bfs_free;",
631 "SV_Hold *svhold, *svfree;",
633 "uchar do_reverse(Trans *, short, uchar);",
634 "void snapshot(void);",
638 "{ SV_Hold *h = (SV_Hold *) 0, *oh;",
640 " oh = (SV_Hold *) 0;",
641 " for (h = svfree; h; oh = h, h = h->nxt)",
642 " { if (n == h->sz)",
646 " oh->nxt = h->nxt;",
647 " h->nxt = (SV_Hold *) 0;",
651 " { h = (SV_Hold *) 0;",
654 " /* else continue */",
658 " { h = (SV_Hold *) emalloc(sizeof(SV_Hold));",
660 " h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n);",
668 " static EV_Hold *kept = (EV_Hold *) 0;",
670 " for (h = kept; h; h = h->nxt)",
672 " && (memcmp((char *) Mask, (char *) h->sv, n) == 0)",
673 " && (now._nr_pr == h->nrpr)",
674 " && (now._nr_qs == h->nrqs)",
675 "#if VECTORSZ>32000",
676 " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(int)) == 0)",
677 " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(int)) == 0)",
679 " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(short)) == 0)",
680 " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(short)) == 0)",
682 " && (memcmp((char *) proc_skip, (char *) h->ps, now._nr_pr * sizeof(uchar)) == 0)",
683 " && (memcmp((char *) q_skip, (char *) h->qs, now._nr_qs * sizeof(uchar)) == 0))",
686 " { h = (EV_Hold *) emalloc(sizeof(EV_Hold));",
688 " h->nrpr = now._nr_pr;",
689 " h->nrqs = now._nr_qs;",
691 " h->sv = (char *) emalloc(n * sizeof(char));",
692 " memcpy((char *) h->sv, (char *) Mask, n);",
694 " if (now._nr_pr > 0)",
695 " { h->po = (int *) emalloc(now._nr_pr * sizeof(int));",
696 " h->ps = (int *) emalloc(now._nr_pr * sizeof(int));",
697 "#if VECTORSZ>32000",
698 " memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(int));",
700 " memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(short));",
702 " memcpy((char *) h->ps, (char *) proc_skip, now._nr_pr * sizeof(uchar));",
704 " if (now._nr_qs > 0)",
705 " { h->qo = (int *) emalloc(now._nr_qs * sizeof(int));",
706 " h->qs = (int *) emalloc(now._nr_qs * sizeof(int));",
707 "#if VECTORSZ>32000",
708 " memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(int));",
710 " memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(short));",
712 " memcpy((char *) h->qs, (char *) q_skip, now._nr_qs * sizeof(uchar));",
722 "freesv(SV_Hold *p)",
723 "{ SV_Hold *h, *oh;",
725 " oh = (SV_Hold *) 0;",
726 " for (h = svfree; h; oh = h, h = h->nxt)",
727 " if (h->sz >= p->sz)",
731 " { p->nxt = svfree;",
740 "get_bfs_frame(void)",
745 " bfs_free = bfs_free->nxt;",
746 " t->nxt = (BFS_Trail *) 0;",
748 " { t = (BFS_Trail *) emalloc(sizeof(BFS_Trail));",
750 " t->frame = (Trail *) emalloc(sizeof(Trail));", /* always new */
755 "push_bfs(Trail *f, int d)",
758 " t = get_bfs_frame();",
759 " memcpy((char *)t->frame, (char *)f, sizeof(Trail));",
760 " t->frame->o_tt = d; /* depth */",
763 " t->onow = getsv(vsize);",
764 " memcpy((char *)t->onow->sv, (char *)&now, vsize);",
765 " t->omask = getsv_mask(vsize);",
766 "#if defined(FULLSTACK) && defined(Q_PROVISO)",
767 " t->lstate = Lstate;",
770 " { bfs_bot = bfs_trail = t;",
772 " { bfs_bot->nxt = t;",
776 " printf(\"PUSH %%u (%%d)\\n\", t->frame, d);",
785 " return (Trail *) 0;",
788 " bfs_trail = t->nxt;",
790 " bfs_bot = (BFS_Trail *) 0;",
791 "#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)",
792 " if (t->lstate) t->lstate->tagged = 0;",
795 " t->nxt = bfs_free;",
798 " vsize = t->onow->sz;",
801 " memcpy((uchar *) &now, (uchar *) t->onow->sv, vsize);",
802 " memcpy((uchar *) Mask, (uchar *) t->omask->sv, vsize);",
804 " if (now._nr_pr > 0)",
805 "#if VECTORSZ>32000",
806 " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(int));",
808 " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(short));",
810 " memcpy((char *)proc_skip, (char *)t->omask->ps, now._nr_pr * sizeof(uchar));",
812 " if (now._nr_qs > 0)",
813 "#if VECTORSZ>32000",
814 " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(int));",
816 " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(short));",
818 " memcpy((uchar *)q_skip, (uchar *)t->omask->qs, now._nr_qs * sizeof(uchar));",
821 " freesv(t->onow); /* omask not freed */",
823 " printf(\"POP %%u (%%d)\\n\", t->frame, t->frame->o_tt);",
829 "store_state(Trail *ntrpt, int shortcut, short oboq)",
832 " Trans *t2 = (Trans *) 0;",
833 " uchar ot; int tt, E_state;",
834 " uchar o_opm = trpt->o_pm, *othis = this;",
839 " printf(\"claim: shortcut\\n\");",
841 " goto store_it; /* no claim move */",
844 " this = (((uchar *)&now)+proc_offset[0]); /* 0 = never claim */",
845 " trpt->o_pm = 0;", /* to interpret else in never claim */
847 " tt = (int) ((P0 *)this)->_p;",
848 " ot = (uchar) ((P0 *)this)->_t;",
853 " for (t2 = trans[ot][tt]; t2; t2 = t2?t2->nxt:(Trans *)0)",
857 " && E_state != t2->e_trans)",
860 " if (do_transit(t2, 0))",
863 " if (!reached[ot][t2->st])",
864 " printf(\"depth: %%d -- claim move from %%d -> %%d\\n\",",
865 " trpt->o_tt, ((P0 *)this)->_p, t2->st);",
868 " E_state = t2->e_trans;",
871 " { ((P0 *)this)->_p = t2->st;",
872 " reached[ot][t2->st] = 1;",
874 " check_claim(t2->st);",
877 " if (now._nr_pr == 0) /* claim terminated */",
878 " uerror(\"end state in claim reached\");",
884 " if (t2->atom&2)", /* atomic in claim */
885 " Uerror(\"atomic in claim not supported in BFS mode\");",
891 " if (!bstore((char *)&now, vsize))",
894 " if (!gstore((char *)&now, vsize, 0))",
896 " if (!hstore((char *)&now, vsize))",
901 " trpt->tau |= 64;", /* succ definitely outside stack */
906 " else if (oboq != -1)",
908 " x = (Trail *) trpt->ostate; /* pre-rv state */",
909 " if (x) x->o_pm |= 4; /* mark success */",
912 " push_bfs(ntrpt, trpt->o_tt+1);",
916 "#if !defined(NOREDUCE) && defined(FULLSTACK) && defined(Q_PROVISO)",
917 "#if !defined(QLIST) && !defined(BITSTATE)",
918 " if (Lstate && Lstate->tagged) trpt->tau |= 64;",
920 " if (trpt->tau&32)",
921 " { BFS_Trail *tprov;",
922 " for (tprov = bfs_trail; tprov; tprov = tprov->nxt)",
923 " if (!memcmp((uchar *)&now, (uchar *)tprov->onow->sv, vsize))",
924 " { trpt->tau |= 64;",
925 " break; /* state is in queue */",
931 " ((P0 *)this)->_p = tt; /* reset claim */",
933 " do_reverse(t2, 0, 0);",
938 " trpt->o_pm = o_opm;",
942 "Trail *ntrpt;", /* 4.2.8 */
946 "{ Trans *t; Trail *otrpt, *x;",
947 " uchar _n, _m, ot, nps = 0;",
949 " short II, From = (short) (now._nr_pr-1), To = BASE;",
950 " short oboq = boq;",
952 " ntrpt = (Trail *) emalloc(sizeof(Trail));",
953 " trpt->ostate = (struct H_el *) 0;",
957 " store_state(ntrpt, 0, oboq); /* initial state */",
959 " while ((otrpt = pop_bfs())) /* also restores now */",
960 " { memcpy((char *) trpt, (char *) otrpt, sizeof(Trail));",
961 "#if defined(C_States) && (HAS_TRACK==1)",
962 " c_revert((uchar *) &(now.c_state[0]));",
964 " if (trpt->o_pm & 4)",
967 " printf(\"Revisit of atomic not needed (%%d)\\n\",",
968 " trpt->o_pm);", /* at least 1 rv succeeded */
975 " if (trpt->o_pm == 8)",
980 " printf(\"Break atomic (pm:%%d,tau:%%d)\\n\",",
981 " trpt->o_pm, trpt->tau);",
986 " else if (trpt->tau&32)", /* was a preselected move */
989 " printf(\"Void preselection (pm:%%d,tau:%%d)\\n\",",
990 " trpt->o_pm, trpt->tau);",
992 " trpt->tau &= ~32;",
993 " nps = 1; /* no preselection in repeat */",
997 " trpt->o_pm &= ~(4|8);",
998 " if (trpt->o_tt > mreached)",
999 " { mreached = trpt->o_tt;",
1000 " if (mreached%%10 == 0)",
1001 " { printf(\"Depth= %%7d States= %%7g \", mreached, nstates);",
1002 " printf(\"Transitions= %%7g \", nstates+truncs);",
1004 " printf(\"Nodes= %%7d \", nr_states);",
1006 " printf(\"Memory= %%-6.3f\\n\", memcnt/1000000.);",
1009 " depth = trpt->o_tt;",
1011 " if (depth >= maxdepth)",
1016 " { x = (Trail *) trpt->ostate;",
1017 " if (x) x->o_pm |= 4; /* not failing */",
1023 " printf(\"error: max search depth too small\\n\");",
1026 " uerror(\"depth limit reached\");",
1032 " if (boq == -1 && !(trpt->tau&8) && nps == 0)",
1033 " for (II = now._nr_pr-1; II >= BASE; II -= 1)",
1035 "Pickup: this = pptr(II);",
1036 " tt = (int) ((P0 *)this)->_p;",
1037 " ot = (uchar) ((P0 *)this)->_t;",
1038 " if (trans[ot][tt]->atom & 8)", /* safe */
1039 " { t = trans[ot][tt];",
1040 " if (t->qu[0] != 0)",
1042 " if (!q_cond(II, t))",
1047 " trpt->tau |= 32; /* preselect marker */",
1049 " printf(\"%%3d: proc %%d PreSelected (tau=%%d)\\n\", ",
1050 " depth, II, trpt->tau);",
1054 " trpt->tau &= ~32;", /* not preselected */
1058 " if (trpt->tau&8) /* atomic */",
1059 " { From = To = (short ) trpt->pr;",
1062 " { From = now._nr_pr-1;",
1067 " for (II = From; II >= To; II -= 1)",
1069 " this = (((uchar *)&now)+proc_offset[II]);",
1070 " tt = (int) ((P0 *)this)->_p;",
1071 " ot = (uchar) ((P0 *)this)->_t;",
1073 " /* no rendezvous with same proc */",
1074 " if (boq != -1 && trpt->pr == II) continue;",
1076 " ntrpt->pr = (uchar) II;",
1077 " ntrpt->st = tt; ",
1078 " trpt->o_pm &= ~1; /* no move yet */",
1079 "#ifdef EVENT_TRACE",
1080 " trpt->o_event = now._event;",
1082 "#ifdef HAS_PROVIDED",
1083 " if (!provided(II, ot, tt, t)) continue;",
1085 "#ifdef HAS_UNLESS",
1088 " for (t = trans[ot][tt]; t; t = t->nxt)",
1090 "#ifdef HAS_UNLESS",
1092 " && E_state != t->e_trans)",
1099 " if (!(_m = do_transit(t, II)))",
1102 " trpt->o_pm |= 1; /* we moved */",
1103 " (trpt+1)->o_m = _m; /* for unsend */",
1108 " printf(\"%%3d: proc %%d exec %%d, \",",
1109 " depth, II, t->forw);",
1110 " printf(\"%%d to %%d, %%s %%s %%s\",",
1111 " tt, t->st, t->tp,",
1112 " (t->atom&2)?\"atomic\":\"\",",
1113 " (boq != -1)?\"rendez-vous\":\"\");",
1114 "#ifdef HAS_UNLESS",
1116 " printf(\" (escapes to state %%d)\", t->st);",
1118 " printf(\" %%saccepting [tau=%%d]\\n\",",
1119 " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);",
1121 "#ifdef HAS_UNLESS",
1122 " E_state = t->e_trans;",
1124 " if (t->e_trans > 0 && (boq != -1 /* || oboq != -1 */))",
1125 " { fprintf(efd, \"error:\tthe use of rendezvous stmnt in the escape clause\\n\");",
1126 " fprintf(efd, \"\tof an unless stmnt is not compatible with -DBFS\\n\");",
1131 " if (t->st > 0) ((P0 *)this)->_p = t->st;",
1133 " /* ptr to pred: */ ntrpt->ostate = (struct H_el *) otrpt;",
1135 " if (boq == -1 && (t->atom&2)) /* atomic */",
1136 " ntrpt->tau = 8; /* record for next move */",
1140 " store_state(ntrpt, (boq != -1 || (t->atom&2)), oboq);",
1141 "#ifdef EVENT_TRACE",
1142 " now._event = trpt->o_event;",
1145 " /* undo move and continue */",
1146 " trpt++; /* this is where ovals and ipt are set */",
1147 " do_reverse(t, II, _m); /* restore now. */",
1150 " printf(\"%%3d: proc %%d \", depth, II);",
1151 " printf(\"reverses %%d, %%d to %%d,\",",
1152 " t->forw, tt, t->st);",
1153 " printf(\" %%s [abit=%%d,adepth=%%d,\",",
1154 " t->tp, now._a_t, A_depth);",
1155 " printf(\"tau=%%d,%%d]\\n\",",
1156 " trpt->tau, (trpt-1)->tau);",
1158 " reached[ot][t->st] = 1;",
1159 " reached[ot][tt] = 1;",
1161 " ((P0 *)this)->_p = tt;",
1166 " /* preselected - no succ definitely outside stack */",
1167 " if ((trpt->tau&32) && !(trpt->tau&64))",
1168 " { From = now._nr_pr-1; To = BASE;",
1170 " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ",
1171 " depth, II+1, (int) _n, trpt->tau);",
1173 " _n = 0; trpt->tau &= ~32;",
1178 " trpt->tau &= ~(32|64);",
1184 " printf(\"%%3d: no move [II=%%d, tau=%%d, boq=%%d, _nr_pr=%%d]\\n\",",
1185 " depth, II, trpt->tau, boq, now._nr_pr);",
1189 " x = (Trail *) trpt->ostate; /* pre-rv state */",
1190 " if (!x) continue; /* root state */",
1191 " if ((x->tau&8) || (x->tau&32)) /* break atomic or preselect at parent */",
1192 " { x->o_pm |= 8; /* mark failure */",
1193 " this = (((uchar *)&now)+proc_offset[otrpt->pr]);",
1195 " printf(\"\\treset state of %%d from %%d to %%d\\n\",",
1196 " otrpt->pr, ((P0 *)this)->_p, otrpt->st);",
1198 " ((P0 *)this)->_p = otrpt->st;",
1199 " unsend(boq); /* retract rv offer */",
1202 " push_bfs(x, x->o_tt);",
1204 " printf(\"failed rv, repush with %%d\\n\", x->o_pm);",
1208 " else printf(\"failed rv, tau at parent: %%d\\n\", x->tau);",
1210 " } else if (now._nr_pr > 0)",
1212 " if ((trpt->tau&8)) /* atomic */",
1213 " { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */",
1215 " printf(\"%%3d: atomic step proc %%d blocks\\n\",",
1221 " if (!(trpt->tau&1)) /* didn't try timeout yet */",
1222 " { trpt->tau |= 1;",
1224 " printf(\"%%d: timeout\\n\", depth);",
1229 " if (!noends && !a_cycles && !endstate())",
1230 " uerror(\"invalid end state\");",
1236 "putter(Trail *trpt, int fd)",
1239 " if (!trpt) return;",
1241 " if (trpt != (Trail *) trpt->ostate)",
1242 " putter((Trail *) trpt->ostate, fd);",
1245 " { sprintf(snap, \"%%d:%%d:%%d\\n\",",
1246 " trcnt++, trpt->pr, trpt->o_t->t_id);",
1247 " j = strlen(snap);",
1248 " if (write(fd, snap, j) != j)",
1249 " { printf(\"pan: error writing %%s\\n\", fnm);",
1255 "nuerror(char *str)",
1256 "{ int fd = make_trail();",
1259 " if (fd < 0) return;",
1261 " sprintf(snap, \"-2:%%d:-2\\n\", VERI);",
1262 " write(fd, snap, strlen(snap));",
1265 " sprintf(snap, \"-4:-4:-4\\n\");",
1266 " write(fd, snap, strlen(snap));",
1269 " putter(trpt, fd);",
1270 " if (ntrpt->o_t)", /* 4.2.8 -- Alex example, missing last transition */
1271 " { sprintf(snap, \"%%d:%%d:%%d\\n\",",
1272 " trcnt++, ntrpt->pr, ntrpt->o_t->t_id);",
1273 " j = strlen(snap);",
1274 " if (write(fd, snap, j) != j)",
1275 " { printf(\"pan: error writing %%s\\n\", fnm);",
1279 " if (errors >= upto && upto != 0)",
1288 static char *Code2c[] = {
1290 "do_the_search(void)",
1292 " depth = mreached = 0;",
1293 " trpt = &trail[0];",
1295 " trpt->tau |= 4; /* the claim moves first */",
1297 " for (i = 0; i < (int) now._nr_pr; i++)",
1298 " { P0 *ptr = (P0 *) pptr(i);",
1300 " if (!(trpt->o_pm&2)",
1301 " && accpstate[ptr->_t][ptr->_p])",
1302 " { trpt->o_pm |= 2;",
1305 " if (!(trpt->o_pm&4)",
1306 " && progstate[ptr->_t][ptr->_p])",
1307 " { trpt->o_pm |= 4;",
1311 "#ifdef EVENT_TRACE",
1313 " if (accpstate[EVENT_TRACE][now._event])",
1314 " { trpt->o_pm |= 2;",
1317 " if (progstate[EVENT_TRACE][now._event])",
1318 " { trpt->o_pm |= 4;",
1323 " Mask[0] = Mask[1] = 1; /* _nr_pr, _nr_qs */",
1325 " { i = &(now._a_t) - (uchar *) &now;",
1326 " Mask[i] = 1; /* _a_t */",
1331 " i = &(now._cnt[0]) - (uchar *) &now;",
1332 " while (j++ < NFAIR)",
1333 " Mask[i++] = 1; /* _cnt[] */",
1339 " && (a_cycles && (trpt->o_pm&2)))",
1340 " { now._a_t = 2; /* set the A-bit */",
1341 " now._cnt[0] = now._nr_pr + 1;", /* NEW: +1 */
1343 " printf(\"%%3d: fairness Rule 1, cnt=%%d, _a_t=%%d\\n\",",
1344 " depth, now._cnt[now._a_t&1], now._a_t);",
1349 "#if defined(C_States) && (HAS_TRACK==1)",
1350 " /* capture initial state of tracked C objects */",
1351 " c_update((uchar *) &(now.c_state[0]));",
1355 " if (readtrail) getrail(); /* no return */",
1360 "#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)",
1361 " /* initial state of tracked & unmatched objects */",
1362 " c_stack((uchar *) &(svtack->c_stack[0]));",
1367 " new_state(); /* start 1st DFS */",
1371 "#ifdef INLINE_REV",
1373 "do_reverse(Trans *t, short II, uchar M)",
1375 " int tt = (int) ((P0 *)this)->_p;",
1376 "#include REVERSE_MOVES",
1382 "#ifdef EVENT_TRACE",
1383 "static char _tp = 'n'; static int _qid = 0;",
1386 "do_transit(Trans *t, short II)",
1388 " int tt = (int) ((P0 *)this)->_p;",
1390 " uchar delta_m = 0;",
1392 "#ifdef EVENT_TRACE",
1393 " short oboq = boq;",
1394 " uchar ot = (uchar) ((P0 *)this)->_t;",
1395 " if (ot == EVENT_TRACE) boq = -1;",
1396 "#define continue { boq = oboq; return 0; }",
1398 "#define continue return 0",
1400 " uchar ot = (uchar) ((P0 *)this)->_t;",
1403 "#include FORWARD_MOVES",
1405 "#ifdef EVENT_TRACE",
1406 " if (ot == EVENT_TRACE) boq = oboq;",
1412 "#ifdef EVENT_TRACE",
1414 "require(char tp, int qid)",
1416 " _tp = tp; _qid = qid;",
1418 " if (now._event != endevent)",
1419 " for (t = trans[EVENT_TRACE][now._event]; t; t = t->nxt)",
1420 " { if (do_transit(t, EVENT_TRACE))",
1421 " { now._event = t->st;",
1422 " reached[EVENT_TRACE][t->st] = 1;",
1424 " printf(\" event_trace move to -> %%d\\n\", t->st);",
1428 " if (accpstate[EVENT_TRACE][now._event])",
1429 " (trpt+1)->o_pm |= 2;",
1431 " if (progstate[EVENT_TRACE][now._event])",
1432 " (trpt+1)->o_pm |= 4;",
1435 "#ifdef NEGATED_TRACE",
1436 " if (now._event == endevent)",
1439 " depth++; trpt++;",
1441 " uerror(\"event_trace error (all events matched)\");",
1443 " trpt--; depth--;",
1448 " for (t = t->nxt; t; t = t->nxt)",
1449 " { if (do_transit(t, EVENT_TRACE))",
1450 " Uerror(\"non-determinism in event-trace\");",
1456 " printf(\" event_trace miss '%%c' -- %%d, %%d, %%d\\n\",",
1457 " tp, qid, now._event, t->forw);",
1460 "#ifdef NEGATED_TRACE",
1461 " now._event = endevent; /* only 1st try will count -- fixed 4.2.6 */",
1464 " depth++; trpt++;",
1466 " uerror(\"event_trace error (no matching event)\");",
1468 " trpt--; depth--;",
1475 "enabled(int iam, int pid)",
1476 "{ Trans *t; uchar *othis = this;",
1477 " int res = 0; int tt; uchar ot;",
1479 " /* if (pid > 0) */ pid++;",
1482 " Uerror(\"used: enabled(pid=thisproc)\");",
1483 " if (pid < 0 || pid >= (int) now._nr_pr)",
1485 " this = pptr(pid);",
1487 " tt = (int) ((P0 *)this)->_p;",
1488 " ot = (uchar) ((P0 *)this)->_t;",
1489 " for (t = trans[ot][tt]; t; t = t->nxt)",
1490 " if (do_transit(t, (short) pid))",
1501 "{ static long sdone = (long) 0;",
1502 " long ndone = (unsigned long) nstates/1000000;",
1503 " if (ndone == sdone) return;",
1505 " printf(\"Depth= %%7d States= %%7g \", mreached, nstates);",
1506 " printf(\"Transitions= %%7g \", nstates+truncs);",
1508 " printf(\"Nodes= %%7d \", nr_states);",
1510 " printf(\"Memory= %%-6.3f\\n\", memcnt/1000000.);",
1519 " && (stackwrite = creat(stackfile, TMODE)) < 0)",
1520 " Uerror(\"cannot create stackfile\");",
1522 " if (write(stackwrite, trail, DDD*sizeof(Trail))",
1523 " != DDD*sizeof(Trail))",
1524 " Uerror(\"stackfile write error -- disk is full?\");",
1526 " memmove(trail, &trail[DDD], (HHH-DDD+2)*sizeof(Trail));",
1527 " memset(&trail[HHH-DDD+2], 0, (omaxdepth - HHH + DDD - 2)*sizeof(Trail));",
1535 " memmove(&trail[DDD], trail, (HHH-DDD+2)*sizeof(Trail));",
1538 " || lseek(stackwrite, -DDD* (off_t) sizeof(Trail), SEEK_CUR) == -1)",
1539 " Uerror(\"disk2stack lseek error\");",
1542 " && (stackread = open(stackfile, 0)) < 0)",
1543 " Uerror(\"cannot open stackfile\");",
1545 " if (lseek(stackread, (CNT1-CNT2)*DDD* (off_t) sizeof(Trail), SEEK_SET) == -1)",
1546 " Uerror(\"disk2stack lseek error\");",
1548 " have = read(stackread, trail, DDD*sizeof(Trail));",
1549 " if (have != DDD*sizeof(Trail))",
1550 " Uerror(\"stackfile read error\");",
1555 "Pptr(int x)", /* as a fct, to avoid a problem with the p9 compiler */
1556 "{ if (x < 0 || x >= MAXPROC || !proc_offset[x])", /* does not exist */
1559 " return (uchar *) pptr(x);",
1561 "int qs_empty(void);",
1564 " * new_state() is the main DFS search routine in the verifier",
1565 " * it has a lot of code ifdef-ed together to support",
1566 " * different search modes, which makes it quite unreadable.",
1567 " * if you are studying the code, first use the C preprocessor",
1568 " * to generate a specific version from the pan.c source,",
1569 " * e.g. by saying:",
1570 " * gcc -E -DNOREDUCE -DBITSTATE pan.c > ppan.c",
1571 " * and then study the resulting file, rather than this one",
1573 "#if !defined(BFS) && (!defined(BITSTATE) || !defined(MA))",
1577 " uchar _n, _m, ot;",
1582 " uchar delta_m = 0;",
1584 " short II, JJ = 0, kk;",
1586 " short From = now._nr_pr-1, To = BASE;",
1589 " printf(\"%%d: Down - %%s\",",
1590 " depth, (trpt->tau&4)?\"claim\":\"program\");",
1591 " printf(\" %%saccepting [pids %%d-%%d]\\n\",",
1592 " (trpt->o_pm&2)?\"\":\"non-\", From, To);",
1596 " if (depth > hiwater)",
1598 " maxdepth += DDD;",
1602 " printf(\"zap %%d: %%d (maxdepth now %%d)\\n\",",
1603 " CNT1, hiwater, maxdepth);",
1607 " trpt->tau &= ~(16|32|64); /* make sure these are off */",
1608 "#if defined(FULLSTACK) && defined(MA)",
1609 " trpt->proviso = 0;",
1611 " if (depth >= maxdepth)",
1614 " (trpt+1)->o_n = 1; /* not a deadlock */",
1618 " printf(\"error: max search depth too small\\n\");",
1620 " if (bounded) uerror(\"depth limit reached\");",
1621 " (trpt-1)->tau |= 16; /* worstcase guess */",
1625 "#if defined(FULLSTACK) && !defined(MA)",
1626 " /* if atomic or rv move, carry forward previous state */",
1627 " trpt->ostate = (trpt-1)->ostate;", /* was: = (struct H_el *) 0;*/
1630 " if ((trpt->tau&4) || ((trpt-1)->tau&128))",
1632 " if (boq == -1) { /* if not mid-rv */",
1634 " /* this check should now be redundant",
1635 " * because the seed state also appears",
1636 " * on the 1st dfs stack and would be",
1637 " * matched in hstore below",
1639 " if ((now._a_t&1) && depth > A_depth)",
1640 " { if (!memcmp((char *)&A_Root, ",
1641 " (char *)&now, vsize))",
1643 " depthfound = A_depth;",
1645 " printf(\"matches seed\\n\");",
1648 " uerror(\"non-progress cycle\");",
1650 " uerror(\"acceptance cycle\");",
1655 " printf(\"not seed\\n\");",
1659 " if (!(trpt->tau&8)) /* if no atomic move */",
1662 "#ifdef CNTRSTACK", /* -> bitstate, reduced, safety */
1663 " II = bstore((char *)&now, vsize);",
1664 " trpt->j6 = j1; trpt->j7 = j2;",
1665 " JJ = LL[j1] && LL[j2];",
1668 " JJ = onstack_now();", /* sets j1 */
1671 " JJ = II; /* worstcase guess for p.o. */",
1674 " II = bstore((char *)&now, vsize);", /* sets j1-j4 */
1678 " II = gstore((char *)&now, vsize, 0);",
1679 "#ifndef FULLSTACK",
1682 " JJ = (II == 2)?1:0;",
1685 " II = hstore((char *)&now, vsize);",
1687 " JJ = (II == 2)?1:0;",
1691 " kk = (II == 1 || II == 2);",
1692 /* II==0 new state */
1693 /* II==1 old state */
1694 /* II==2 on current dfs stack */
1695 /* II==3 on 1st dfs stack */
1698 " if (!fairness && a_cycles)",
1699 " if (II == 2 && ((trpt->o_pm&2) || ((trpt-1)->o_pm&2)))",
1700 " { II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */",
1702 " printf(\"state match on dfs stack\\n\");",
1708 "#if defined(FULLSTACK) && defined(BITSTATE)",
1709 " if (!JJ && (now._a_t&1) && depth > A_depth)",
1711 " uchar o_a_t = now._a_t;",
1712 " now._a_t &= ~(1|16|32);", /* 1st stack */
1713 " if (onstack_now())", /* changes j1 */
1716 " printf(\"state match on 1st dfs stack\\n\");",
1719 " now._a_t = o_a_t;", /* restore */
1723 " if (II == 3 && a_cycles && (now._a_t&1))",
1726 " if (fairness && now._cnt[1] > 1) /* was != 0 */",
1729 " printf(\"\tfairness count non-zero\\n\");",
1731 " II = 0;", /* treat as new state */
1738 "same_case: if (Lstate) depthfound = Lstate->D;",
1740 " uerror(\"non-progress cycle\");",
1742 " uerror(\"acceptance cycle\");",
1751 " if ((II && JJ) || (II == 3))",
1752 " { /* marker for liveness proviso */",
1753 " (trpt-1)->tau |= 16;",
1758 " { /* successor outside stack */",
1759 " (trpt-1)->tau |= 64;",
1769 " if ((unsigned long) nstates%%1000000 == 0)",
1772 " if (vprefix > 0)",
1773 " if (write(svfd, (uchar *) &now, vprefix) != vprefix)",
1774 " { fprintf(efd, \"writing %%s.svd failed\\n\", Source);",
1778 "#if defined(MA) && defined(W_XPT)",
1779 " if ((unsigned long) nstates%%W_XPT == 0)",
1780 " { void w_xpoint(void);",
1785 "#if defined(FULLSTACK) || defined(CNTRSTACK)",
1788 "#if defined(FULLSTACK) && !defined(MA)",
1789 " printf(\"%%d: putting %%u (%%d)\\n\", depth,",
1791 " (trpt->ostate)?trpt->ostate->tagged:0);",
1793 " printf(\"%%d: putting\\n\", depth);",
1800 " if (depth > mreached)",
1801 " mreached = depth;",
1803 " if (trpt->tau&4)",
1805 " trpt->tau &= ~(1|2); /* timeout and -request off */",
1808 " (trpt+1)->o_n = 0;",
1811 " if (now._nr_pr == 0) /* claim terminated */",
1812 " uerror(\"end state in claim reached\");",
1813 " check_claim(((P0 *)pptr(0))->_p);",
1815 " if (trpt->tau&4) /* must make a claimmove */",
1819 " if ((now._a_t&2) /* A-bit set */",
1820 " && now._cnt[now._a_t&1] == 1)",
1821 " { now._a_t &= ~2;",
1822 " now._cnt[now._a_t&1] = 0;",
1823 " trpt->o_pm |= 16;",
1825 " printf(\"%%3d: fairness Rule 3.: _a_t = %%d\\n\",",
1826 " depth, now._a_t);",
1831 " II = 0; /* never */",
1836 " /* Look for a process with only safe transitions */",
1837 " /* (special rules apply in the 2nd dfs) */",
1839 " if (boq == -1 && From != To)",
1841 "/* implied: #ifdef FULLSTACK */",
1842 " if (boq == -1 && From != To",
1843 " && (!(now._a_t&1)",
1848 " !((trpt-1)->proviso))",
1850 " !(trpt->proviso))",
1854 " (trpt-1)->ostate &&",
1855 " !(((char *)&((trpt-1)->ostate->state))[0] & 128))",
1857 " !(((char *)&(trpt->ostate->state))[0] & 128))",
1862 " (trpt-1)->ostate &&",
1863 " (trpt-1)->ostate->proviso == 0)",
1865 " trpt->ostate->proviso == 0)",
1871 " for (II = From; II >= To; II -= 1)",
1873 "Resume: /* pick up here if preselect fails */",
1874 " this = pptr(II);",
1875 " tt = (int) ((P0 *)this)->_p;",
1876 " ot = (uchar) ((P0 *)this)->_t;",
1877 " if (trans[ot][tt]->atom & 8)",
1878 " { t = trans[ot][tt];",
1879 " if (t->qu[0] != 0)",
1881 " if (!q_cond(II, t))",
1889 " trpt->tau |= 32; /* preselect marker */",
1892 " printf(\"%%3d: proc %%d Pre\", depth, II);",
1893 " printf(\"Selected (om=%%d, tau=%%d)\\n\", ",
1894 " t->om, trpt->tau);",
1896 " printf(\"%%3d: proc %%d PreSelected (tau=%%d)\\n\", ",
1897 " depth, II, trpt->tau);",
1903 " trpt->tau &= ~32;",
1905 "#if !defined(NOREDUCE) || (defined(ETIM) && !defined(VERI))",
1908 " /* The Main Expansion Loop over Processes */",
1910 " trpt->o_pm &= ~(8|16|32|64); /* fairness-marks */",
1913 " if (fairness && boq == -1",
1915 " && (!(trpt->tau&4) && !((trpt-1)->tau&128))",
1917 " && !(trpt->tau&8))",
1918 " { /* A_bit = 1; Cnt = N in acc states with A_bit 0 */",
1919 " if (!(now._a_t&2))", /* A-bit not set */
1921 " if (a_cycles && (trpt->o_pm&2))",
1922 " { /* Accepting state */",
1924 " now._cnt[now._a_t&1] = now._nr_pr + 1;", /* NEW +1 */
1925 " trpt->o_pm |= 8;",
1927 " printf(\"%%3d: fairness Rule 1: cnt=%%d, _a_t=%%d\\n\",",
1928 " depth, now._cnt[now._a_t&1], now._a_t);",
1931 " } else", /* A-bit set */
1932 " { /* A_bit = 0 when Cnt 0 */",
1933 " if (now._cnt[now._a_t&1] == 1)", /* NEW: 1 iso 0 */
1934 " { now._a_t &= ~2;", /* reset a-bit */
1935 " now._cnt[now._a_t&1] = 0;", /* NEW: reset cnt */
1936 " trpt->o_pm |= 16;",
1938 " printf(\"%%3d: fairness Rule 3: _a_t = %%d\\n\",",
1939 " depth, now._a_t);",
1944 " for (II = From; II >= To; II -= 1)",
1947 " /* no rendezvous with same proc */",
1948 " if (boq != -1 && trpt->pr == II) continue;",
1953 " this = pptr(II);",
1954 " tt = (int) ((P0 *)this)->_p;",
1955 " ot = (uchar) ((P0 *)this)->_t;",
1958 " /* don't repeat a previous preselected expansion */",
1959 " /* could hit this if reduction proviso was false */",
1960 " t = trans[ot][tt];",
1961 " if (!(trpt->tau&4)", /* not claim */
1962 " && !(trpt->tau&1)", /* not timeout */
1963 " && !(trpt->tau&32)", /* not preselected */
1964 " && (t->atom & 8)", /* local */
1965 " && boq == -1", /* not inside rendezvous */
1966 " && From != To)", /* not inside atomic seq */
1967 " { if (t->qu[0] == 0", /* unconditional */
1968 " || q_cond(II, t))", /* true condition */
1970 " if (_m>_n||(_n>3&&_m!=0)) _n=_m;",
1971 " continue; /* did it before */",
1974 " trpt->o_pm &= ~1; /* no move in this pid yet */",
1975 "#ifdef EVENT_TRACE",
1976 " (trpt+1)->o_event = now._event;",
1978 " /* Fairness: Cnt++ when Cnt == II */",
1980 " trpt->o_pm &= ~64; /* didn't apply rule 2 */",
1982 " && boq == -1", /* not mid rv - except rcv - NEW 3.0.8 */
1983 " && !(trpt->o_pm&32)", /* Rule 2 not in effect */
1984 " && (now._a_t&2)", /* A-bit is set */
1985 " && now._cnt[now._a_t&1] == II+2)",
1986 " { now._cnt[now._a_t&1] -= 1;",
1988 " /* claim need not participate */",
1990 " now._cnt[now._a_t&1] = 1;",
1993 " printf(\"%%3d: proc %%d fairness \", depth, II);",
1994 " printf(\"Rule 2: --cnt to %%d (%%d)\\n\",",
1995 " now._cnt[now._a_t&1], now._a_t);",
1997 " trpt->o_pm |= (32|64);",
2000 "#ifdef HAS_PROVIDED",
2001 " if (!provided(II, ot, tt, t)) continue;",
2003 " /* check all trans of proc II - escapes first */",
2004 "#ifdef HAS_UNLESS",
2005 " trpt->e_state = 0;",
2007 " (trpt+1)->pr = (uchar) II;", /* for uerror */
2008 " (trpt+1)->st = tt;",
2011 " for (ooi = eoi = 0, t = trans[ot][tt]; t; t = t->nxt, ooi++)",
2012 " if (strcmp(t->tp, \"else\") == 0)",
2016 " { t = trans[ot][tt];",
2018 " printf(\"randomizer: suppressed, saw else\\n\");",
2021 " { eoi = rand()%%ooi;",
2023 " printf(\"randomizer: skip %%d in %%d\\n\", eoi, ooi);",
2025 " for (t = trans[ot][tt]; t; t = t->nxt)",
2026 " if (eoi-- <= 0) break;",
2029 " for ( ; t && ooi > 0; t = t->nxt, ooi--)",
2031 " for (t = trans[ot][tt]; t; t = t->nxt)",
2034 "#ifdef HAS_UNLESS",
2035 " /* exploring all transitions from",
2036 " * a single escape state suffices",
2038 " if (trpt->e_state > 0",
2039 " && trpt->e_state != t->e_trans)",
2042 " printf(\"skip 2nd escape %%d (did %%d before)\\n\",",
2043 " t->e_trans, trpt->e_state);",
2048 " (trpt+1)->o_t = t;", /* for uerror */
2050 "#include FORWARD_MOVES",
2051 "P999: /* jumps here when move succeeds */",
2053 " if (!(_m = do_transit(t, II))) continue;",
2057 " /* for branching-time, can accept reduction only if */",
2058 " /* the persistent set contains just 1 transition */",
2059 " { if ((trpt->tau&32) && (trpt->o_pm&1))",
2060 " trpt->tau |= 16;",
2061 " trpt->o_pm |= 1; /* we moved */",
2064 " trpt->o_pm |= 1; /* we moved */",
2070 "#if defined(VERBOSE) || defined(CHECK)",
2071 "#if defined(SVDUMP)",
2072 " printf(\"%%3d: proc %%d exec %%d \\n\", ",
2073 " depth, II, t->t_id);",
2075 " printf(\"%%3d: proc %%d exec %%d, \", ",
2076 " depth, II, t->forw);",
2077 " printf(\"%%d to %%d, %%s %%s %%s\", ",
2078 " tt, t->st, t->tp,",
2079 " (t->atom&2)?\"atomic\":\"\",",
2080 " (boq != -1)?\"rendez-vous\":\"\");",
2081 "#ifdef HAS_UNLESS",
2083 " printf(\" (escapes to state %%d)\",",
2086 " printf(\" %%saccepting [tau=%%d]\\n\",",
2087 " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);",
2090 " printf(\" randomizer %%d\\n\", ooi);",
2098 " now._last = II - BASE;",
2100 "#ifdef HAS_UNLESS",
2101 " trpt->e_state = t->e_trans;",
2104 " depth++; trpt++;",
2105 " trpt->pr = (uchar) II;",
2107 " trpt->o_pm &= ~(2|4);",
2109 " { ((P0 *)this)->_p = t->st;",
2110 "/* moved down reached[ot][t->st] = 1; */",
2115 "#if (ACCEPT_LAB>0 && !defined(NP)) || (PROG_LAB>0 && defined(HAS_NP))",
2118 "#define P__Q ((P0 *)pptr(ii))",
2121 " /* state 1 of np_ claim is accepting */",
2122 " if (((P0 *)pptr(0))->_p == 1)",
2123 " trpt->o_pm |= 2;",
2125 " for (ii = 0; ii < (int) now._nr_pr; ii++)",
2126 " { if (accpstate[P__Q->_t][P__Q->_p])",
2127 " { trpt->o_pm |= 2;",
2132 "#if defined(HAS_NP) && PROG_LAB>0",
2133 " for (ii = 0; ii < (int) now._nr_pr; ii++)",
2134 " { if (progstate[P__Q->_t][P__Q->_p])",
2135 " { trpt->o_pm |= 4;",
2142 " trpt->o_t = t; trpt->o_n = _n;",
2143 " trpt->o_ot = ot; trpt->o_tt = tt;",
2144 " trpt->o_To = To; trpt->o_m = _m;",
2147 " trpt->oo_i = ooi;",
2149 " if (boq != -1 || (t->atom&2))",
2150 " { trpt->tau |= 8;",
2152 " /* atomic sequence in claim */",
2153 " if((trpt-1)->tau&4)",
2156 " trpt->tau &= ~4;",
2158 " { if ((trpt-1)->tau&4)",
2159 " trpt->tau &= ~4;",
2163 " /* if claim allowed timeout, so */",
2164 " /* does the next program-step: */",
2165 " if (((trpt-1)->tau&1) && !(trpt->tau&4))",
2169 " trpt->tau &= ~8;",
2171 " if (boq == -1 && (t->atom&2))",
2172 " { From = To = II; nlinks++;",
2174 " { From = now._nr_pr-1; To = BASE;",
2176 " goto Down; /* pseudo-recursion */",
2179 " printf(\"%%d: Up - %%s\\n\", depth,",
2180 " (trpt->tau&4)?\"claim\":\"program\");",
2183 " if (depth <= 0) return;",
2184 " /* e.g., if first state is old, after a restart */",
2189 " && depth < hiwater - (HHH-DDD) + 2)",
2193 " maxdepth -= DDD;",
2196 "printf(\"unzap %%d: %%d\\n\", CNT2, hiwater);",
2201 " if (trpt->o_pm&128) /* fairness alg */",
2202 " { now._cnt[now._a_t&1] = trpt->bup.oval;",
2203 " _n = 1; trpt->o_pm &= ~128;",
2204 " depth--; trpt--;",
2205 "#if defined(VERBOSE) || defined(CHECK)",
2206 " printf(\"%%3d: reversed fairness default move\\n\", depth);",
2214 " { int d; Trail *trl;",
2216 " for (d = 1; d < depth; d++)",
2217 " { trl = getframe(depth-d); /* was (trpt-d) */",
2218 " if (trl->pr != 0)",
2219 " { now._last = trl->pr - BASE;",
2223 " now._last = (depth<1)?0:(trpt-1)->pr;",
2226 "#ifdef EVENT_TRACE",
2227 " now._event = trpt->o_event;",
2230 " if ((now._a_t&1) && depth <= A_depth)",
2231 " return; /* to checkcycles() */",
2233 " t = trpt->o_t; _n = trpt->o_n;",
2234 " ot = trpt->o_ot; II = trpt->pr;",
2235 " tt = trpt->o_tt; this = pptr(II);",
2236 " To = trpt->o_To; _m = trpt->o_m;",
2238 " ooi = trpt->oo_i;",
2240 "#ifdef INLINE_REV",
2241 " _m = do_reverse(t, II, _m);",
2243 "#include REVERSE_MOVES",
2244 "R999: /* jumps here when done */",
2248 " printf(\"%%3d: proc %%d \", depth, II);",
2249 " printf(\"reverses %%d, %%d to %%d,\",",
2250 " t->forw, tt, t->st);",
2251 " printf(\" %%s [abit=%%d,adepth=%%d,\", ",
2252 " t->tp, now._a_t, A_depth);",
2253 " printf(\"tau=%%d,%%d]\\n\", ",
2254 " trpt->tau, (trpt-1)->tau);",
2257 " /* pass the proviso tags */",
2258 " if ((trpt->tau&8) /* rv or atomic */",
2259 " && (trpt->tau&16))",
2260 " (trpt-1)->tau |= 16;",
2262 " if ((trpt->tau&8) /* rv or atomic */",
2263 " && (trpt->tau&64))",
2264 " (trpt-1)->tau |= 64;",
2267 " depth--; trpt--;",
2269 " (trans[ot][tt])->om = _m; /* head of list */",
2272 " /* i.e., not set if rv fails */",
2275 "#if defined(VERI) && !defined(NP)",
2276 " if (II == 0 && verbose && !reached[ot][t->st])",
2278 " printf(\"depth %%d: Claim reached state %%d (line %%d)\\n\",",
2279 " depth, t->st, src_claim [t->st]);",
2283 " reached[ot][t->st] = 1;",
2284 " reached[ot][tt] = 1;",
2286 "#ifdef HAS_UNLESS",
2287 " else trpt->e_state = 0; /* undo */",
2290 " if (_m>_n||(_n>3&&_m!=0)) _n=_m;",
2291 " ((P0 *)this)->_p = tt;",
2292 " } /* all options */",
2295 " if (!t && ooi > 0)", /* means we skipped some initial options */
2296 " { t = trans[ot][tt];",
2298 " printf(\"randomizer: continue for %%d more\\n\", ooi);",
2304 " printf(\"randomizer: done\\n\");",
2309 " /* Fairness: undo Rule 2 */",
2310 " if ((trpt->o_pm&32)",/* rule 2 was applied */
2311 " && (trpt->o_pm&64))",/* by this process II */
2312 " { if (trpt->o_pm&1)",/* it didn't block */
2315 " if (now._cnt[now._a_t&1] == 1)", /* NEW: 1 iso 0 */
2316 " now._cnt[now._a_t&1] = 2;", /* NEW: 2 iso 1*/
2318 " now._cnt[now._a_t&1] += 1;",
2320 " printf(\"%%3d: proc %%d fairness \", depth, II);",
2321 " printf(\"undo Rule 2, cnt=%%d, _a_t=%%d\\n\",",
2322 " now._cnt[now._a_t&1], now._a_t);",
2324 " trpt->o_pm &= ~(32|64);",
2325 " } else", /* process blocked */
2326 " { if (_n > 0)", /* a prev proc didn't */
2327 " {", /* start over */
2328 " trpt->o_pm &= ~64;",
2334 " if (II == 0) break; /* never claim */",
2336 " } /* all processes */",
2339 " /* Fairness: undo Rule 2 */",
2340 " if (trpt->o_pm&32) /* remains if proc blocked */",
2343 " if (now._cnt[now._a_t&1] == 1)", /* NEW: 1 iso 0 */
2344 " now._cnt[now._a_t&1] = 2;", /* NEW: 2 iso 1 */
2346 " now._cnt[now._a_t&1] += 1;",
2348 " printf(\"%%3d: proc -- fairness \", depth);",
2349 " printf(\"undo Rule 2, cnt=%%d, _a_t=%%d\\n\",",
2350 " now._cnt[now._a_t&1], now._a_t);",
2352 " trpt->o_pm &= ~32;",
2355 /* 12/97 non-progress cycles cannot be created
2356 * by stuttering extension, here or elsewhere
2359 " && _n == 0 /* nobody moved */",
2361 " && !(trpt->tau&4) /* in program move */",
2363 " && !(trpt->tau&8) /* not an atomic one */",
2365 " && ((trpt->tau&1) || endstate())",
2368 " && (trpt->tau&1) /* already tried timeout */",
2373 " && !((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))",
2375 " && now._cnt[now._a_t&1] > 0) /* needed more procs */",
2376 " { depth++; trpt++;",
2377 " trpt->o_pm |= 128 | ((trpt-1)->o_pm&(2|4));",
2378 " trpt->bup.oval = now._cnt[now._a_t&1];",
2379 " now._cnt[now._a_t&1] = 1;",
2385 " From = now._nr_pr-1; To = BASE;",
2386 "#if defined(VERBOSE) || defined(CHECK)",
2387 " printf(\"%%3d: fairness default move \", depth);",
2388 " printf(\"(all procs block)\\n\");",
2393 "Q999: /* returns here with _n>0 when done */;",
2395 " if (trpt->o_pm&8)",
2396 " { now._a_t &= ~2;",
2397 " now._cnt[now._a_t&1] = 0;",
2398 " trpt->o_pm &= ~8;",
2400 " printf(\"%%3d: fairness undo Rule 1, _a_t=%%d\\n\",",
2401 " depth, now._a_t);",
2404 " if (trpt->o_pm&16)",
2405 " { now._a_t |= 2;", /* restore a-bit */
2406 " now._cnt[now._a_t&1] = 1;", /* NEW: restore cnt */
2407 " trpt->o_pm &= ~16;",
2409 " printf(\"%%3d: fairness undo Rule 3, _a_t=%%d\\n\",",
2410 " depth, now._a_t);",
2417 " /* preselected move - no successors outside stack */",
2418 " if ((trpt->tau&32) && !(trpt->tau&64))",
2419 " { From = now._nr_pr-1; To = BASE;",
2421 " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ",
2422 " depth, II+1, _n, trpt->tau);",
2424 " _n = 0; trpt->tau &= ~(16|32|64);",
2425 " if (II >= BASE) /* II already decremented */",
2431 " /* at least one move that was preselected at this */",
2432 " /* level, blocked or truncated at the next level */",
2433 "/* implied: #ifdef FULLSTACK */",
2434 " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))",
2437 " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ",
2438 " depth, II+1, (int) _n, trpt->tau);",
2440 " if (a_cycles && (trpt->tau&16))",
2441 " { if (!(now._a_t&1))",
2444 " printf(\"%%3d: setting proviso bit\\n\", depth);",
2449 " (trpt-1)->proviso = 1;",
2451 " trpt->proviso = 1;",
2455 " if ((trpt-1)->ostate)",
2456 " ((char *)&((trpt-1)->ostate->state))[0] |= 128;",
2458 " ((char *)&(trpt->ostate->state))[0] |= 128;",
2463 " if ((trpt-1)->ostate)",
2464 " (trpt-1)->ostate->proviso = 1;",
2466 " trpt->ostate->proviso = 1;",
2469 " From = now._nr_pr-1; To = BASE;",
2470 " _n = 0; trpt->tau &= ~(16|32|64);",
2471 " goto Again; /* do full search */",
2472 " } /* else accept reduction */",
2474 " { From = now._nr_pr-1; To = BASE;",
2475 " _n = 0; trpt->tau &= ~(16|32|64);",
2476 " if (II >= BASE) /* already decremented */",
2485 " if (_n == 0 || ((trpt->tau&4) && (trpt->tau&2)))",
2488 " printf(\"%%3d: no move [II=%%d, tau=%%d, boq=%%d]\\n\",",
2489 " depth, II, trpt->tau, boq);",
2492 " /* ok if a rendez-vous fails: */",
2493 " if (boq != -1) goto Done;",
2495 " /* ok if no procs or we're at maxdepth */",
2496 " if ((now._nr_pr == 0 && (!strict || qs_empty()))",
2500 " || depth >= maxdepth-1) goto Done;",
2502 " if ((trpt->tau&8) && !(trpt->tau&4))",
2503 " { trpt->tau &= ~(1|8);",
2504 " /* 1=timeout, 8=atomic */",
2505 " From = now._nr_pr-1; To = BASE;",
2507 " printf(\"%%3d: atomic step proc %%d \", depth, II+1);",
2508 " printf(\"unexecutable\\n\");",
2511 " trpt->tau |= 4; /* switch to claim */",
2517 " if (!(trpt->tau&1)) /* didn't try timeout yet */",
2520 " if (trpt->tau&4)",
2523 " if (trpt->tau&2) /* requested */",
2525 " { trpt->tau |= 1;",
2526 " trpt->tau &= ~2;",
2528 " printf(\"%%d: timeout\\n\", depth);",
2533 " { /* only claim can enable timeout */",
2534 " if ((trpt->tau&8)",
2535 " && !((trpt-1)->tau&4))",
2536 "/* blocks inside an atomic */ goto BreakOut;",
2538 " printf(\"%%d: req timeout\\n\",",
2541 " (trpt-1)->tau |= 2; /* request */",
2547 " printf(\"%%d: timeout\\n\", depth);",
2555 /* old location of atomic block code */
2558 "#ifndef NOSTUTTER",
2559 " if (!(trpt->tau&4))",
2560 " { trpt->tau |= 4; /* claim stuttering */",
2561 " trpt->tau |= 128; /* stutter mark */",
2563 " printf(\"%%d: claim stutter\\n\", depth);",
2571 " if (!noends && !a_cycles && !endstate())",
2572 " { depth--; trpt--; /* new 4.2.3 */",
2573 " uerror(\"invalid end state\");",
2574 " depth++; trpt++;",
2576 "#ifndef NOSTUTTER",
2577 " else if (a_cycles && (trpt->o_pm&2)) /* new 4.2.4 */",
2578 " { depth--; trpt--;",
2579 " uerror(\"accept stutter\");",
2580 " depth++; trpt++;",
2586 " if (!(trpt->tau&8)) /* not in atomic seqs */",
2589 " if (_n != 0", /* we made a move */
2591 " /* --after-- a program-step, i.e., */",
2592 " /* after backtracking a claim-step */",
2593 " && (trpt->tau&4)",
2594 " /* with at least one running process */",
2595 " /* unless in a stuttered accept state */",
2596 " && ((now._nr_pr > 1) || (trpt->o_pm&2))",
2598 " && !(now._a_t&1))", /* not in 2nd DFS */
2601 " if (fairness)", /* implies a_cycles */
2604 " printf(\"Consider check %%d %%d...\\n\",",
2605 " now._a_t, now._cnt[0]);",
2608 the a-bit is set, which means that the fairness
2609 counter is running -- it was started in an accepting state.
2610 we check that the counter reached 1, which means that all
2611 processes moved least once.
2612 this means we can start the search for cycles -
2613 to be able to return to this state, we should be able to
2614 run down the counter to 1 again -- which implies a visit to
2615 the accepting state -- even though the Seed state for this
2616 search is itself not necessarily accepting
2618 " if ((now._a_t&2) /* A-bit */",
2619 " && (now._cnt[0] == 1))",
2623 " if (a_cycles && (trpt->o_pm&2))",
2628 "#if defined(FULLSTACK) || defined(CNTRSTACK)",
2631 " && (((trpt->tau&4) && !(trpt->tau&128))",
2632 " || ( (trpt-1)->tau&128)))",
2638 "#if defined(FULLSTACK)",
2639 " printf(\"%%d: zapping %%u (%%d)\\n\",",
2640 " depth, trpt->ostate,",
2641 " (trpt->ostate)?trpt->ostate->tagged:0);",
2650 " && (((trpt->tau&4) && !(trpt->tau&128))",
2651 " || ( (trpt-1)->tau&128)))",
2657 " printf(\"%%d: zapping\\n\", depth);",
2661 " if (trpt->proviso)",
2662 " gstore((char *) &now, vsize, 1);",
2667 " if (depth > 0) goto Up;",
2670 "void new_state(void) { /* place holder */ }",
2674 "assert(int a, char *s, int ii, int tt, Trans *t)",
2676 " if (!a && !noasserts)",
2677 " { char bad[1024];",
2678 " strcpy(bad, \"assertion violated \");",
2679 " if (strlen(s) > 1000)",
2680 " { strncpy(&bad[19], (const char *) s, 1000);",
2681 " bad[1019] = '\\0';",
2683 " strcpy(&bad[19], s);",
2687 "#ifndef NOBOUNDCHECK",
2689 "Boundcheck(int x, int y, int a1, int a2, Trans *a3)",
2691 " assert((x >= 0 && x < y), \"- invalid array index\",",
2700 " printf(\"%%8g states, stored (%%g visited)\\n\",",
2701 " nstates - nShadow, nstates);",
2703 " printf(\"%%8g states, stored\\n\", nstates);",
2706 " printf(\" %%8g nominal states (- rv and atomic)\\n\", nstates-midrv-nlinks+revrv);",
2707 " printf(\" %%8g rvs succeeded\\n\", midrv-failedrv);",
2709 " printf(\" %%8g nominal states (stored-atomic)\\n\", nstates-nlinks);",
2712 " printf(\" %%8g midrv\\n\", midrv);",
2713 " printf(\" %%8g failedrv\\n\", failedrv);",
2714 " printf(\" %%8g revrv\\n\", revrv);",
2717 " printf(\"%%8g states, matched\\n\", truncs);",
2719 " printf(\"%%8g matches within stack\\n\",truncs2);",
2722 " printf(\"%%8g transitions (= visited+matched)\\n\",",
2723 " nstates+truncs);",
2725 " printf(\"%%8g transitions (= stored+matched)\\n\",",
2726 " nstates+truncs);",
2727 " printf(\"%%8g atomic steps\\n\", nlinks);",
2728 " if (nlost) printf(\"%%g lost messages\\n\", (double) nlost);",
2731 " printf(\"hash conflicts: %%g (resolved)\\n\", hcmp);",
2734 " printf(\"%%8g states allocated for dfs stack\\n\", ngrabs);",
2736 " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",",
2737 " (double)(1<<(ssize-8)) / (double) nstates * 256.0);",
2738 " printf(\"bits set per state: %%u (-k%%u)\\n\", hfns, hfns);",
2742 " printf(\"total bits available: %%8g (-M%%ld)\\n\",",
2743 " ((double) udmem) * 8.0, udmem/(1024L*1024L));",
2746 " printf(\"total bits available: %%8g (-w%%d)\\n\",",
2747 " ((double) (1L << (ssize-4)) * 16.0), ssize);",
2750 " /* this code requires compilation with -lm on some systems */",
2751 " { double pow(double, double);",
2752 " double log(double);",
2753 " unsigned int best_k;",
2754 " double i, n = 30000.0L;",
2755 " double f, p, q, m, c, est = 0.0L, k = (double)hfns;",
2756 " c = (double) nstates / n;",
2757 " m = (double) (1<<(ssize-8)) * 256.0L / c;",
2758 " p = 1.0L - (k / m); q = 1.0L;",
2759 " for (i = 0.0L; i - est < n; i += 1.0L)",
2761 " est += pow(1.0L - q, k);",
2766 " /* account for loss from enhanced double hashing */",
2767 " if (hfns > 2) est += i * pow(0.5, (double) ssize * 2.0);",
2769 " if (f < 1.134) best_k = 1;",
2770 " else if (f < 2.348) best_k = 2;",
2771 " else if (f < 3.644) best_k = 3;",
2772 " else best_k = (unsigned int) (pow(3.8L,1.0L/(f+4.2L))*f*.69315L + 0.99999999L);",
2774 " if (best_k != hfns && best_k > ssize)",
2775 " best_k = (unsigned int) 1.0 + ssize/log((double)best_k / (double)ssize + 3.0);",
2777 " if (best_k > 32)",
2778 " best_k = 1 + (unsigned int) (32.0/log((double)best_k/35.0));",
2780 " if (est * (double) nstates < 1.0)",
2781 " { printf(\"prob. of omissions: negligible\\n\");",
2782 " return; /* no hints needed */",
2785 " if (best_k != hfns)",
2786 " { printf(\"hint: repeating the search with -k%%u \", best_k);",
2787 " printf(\"may increase accuracy\\n\");",
2789 " { printf(\"hint: the current setting for -k (-k%%d) \", hfns);",
2790 " printf(\"is likely to be optimal for -w%%d\\n\", ssize);",
2793 " { printf(\"hint: increasing -w above -w%%d \", ssize);",
2794 " printf(\"will increase accuracy (max is -w34)\\n\");",
2795 " printf(\"(in xspin, increase Estimated State Space Size)\\n\");",
2803 "#if defined(BITSTATE) || !defined(NOCOMP)",
2804 " double nr1, nr2, nr3 = 0.0, nr4, nr5 = 0.0;",
2805 "#if !defined(MA) && (defined(MEMCNT) || defined(MEMLIM))",
2806 " int mverbose = 1;",
2808 " int mverbose = verbose;",
2812 " signal(SIGINT, SIG_DFL);",
2813 " printf(\"(%%s)\\n\", Version);",
2814 " if (!done) printf(\"Warning: Search not completed\\n\");",
2816 " (void) unlink((const char *)stackfile);",
2819 " printf(\" + Using Breadth-First Search\\n\");",
2822 " printf(\" + Partial Order Reduction\\n\");",
2826 " printf(\" + Queue Proviso\\n\");",
2830 " printf(\" + Compression\\n\");",
2833 " printf(\" + Graph Encoding (-DMA=%%d)\\n\", MA);",
2835 " printf(\" Restarted from checkpoint %%s.xpt\\n\", Source);",
2840 " printf(\" + FullStack Matching\\n\");",
2843 " printf(\" + CntrStack Matching\\n\");",
2847 " printf(\"\\nBit statespace search for:\\n\");",
2850 " printf(\"\\nHash-Compact %%d search for:\\n\", HC);",
2852 " printf(\"\\nFull statespace search for:\\n\");",
2855 "#ifdef EVENT_TRACE",
2856 "#ifdef NEGATED_TRACE",
2857 " printf(\"\tnotrace assertion \t+\\n\");",
2859 " printf(\"\ttrace assertion \t+\\n\");",
2863 " printf(\"\tnever claim \t+\\n\");",
2864 " printf(\"\tassertion violations\t\");",
2866 " printf(\"- (disabled by -A flag)\\n\");",
2868 " printf(\"+ (if within scope of claim)\\n\");",
2871 " printf(\"\tnever claim \t- (not selected)\\n\");",
2873 " printf(\"\tnever claim \t- (none specified)\\n\");",
2875 " printf(\"\tassertion violations\t\");",
2877 " printf(\"- (disabled by -A flag)\\n\");",
2879 " printf(\"+\\n\");",
2883 " printf(\"\tnon-progress cycles \t\");",
2885 " printf(\"\tacceptance cycles \t\");",
2888 " printf(\"+ (fairness %%sabled)\\n\",",
2889 " fairness?\"en\":\"dis\");",
2890 " else printf(\"- (not selected)\\n\");",
2892 " printf(\"\tcycle checks \t- (disabled by -DSAFETY)\\n\");",
2895 " printf(\"\tinvalid end states\t- \");",
2896 " printf(\"(disabled by \");",
2898 " printf(\"-E flag)\\n\\n\");",
2900 " printf(\"never claim)\\n\\n\");",
2902 " printf(\"\tinvalid end states\t\");",
2904 " printf(\"- (disabled by -E flag)\\n\\n\");",
2906 " printf(\"+\\n\\n\");",
2908 " printf(\"State-vector %%d byte, depth reached %%d\", ",
2909 " hmax, mreached);",
2910 " printf(\", errors: %%d\\n\", errors);",
2913 " { extern void dfa_stats(void);",
2914 " if (maxgs+a_cycles+2 < MA)",
2915 " printf(\"MA stats: -DMA=%%d is sufficient\\n\",",
2916 " maxgs+a_cycles+2);",
2922 " printf(\"stackframes: %%d/%%d\\n\\n\", smax, svmax);",
2923 " printf(\"stats: fa %%d, fh %%d, zh %%d, zn %%d - \",",
2924 " Fa, Fh, Zh, Zn);",
2925 " printf(\"check %%d holds %%d\\n\", Ccheck, Cholds);",
2926 " printf(\"stack stats: puts %%d, probes %%d, zaps %%d\\n\",",
2927 " PUT, PROBE, ZAPS);",
2929 " printf(\"\\n\");",
2932 "#if defined(BITSTATE) || !defined(NOCOMP)",
2933 " nr1 = (nstates-nShadow)*",
2934 " (double)(hmax+sizeof(struct H_el)-sizeof(unsigned));",
2938 " nr2 = (double) ((maxdepth+3)*sizeof(Trail));",
2942 "#if !defined(MA) || defined(COLLAPSE)",
2943 " nr3 = (double) (1L<<ssize)*sizeof(struct H_el *);",
2948 " nr3 = (double) (udmem);",
2951 " nr3 = (double) (1L<<(ssize-3));",
2953 " nr3 += (double) (1L<<(ssize-3));",
2956 " nr5 = (double) (maxdepth*sizeof(struct H_el *));",
2959 " nr4 = (double) (svmax * (sizeof(Svtack) + hmax))",
2960 " + (double) (smax * (sizeof(Stack) + Maxbody));",
2962 " if (mverbose || memcnt < nr1+nr2+nr3+nr4+nr5)",
2964 " { double remainder = memcnt;",
2965 " double tmp_nr = memcnt-nr3-nr4-(nr2-fragment)-nr5;",
2966 " if (tmp_nr < 0.0) tmp_nr = 0.;",
2967 " printf(\"Stats on memory usage (in Megabytes):\\n\");",
2968 " printf(\"%%-6.3f\tequivalent memory usage for states\",",
2970 " printf(\" (stored*(State-vector + overhead))\\n\");",
2974 " printf(\"%%-6.3f\tmemory used for hash array (-M%%ld)\\n\",",
2975 " nr3/1000000., udmem/(1024L*1024L));",
2978 " printf(\"%%-6.3f\tmemory used for hash array (-w%%d)\\n\",",
2979 " nr3/1000000., ssize);",
2981 " printf(\"%%-6.3f\tmemory used for bit stack\\n\",",
2983 " remainder = remainder - nr3 - nr5;",
2985 " printf(\"%%-6.3f\tactual memory usage for states\",",
2986 " tmp_nr/1000000.);",
2987 " remainder = remainder - tmp_nr;",
2989 " if (tmp_nr > 0.)",
2990 " { if (tmp_nr > nr1) printf(\"unsuccessful \");",
2991 " printf(\"compression: %%.2f%%%%)\\n\",",
2992 " (100.0*tmp_nr)/nr1);",
2994 " printf(\"less than 1k)\\n\");",
2996 " if (tmp_nr > 0.)",
2997 " { printf(\"\tState-vector as stored = %%.0f byte\",",
2998 " (tmp_nr)/(nstates-nShadow) -",
2999 " (double) (sizeof(struct H_el) - sizeof(unsigned)));",
3000 " printf(\" + %%ld byte overhead\\n\",",
3001 " sizeof(struct H_el)-sizeof(unsigned));",
3004 "#if !defined(MA) || defined(COLLAPSE)",
3005 " printf(\"%%-6.3f\tmemory used for hash table (-w%%d)\\n\",",
3006 " nr3/1000000., ssize);",
3007 " remainder = remainder - nr3;",
3011 " printf(\"%%-6.3f\tmemory used for DFS stack (-m%%ld)\\n\",",
3012 " nr2/1000000., maxdepth);",
3013 " remainder = remainder - nr2;",
3015 " if (remainder - fragment > 0.0)",
3016 " printf(\"%%-6.3f\tother (proc and chan stacks)\\n\",",
3017 " (remainder-fragment)/1000000.);",
3018 " if (fragment > 0.0)",
3019 " printf(\"%%-6.3f\tmemory lost to fragmentation\\n\",",
3020 " fragment/1000000.);",
3021 " printf(\"%%-6.3f\ttotal actual memory usage\\n\\n\",",
3022 " memcnt/1000000.);",
3029 " printf(\"%%-6.3f\tmemory usage (Mbyte)\\n\\n\",",
3030 " memcnt/1000000.);",
3033 " printf(\"nr of templates: [ globals chans procs ]\\n\");",
3034 " printf(\"collapse counts: [ \");",
3035 " { int i; for (i = 0; i < 256+2; i++)",
3036 " if (ncomps[i] != 0)",
3037 " printf(\"%%d \", ncomps[i]);",
3038 " printf(\"]\\n\");",
3042 " if ((done || verbose) && !no_rck) do_reach();",
3045 " printf(\"\\nPeg Counts (transitions executed):\\n\");",
3046 " for (i = 1; i < NTRANS; i++)",
3047 " { if (peg[i]) putpeg(i, peg[i]);",
3050 "#ifdef VAR_RANGES",
3054 " if (vprefix > 0) close(svfd);",
3060 "{ printf(\"Interrupted\\n\");",
3065 " * based on Bob Jenkins hash-function from 1996",
3066 " * see: http://www.burtleburtle.net/bob/",
3069 "#if defined(HASH64) || defined(WIN64)",
3070 /* 64-bit Jenkins hash: http://burtleburtle.net/bob/c/lookup8.c */
3071 "#define mix(a,b,c) \\",
3072 "{ a -= b; a -= c; a ^= (c>>43); \\",
3073 " b -= c; b -= a; b ^= (a<<9); \\",
3074 " c -= a; c -= b; c ^= (b>>8); \\",
3075 " a -= b; a -= c; a ^= (c>>38); \\",
3076 " b -= c; b -= a; b ^= (a<<23); \\",
3077 " c -= a; c -= b; c ^= (b>>5); \\",
3078 " a -= b; a -= c; a ^= (c>>35); \\",
3079 " b -= c; b -= a; b ^= (a<<49); \\",
3080 " c -= a; c -= b; c ^= (b>>11); \\",
3081 " a -= b; a -= c; a ^= (c>>12); \\",
3082 " b -= c; b -= a; b ^= (a<<18); \\",
3083 " c -= a; c -= b; c ^= (b>>22); \\",
3086 "#define mix(a,b,c) \\",
3087 "{ a -= b; a -= c; a ^= (c>>13); \\",
3088 " b -= c; b -= a; b ^= (a<<8); \\",
3089 " c -= a; c -= b; c ^= (b>>13); \\",
3090 " a -= b; a -= c; a ^= (c>>12); \\",
3091 " b -= c; b -= a; b ^= (a<<16); \\",
3092 " c -= a; c -= b; c ^= (b>>5); \\",
3093 " a -= b; a -= c; a ^= (c>>3); \\",
3094 " b -= c; b -= a; b ^= (a<<10); \\",
3095 " c -= a; c -= b; c ^= (b>>15); \\",
3099 "d_hash(uchar *Cp, int Om) /* double bit hash - Jenkins */",
3100 "{ unsigned long a = 0x9e3779b9, b, c = 0, len, length;",
3101 " unsigned long *k = (unsigned long *) Cp;",
3103 " length = len = (unsigned long) ((unsigned long) Om + WS-1)/WS;",
3105 " b = HASH_CONST[HASH_NR];",
3106 " while (len >= 3)",
3111 " k += 3; len -= 3;",
3115 " case 2: b += k[1];",
3116 " case 1: a += k[0];",
3119 " j1 = c&nmask; j3 = a&7;", /* 1st bit */
3120 " j2 = b&nmask; j4 = (a>>3)&7;", /* 2nd bit */
3121 " K1 = c; K2 = b;", /* no nmask */
3124 "s_hash(uchar *cp, int om)",
3125 "{ d_hash(cp, om); /* sets K1 and K2 */",
3127 " if (S_Tab == H_tab)", /* state stack in bitstate search */
3128 " j1 = K1 %% omaxdepth;",
3130 "#endif", /* if (S_Tab != H_Tab) */
3131 " if (ssize < 8*WS)",
3141 " srand(123); /* fixed startpoint */",
3142 " prerand = (int *) emalloc((omaxdepth+3)*sizeof(int));",
3143 " for (i = 0; i < omaxdepth+3; i++)",
3144 " prerand[i] = rand();",
3148 "{ if (!prerand) inirand();",
3149 " return prerand[depth];",
3154 "main(int argc, char *argv[])",
3155 "{ void to_compile(void);\n",
3156 " efd = stderr; /* default */",
3158 " bstore = bstore_reg; /* default */",
3160 " while (argc > 1 && argv[1][0] == '-')",
3161 " { switch (argv[1][1]) {",
3164 " case 'a': fprintf(efd, \"error: -a disabled\");",
3165 " usage(efd); break;",
3167 " case 'a': a_cycles = 1; break;",
3170 " case 'A': noasserts = 1; break;",
3171 " case 'b': bounded = 1; break;",
3172 " case 'c': upto = atoi(&argv[1][2]); break;",
3173 " case 'd': state_tables++; break;",
3174 " case 'e': every_error = 1; Nr_Trails = 1; break;",
3175 " case 'E': noends = 1; break;",
3177 " case 'F': if (strlen(argv[1]) > 2)",
3178 " stackfile = &argv[1][2];",
3181 "#if !defined(SAFETY) && !defined(NOFAIR)",
3182 " case 'f': fairness = 1; break;",
3184 " case 'h': if (!argv[1][2]) usage(efd); else",
3185 " HASH_NR = atoi(&argv[1][2])%%33; break;",
3186 " case 'I': iterative = 2; every_error = 1; break;",
3187 " case 'i': iterative = 1; every_error = 1; break;",
3188 " case 'J': like_java = 1; break; /* Klaus Havelund */",
3190 " case 'k': hfns = atoi(&argv[1][2]); break;",
3194 " case 'l': a_cycles = 1; break;",
3196 " case 'l': fprintf(efd, \"error: -l disabled\");",
3197 " usage(efd); break;",
3202 " case 'M': udmem = atoi(&argv[1][2]); break;",
3203 " case 'G': udmem = atoi(&argv[1][2]); udmem *= 1024; break;",
3205 " case 'M': case 'G':",
3206 " fprintf(stderr, \"-M and -G affect only -DBITSTATE\\n\");",
3210 " case 'm': maxdepth = atoi(&argv[1][2]); break;",
3211 " case 'n': no_rck = 1; break;",
3213 " case 'p': vprefix = atoi(&argv[1][2]); break;",
3215 " case 'q': strict = 1; break;",
3218 "samething: readtrail = 1;",
3219 " if (isdigit(argv[1][2]))",
3220 " whichtrail = atoi(&argv[1][2]);",
3222 " case 'P': readtrail = 1; onlyproc = atoi(&argv[1][2]); break;",
3223 " case 'C': coltrace = 1; goto samething;",
3224 " case 'g': gui = 1; goto samething;",
3225 " case 'S': silent = 1; break;",
3227 " case 'R': Nrun = atoi(&argv[1][2]); break;",
3229 " case 's': hfns = 1; break;",
3231 " case 'T': TMODE = 0444; break;",
3232 " case 't': if (argv[1][2]) tprefix = &argv[1][2]; break;",
3233 " case 'V': printf(\"Generated by %%s\\n\", Version);",
3234 " to_compile(); pan_exit(0); break;",
3235 " case 'v': verbose = 1; break;",
3236 " case 'w': ssize = atoi(&argv[1][2]); break;",
3237 " case 'Y': signoff = 1; break;",
3238 " case 'X': efd = stdout; break;",
3239 " default : fprintf(efd, \"saw option -%%c\\n\", argv[1][1]); usage(efd); break;",
3243 " if (iterative && TMODE != 0666)",
3245 " fprintf(efd, \"warning: -T ignored when -i or -I is used\\n\");",
3247 "#if defined(WIN32) || defined(WIN64)",
3248 " if (TMODE == 0666)",
3249 " TMODE = _S_IWRITE | _S_IREAD;",
3251 " TMODE = _S_IREAD;",
3254 " fprintf(efd, \"warning: -DOHASH no longer supported (directive ignored)\\n\");",
3257 " fprintf(efd, \"warning: -DJHASH no longer supported (directive ignored)\\n\");",
3259 "#ifdef HYBRID_HASH",
3260 " fprintf(efd, \"warning: -DHYBRID_HASH no longer supported (directive ignored)\\n\");",
3263 " fprintf(efd, \"warning: -DNOCOVEST no longer supported (directive ignored)\\n\");",
3267 " fprintf(efd, \"warning: -DBCOMP no longer supported (directive ignored)\\n\");",
3271 " fprintf(efd, \"warning: using -k%%d as minimal usable value\\n\", hfns);",
3274 " omaxdepth = maxdepth;",
3276 " if (WS == 4 && ssize > 34)", /* 32-bit word size */
3278 " fprintf(efd, \"warning: using -w%%d as max usable value\\n\", ssize);",
3280 " * -w35 would not work: 35-3 = 32 but 1^31 is the largest",
3281 " * power of 2 that can be represented in an unsigned long",
3285 " if (WS == 4 && ssize > 27)",
3287 " fprintf(efd, \"warning: using -w%%d as max usable value\\n\", ssize);",
3289 " * for emalloc, the lookup table size multiplies by 4 for the pointers",
3290 " * the largest power of 2 that can be represented in a ulong is 1^31",
3291 " * hence the largest number of lookup table slots is 31-4 = 27",
3297 " hiwater = HHH = maxdepth-10;",
3300 " { stackfile = (char *) emalloc(strlen(Source)+4+1);",
3301 " sprintf(stackfile, \"%%s._s_\", Source);",
3304 " { fprintf(efd, \"error: cannot use -i or -I with -DSC\\n\");",
3309 "#if (defined(R_XPT) || defined(W_XPT)) && !defined(MA)",
3310 " fprintf(efd, \"error: -D?_XPT requires -DMA\\n\");",
3314 " if (iterative && a_cycles)",
3315 " fprintf(efd, \"warning: -i or -I work for safety properties only\\n\");",
3319 " fprintf(efd, \"error: -DBFS not compatible with -DSC\\n\");",
3322 "#if defined(HAS_LAST)",
3323 " fprintf(efd, \"error: -DBFS not compatible with _last\\n\");",
3326 "#if defined(REACH)",
3327 " fprintf(efd, \"warning: -DREACH redundant when -DBFS is used\\n\");",
3329 "#if defined(HAS_STACK)",
3330 " fprintf(efd, \"error: cannot use UnMatched qualifier on c_track with BFS\\n\");",
3335 "#if defined(MERGED) && defined(PEG)",
3336 " fprintf(efd, \"error: to allow -DPEG use: spin -o3 -a %%s\\n\", Source);",
3337 " fprintf(efd, \" to turn off transition merge optimization\\n\");",
3342 " fprintf(efd, \"error: cannot combine -DHC and -DNOCOMP\\n\");",
3346 " fprintf(efd, \"error: cannot combine -DHC and -DBITSTATE\\n\");",
3350 "#if defined(SAFETY) && defined(NP)",
3351 " fprintf(efd, \"error: cannot combine -DNP and -DSAFETY\\n\");",
3356 " fprintf(efd, \"error: cannot combine -DMA and -DBITSTATE\\n\");",
3360 " { fprintf(efd, \"usage: -DMA=N with N > 0 and < VECTORSZ\\n\");",
3365 "#if defined(BITSTATE)",
3366 " fprintf(efd, \"error: cannot combine -DBITSTATE and -DCOLLAPSE\\n\");",
3369 "#if defined(NOCOMP)",
3370 " fprintf(efd, \"error: cannot combine -DNOCOMP and -DCOLLAPSE\\n\");",
3374 " if (maxdepth <= 0 || ssize <= 1) usage(efd);",
3375 "#if SYNC>0 && !defined(NOREDUCE)",
3376 " if (a_cycles && fairness)",
3377 " { fprintf(efd, \"error: p.o. reduction not compatible with \");",
3378 " fprintf(efd, \"fairness (-f) in models\\n\");",
3379 " fprintf(efd, \" with rendezvous operations: \");",
3380 " fprintf(efd, \"recompile with -DNOREDUCE\\n\");",
3384 "#if defined(REM_VARS) && !defined(NOREDUCE)",
3385 " { fprintf(efd, \"warning: p.o. reduction not compatible with \");",
3386 " fprintf(efd, \"remote varrefs (use -DNOREDUCE)\\n\");",
3389 "#if defined(NOCOMP) && !defined(BITSTATE)",
3391 " { fprintf(efd, \"error: -DNOCOMP voids -l and -a\\n\");",
3396 "#ifdef MEMLIM", /* MEMLIM setting takes precedence */
3397 " memlim = (double) MEMLIM * (double) (1<<20); /* size in Mbyte */",
3401 " memlim = (double) (1<<MEMCNT);",
3403 " memlim = (double) (1<<30);",
3404 " memlim *= (double) (1<<(MEMCNT-30));",
3410 " if (Nrun > 1) HASH_NR = Nrun - 1;",
3412 " if (Nrun < 1 || Nrun > 32)",
3413 " { fprintf(efd, \"error: invalid arg for -R\\n\");",
3417 " if (fairness && !a_cycles)",
3418 " { fprintf(efd, \"error: -f requires -a or -l\\n\");",
3421 "#if ACCEPT_LAB==0",
3424 " { fprintf(efd, \"error: no accept labels defined \");",
3425 " fprintf(efd, \"in model (for option -a)\\n\");",
3429 " { fprintf(efd, \"warning: no explicit accept labels \");",
3430 " fprintf(efd, \"defined in model (for -a)\\n\");",
3435 "#if !defined(NOREDUCE)",
3436 "#if defined(HAS_ENABLED)",
3437 " fprintf(efd, \"error: reduced search precludes \");",
3438 " fprintf(efd, \"use of 'enabled()'\\n\");",
3441 "#if defined(HAS_PCVALUE)",
3442 " fprintf(efd, \"error: reduced search precludes \");",
3443 " fprintf(efd, \"use of 'pcvalue()'\\n\");",
3446 "#if defined(HAS_BADELSE)",
3447 " fprintf(efd, \"error: reduced search precludes \");",
3448 " fprintf(efd, \"using 'else' combined with i/o stmnts\\n\");",
3451 "#if defined(HAS_LAST)",
3452 " fprintf(efd, \"error: reduced search precludes \");",
3453 " fprintf(efd, \"use of _last\\n\");",
3458 "#if SYNC>0 && !defined(NOREDUCE)",
3459 "#ifdef HAS_UNLESS",
3460 " fprintf(efd, \"warning: use of a rendezvous stmnts in the escape\\n\");",
3461 " fprintf(efd, \"\tof an unless clause, if present, could make p.o. reduction\\n\");",
3462 " fprintf(efd, \"\tinvalid (use -DNOREDUCE to avoid this)\\n\");",
3464 " fprintf(efd, \"\t(this type of rv is also not compatible with -DBFS)\\n\");",
3468 "#if SYNC>0 && defined(BFS)",
3469 " fprintf(efd, \"warning: use of rendezvous in BFS mode \");",
3470 " fprintf(efd, \"does not preserve all invalid endstates\\n\");",
3472 "#if !defined(REACH) && !defined(BITSTATE)",
3473 " if (iterative != 0 && a_cycles == 0)",
3474 " fprintf(efd, \"warning: -i and -I need -DREACH to work accurately\\n\");",
3476 "#if defined(BITSTATE) && defined(REACH)",
3477 " fprintf(efd, \"warning: -DREACH voided by -DBITSTATE\\n\");",
3479 "#if defined(MA) && defined(REACH)",
3480 " fprintf(efd, \"warning: -DREACH voided by -DMA\\n\");",
3482 "#if defined(FULLSTACK) && defined(CNTRSTACK)",
3483 " fprintf(efd, \"error: cannot combine\");",
3484 " fprintf(efd, \" -DFULLSTACK and -DCNTRSTACK\\n\");",
3487 "#if defined(VERI)",
3494 " && !state_tables)",
3495 " { fprintf(efd, \"warning: never claim + accept labels \");",
3496 " fprintf(efd, \"requires -a flag to fully verify\\n\");",
3503 " && !state_tables)",
3504 " { fprintf(efd, \"warning: verification in BFS mode \");",
3505 " fprintf(efd, \"is restricted to safety properties\\n\");",
3515 " && !state_tables)",
3516 " { fprintf(efd, \"hint: this search is more efficient \");",
3517 " fprintf(efd, \"if pan.c is compiled -DSAFETY\\n\");",
3523 " { if (!fairness)",
3524 " S_A = 1; /* _a_t */",
3526 " else /* _a_t and _cnt[NFAIR] */",
3527 " S_A = (&(now._cnt[0]) - (uchar *) &now) + NFAIR - 2;",
3528 " /* -2 because first two uchars in now are masked */",
3533 " signal(SIGINT, stopped);",
3535 /******************* 4.2.5 ********************/
3536 " if (WS == 4 && ssize >= 32)",
3537 " { mask = 0xffffffff;",
3539 " switch (ssize) {",
3540 " case 34: nmask = (mask>>1); break;",
3541 " case 33: nmask = (mask>>2); break;",
3542 " default: nmask = (mask>>3); break;",
3547 " } else if (WS == 8)",
3548 " { mask = ((1L<<ssize)-1); /* hash init */",
3550 " nmask = mask>>3;",
3554 " } else if (WS != 4)",
3555 " { fprintf(stderr, \"pan: wordsize %%ld not supported\\n\", WS);",
3557 " } else /* WS == 4 and ssize < 32 */",
3558 " { mask = ((1L<<ssize)-1); /* hash init */",
3559 " nmask = (mask>>3);",
3561 /****************** end **********************/
3564 " trail = (Trail *) emalloc(6*sizeof(Trail));",
3567 " trail = (Trail *) emalloc((maxdepth+3)*sizeof(Trail));",
3568 " trail++; /* protect trpt-1 refs at depth 0 */",
3571 " if (vprefix > 0)",
3573 " sprintf(nm, \"%%s.svd\", Source);",
3574 " if ((svfd = creat(nm, 0666)) < 0)",
3575 " { fprintf(efd, \"couldn't create %%s\\n\", nm);",
3582 "#if SYNC>0 && ASYNC==0",
3589 "}", /* end of main() */
3594 " fprintf(fd, \"Valid Options are:\\n\");",
3597 " fprintf(fd, \"\t-a -> is disabled by -DNP \");",
3598 " fprintf(fd, \"(-DNP compiles for -l only)\\n\");",
3600 " fprintf(fd, \"\t-a find acceptance cycles\\n\");",
3603 " fprintf(fd, \"\t-a,-l,-f -> are disabled by -DSAFETY\\n\");",
3605 " fprintf(fd, \"\t-A ignore assert() violations\\n\");",
3606 " fprintf(fd, \"\t-b consider it an error to exceed the depth-limit\\n\");",
3607 " fprintf(fd, \"\t-cN stop at Nth error \");",
3608 " fprintf(fd, \"(defaults to -c1)\\n\");",
3609 " fprintf(fd, \"\t-d print state tables and stop\\n\");",
3610 " fprintf(fd, \"\t-e create trails for all errors\\n\");",
3611 " fprintf(fd, \"\t-E ignore invalid end states\\n\");",
3613 " fprintf(fd, \"\t-Ffile use 'file' to store disk-stack\\n\");",
3616 " fprintf(fd, \"\t-f add weak fairness (to -a or -l)\\n\");",
3618 " fprintf(fd, \"\t-hN use different hash-seed N:1..32\\n\");",
3619 " fprintf(fd, \"\t-i search for shortest path to error\\n\");",
3620 " fprintf(fd, \"\t-I like -i, but approximate and faster\\n\");",
3621 " fprintf(fd, \"\t-J reverse eval order of nested unlesses\\n\");",
3623 " fprintf(fd, \"\t-kN set N bits per state (defaults to 3)\\n\");",
3627 " fprintf(fd, \"\t-l find non-progress cycles\\n\");",
3629 " fprintf(fd, \"\t-l find non-progress cycles -> \");",
3630 " fprintf(fd, \"disabled, requires \");",
3631 " fprintf(fd, \"compilation with -DNP\\n\");",
3636 " fprintf(fd, \"\t-MN use N Megabytes for bitstate hash array\\n\");",
3637 " fprintf(fd, \"\t-GN use N Gigabytes for bitstate hash array\\n\");",
3640 " fprintf(fd, \"\t-mN max depth N steps (default=10k)\\n\");",
3641 " fprintf(fd, \"\t-n no listing of unreached states\\n\");",
3643 " fprintf(fd, \"\t-pN create svfile (save N bytes per state)\\n\");",
3645 " fprintf(fd, \"\t-q require empty chans in valid end states\\n\");",
3647 " fprintf(fd, \"\t-r read and execute trail - can add -v,-n,-PN,-g,-C\\n\");",
3648 " fprintf(fd, \"\t-rN read and execute N-th error trail\\n\");",
3649 " fprintf(fd, \"\t-C read and execute trail - columnated output (can add -v,-n)\\n\");",
3650 " fprintf(fd, \"\t-PN read and execute trail - restrict trail output to proc N\\n\");",
3651 " fprintf(fd, \"\t-g read and execute trail + msc gui support\\n\");",
3652 " fprintf(fd, \"\t-S silent replay: only user defined printfs show\\n\");",
3655 " fprintf(fd, \"\t-RN repeat run Nx with N \");",
3656 " fprintf(fd, \"[1..32] independent hash functions\\n\");",
3657 " fprintf(fd, \"\t-s same as -k1 (single bit per state)\\n\");",
3659 " fprintf(fd, \"\t-T create trail files in read-only mode\\n\");",
3660 " fprintf(fd, \"\t-tsuf replace .trail with .suf on trailfiles\\n\");",
3661 " fprintf(fd, \"\t-V print SPIN version number\\n\");",
3662 " fprintf(fd, \"\t-v verbose -- filenames in unreached state listing\\n\");",
3663 " fprintf(fd, \"\t-wN hashtable of 2^N entries \");",
3664 " fprintf(fd, \"(defaults to -w%%d)\\n\", ssize);",
3669 "Malloc(unsigned long n)",
3671 "#if defined(MEMCNT) || defined(MEMLIM)",
3672 " if (memcnt+ (double) n > memlim) goto err;",
3675 " tmp = (char *) malloc(n);",
3678 /* on linux machines, a large amount of memory is set aside
3679 * for malloc, whether it is used or not
3680 * using sbrk would make this memory arena inaccessible
3681 * the reason for using sbrk was originally to provide a
3682 * small additional speedup (since this memory is never released)
3684 " tmp = (char *) sbrk(n);",
3685 " if (tmp == (char *) -1L)",
3688 "#if defined(MEMCNT) || defined(MEMLIM)",
3691 " printf(\"pan: out of memory\\n\");",
3692 "#if defined(MEMCNT) || defined(MEMLIM)",
3693 " printf(\"\t%%g bytes used\\n\", memcnt);",
3694 " printf(\"\t%%g bytes more needed\\n\", (double) n);",
3695 " printf(\"\t%%g bytes limit\\n\",",
3699 " printf(\"hint: to reduce memory, recompile with\\n\");",
3701 " printf(\" -DMA=%%d # better/slower compression, or\\n\", hmax);",
3703 " printf(\" -DBITSTATE # supertrace, approximation\\n\");",
3706 " printf(\"hint: to reduce memory, recompile with\\n\");",
3708 " printf(\" -DCOLLAPSE # good, fast compression, or\\n\");",
3710 " printf(\" -DMA=%%d # better/slower compression, or\\n\", hmax);",
3712 " printf(\" -DHC # hash-compaction, approximation\\n\");",
3714 " printf(\" -DBITSTATE # supertrace, approximation\\n\");",
3719 " memcnt += (double) n;",
3723 "#define CHUNK (100*VECTORSZ)",
3726 "emalloc(unsigned long n) /* never released or reallocated */",
3729 " return (char *) NULL;",
3730 " if (n&(sizeof(void *)-1)) /* for proper alignment */",
3731 " n += sizeof(void *)-(n&(sizeof(void *)-1));",
3732 " if ((unsigned long) left < n)", /* was: (left < (long)n) */
3733 " { grow = (n < CHUNK) ? CHUNK : n;",
3735 " have = Malloc(grow);",
3737 " /* gcc's sbrk can give non-aligned result */",
3738 " grow += sizeof(void *); /* allow realignment */",
3739 " have = Malloc(grow);",
3740 " if (((unsigned) have)&(sizeof(void *)-1))",
3741 " { have += (long) (sizeof(void *) ",
3742 " - (((unsigned) have)&(sizeof(void *)-1)));",
3743 " grow -= sizeof(void *);",
3746 " fragment += (double) left;",
3750 " have += (long) n;",
3751 " left -= (long) n;",
3752 " memset(tmp, 0, n);",
3757 "Uerror(char *str)",
3758 "{ /* always fatal */",
3762 "#if defined(MA) && !defined(SAFETY)",
3765 "{ Trans *t; uchar ot, _m; int tt; short II;",
3769 " uchar oat = now._a_t;",
3770 " now._a_t &= ~(1|16|32);",
3771 " memcpy((char *) &comp_now, (char *) &now, vsize);",
3775 " trpt = getframe(depth);",
3778 " printf(\"%%d State: \", depth);",
3779 " for (i = 0; i < vsize; i++) printf(\"%%d%%s,\",",
3780 " ((char *)&now)[i], Mask[i]?\"*\":\"\");",
3781 " printf(\"\\n\");",
3784 " if (trpt->o_pm&128) /* fairness alg */",
3785 " { now._cnt[now._a_t&1] = trpt->bup.oval;",
3788 " trpt = getframe(depth);",
3797 " { int d; Trail *trl;",
3799 " for (d = 1; d < depth; d++)",
3800 " { trl = getframe(depth-d); /* was trl = (trpt-d); */",
3801 " if (trl->pr != 0)",
3802 " { now._last = trl->pr - BASE;",
3806 " now._last = (depth<1)?0:(trpt-1)->pr;",
3809 "#ifdef EVENT_TRACE",
3810 " now._event = trpt->o_event;",
3812 " if ((now._a_t&1) && depth <= A_depth)",
3813 " { now._a_t &= ~(1|16|32);",
3814 " if (fairness) now._a_t |= 2; /* ? */",
3816 " goto CameFromHere; /* checkcycles() */",
3819 " ot = trpt->o_ot; II = trpt->pr;",
3820 " tt = trpt->o_tt; this = pptr(II);",
3821 " _m = do_reverse(t, II, trpt->o_m);",
3823 " printf(\"%%3d: proc %%d \", depth, II);",
3824 " printf(\"reverses %%d, %%d to %%d,\",",
3825 " t->forw, tt, t->st);",
3826 " printf(\" %%s [abit=%%d,adepth=%%d,\", ",
3827 " t->tp, now._a_t, A_depth);",
3828 " printf(\"tau=%%d,%%d] <unwind>\\n\", ",
3829 " trpt->tau, (trpt-1)->tau);",
3833 " trpt = getframe(depth);",
3837 " /* reached[ot][t->st] = 1; 3.4.13 */",
3838 " ((P0 *)this)->_p = tt;",
3840 " if ((trpt->o_pm&32))",
3843 " if (now._cnt[now._a_t&1] == 0)",
3844 " now._cnt[now._a_t&1] = 1;",
3846 " now._cnt[now._a_t&1] += 1;",
3849 " if (trpt->o_pm&8)",
3850 " { now._a_t &= ~2;",
3851 " now._cnt[now._a_t&1] = 0;",
3853 " if (trpt->o_pm&16)",
3857 " if (memcmp((char *) &now, (char *) &comp_now, vsize) == 0)",
3859 " if (depth > 0) goto Up;",
3863 "static char unwinding;",
3865 "uerror(char *str)",
3866 "{ static char laststr[256];",
3869 " if (unwinding) return; /* 1.4.2 */",
3870 " if (strncmp(str, laststr, 254))",
3871 " printf(\"pan: %%s (at depth %%ld)\\n\", str,",
3872 " (depthfound==-1)?depth:depthfound);",
3873 " strncpy(laststr, str, 254);",
3876 " if (readtrail) { wrap_trail(); return; }",
3878 " is_cycle = (strstr(str, \" cycle\") != (char *) 0);",
3880 " { depth++; trpt++;", /* include failed step */
3882 " if ((every_error != 0)",
3883 " || errors == upto)",
3885 "#if defined(MA) && !defined(SAFETY)",
3887 " { int od = depth;",
3889 " depthfound = Unwind();",
3895 " if (depth > 1) trpt--;",
3897 " if (depth > 1) trpt++;",
3901 "#if defined(MA) && !defined(SAFETY)",
3902 " if (strstr(str, \" cycle\"))",
3903 " { if (every_error)",
3904 " printf(\"sorry: MA writes 1 trail max\\n\");",
3905 " wrapup(); /* no recovery from unwind */",
3910 " { depth--; trpt--; /* undo */",
3913 " if (iterative != 0 && maxdepth > 0)",
3914 " { maxdepth = (iterative == 1)?(depth-1):(depth/2);",
3916 " printf(\"pan: reducing search depth to %%ld\\n\",",
3920 " if (errors >= upto && upto != 0)",
3922 " depthfound = -1;",
3925 "xrefsrc(int lno, S_F_MAP *mp, int M, int i)",
3926 "{ Trans *T; int j, retval=1;",
3927 " for (T = trans[M][i]; T; T = T->nxt)",
3929 " { if (strcmp(T->tp, \".(goto)\") == 0",
3930 " || strncmp(T->tp, \"goto :\", 6) == 0)",
3931 " return 1; /* not reported */",
3933 " printf(\"\\tline %%d\", lno);",
3935 " for (j = 0; j < sizeof(mp); j++)",
3936 " if (i >= mp[j].from && i <= mp[j].upto)",
3937 " { printf(\", \\\"%%s\\\"\", mp[j].fnm);",
3940 " printf(\", state %%d\", i);",
3941 " if (strcmp(T->tp, \"\") != 0)",
3943 " q = transmognify(T->tp);",
3944 " printf(\", \\\"%%s\\\"\", q?q:\"\");",
3945 " } else if (stopstate[M][i])",
3946 " printf(\", -end state-\");",
3947 " printf(\"\\n\");",
3948 " retval = 0; /* reported */",
3953 "r_ck(uchar *which, int N, int M, short *src, S_F_MAP *mp)",
3956 " if (M == VERI && !verbose) return;",
3958 " printf(\"unreached in proctype %%s\\n\", procname[M]);",
3959 " for (i = 1; i < N; i++)",
3961 " if (which[i] == 0 /* && trans[M][i] */)",
3963 " if (which[i] == 0",
3964 " && (mapstate[M][i] == 0",
3965 " || which[mapstate[M][i]] == 0))",
3967 " m += xrefsrc((int) src[i], mp, M, i);",
3970 " printf(\"\t(%%d of %%d states)\\n\", N-1-m, N-1);",
3974 "{ int fd; long i, j;",
3976 "#if defined VERI || defined(MERGED)",
3980 " fd = make_trail();",
3981 " if (fd < 0) return;",
3983 " sprintf(snap, \"-2:%%d:-2\\n\", VERI);",
3984 " write(fd, snap, strlen(snap));",
3987 " sprintf(snap, \"-4:-4:-4\\n\");",
3988 " write(fd, snap, strlen(snap));",
3990 " for (i = 1; i <= depth; i++)",
3991 " { if (i == depthfound+1)",
3992 " write(fd, \"-1:-1:-1\\n\", 9);",
3993 " trl = getframe(i);",
3994 " if (!trl->o_t) continue;",
3995 " if (trl->o_pm&128) continue;",
3996 " sprintf(snap, \"%%ld:%%d:%%d\\n\", ",
3997 " i, trl->pr, trl->o_t->t_id);",
3998 " j = strlen(snap);",
3999 " if (write(fd, snap, j) != j)",
4000 " { printf(\"pan: error writing trailfile\\n\");",
4008 "sv_save(void) /* push state vector onto save stack */",
4009 "{ if (!svtack->nxt)",
4010 " { svtack->nxt = (Svtack *) emalloc(sizeof(Svtack));",
4011 " svtack->nxt->body = emalloc(vsize*sizeof(char));",
4012 " svtack->nxt->lst = svtack;",
4013 " svtack->nxt->m_delta = vsize;",
4015 " } else if (vsize > svtack->nxt->m_delta)",
4016 " { svtack->nxt->body = emalloc(vsize*sizeof(char));",
4017 " svtack->nxt->lst = svtack;",
4018 " svtack->nxt->m_delta = vsize;",
4021 " svtack = svtack->nxt;",
4023 " svtack->o_boq = boq;",
4025 " svtack->o_delta = vsize; /* don't compress */",
4026 " memcpy((char *)(svtack->body), (char *) &now, vsize);",
4027 "#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)",
4028 " c_stack((uchar *) &(svtack->c_stack[0]));",
4031 " printf(\"%%d: sv_save\\n\", depth);",
4035 "sv_restor(void) /* pop state vector from save stack */",
4037 " memcpy((char *)&now, svtack->body, svtack->o_delta);",
4039 " boq = svtack->o_boq;",
4042 "#if defined(C_States) && (HAS_TRACK==1)",
4044 " c_unstack((uchar *) &(svtack->c_stack[0]));",
4046 " c_revert((uchar *) &(now.c_state[0]));",
4049 " if (vsize != svtack->o_delta)",
4050 " Uerror(\"sv_restor\");",
4051 " if (!svtack->lst)",
4052 " Uerror(\"error: v_restor\");",
4053 " svtack = svtack->lst;",
4055 " printf(\" sv_restor\\n\");",
4060 "{ int i; char *z = (char *) &now;\n",
4061 " proc_offset[h] = stack->o_offset;",
4062 " proc_skip[h] = (uchar) stack->o_skip;",
4064 " p_name[h] = stack->o_name;",
4067 " for (i = vsize + stack->o_skip; i > vsize; i--)",
4068 " Mask[i-1] = 1; /* align */",
4070 " vsize += stack->o_skip;",
4071 " memcpy(z+vsize, stack->body, stack->o_delta);",
4072 " vsize += stack->o_delta;",
4074 " now._vsz = vsize;",
4077 " for (i = 1; i <= Air[((P0 *)pptr(h))->_t]; i++)",
4078 " Mask[vsize - i] = 1; /* pad */",
4079 " Mask[proc_offset[h]] = 1; /* _pid */",
4081 " if (BASE > 0 && h > 0)",
4082 " ((P0 *)pptr(h))->_pid = h-BASE;",
4084 " ((P0 *)pptr(h))->_pid = h;",
4085 " i = stack->o_delqs;",
4086 " now._nr_pr += 1;",
4087 " if (!stack->lst) /* debugging */",
4088 " Uerror(\"error: p_restor\");",
4089 " stack = stack->lst;",
4096 "{ char *z = (char *) &now;",
4100 " q_offset[now._nr_qs] = stack->o_offset;",
4101 " q_skip[now._nr_qs] = (uchar) stack->o_skip;",
4103 " q_name[now._nr_qs] = stack->o_name;",
4105 " vsize += stack->o_skip;",
4106 " memcpy(z+vsize, stack->body, stack->o_delta);",
4107 " vsize += stack->o_delta;",
4109 " now._vsz = vsize;",
4111 " now._nr_qs += 1;",
4113 " k_end = stack->o_offset;",
4114 " k = k_end - stack->o_skip;",
4117 " if (q_zero(now._nr_qs)) k_end += stack->o_delta;",
4120 " for ( ; k < k_end; k++)",
4123 " if (!stack->lst) /* debugging */",
4124 " Uerror(\"error: q_restor\");",
4125 " stack = stack->lst;",
4128 "typedef struct IntChunks {",
4130 " struct IntChunks *nxt;",
4132 "IntChunks *filled_chunks[512];",
4133 "IntChunks *empty_chunks[512];",
4136 "grab_ints(int nr)",
4138 " if (nr >= 512) Uerror(\"cannot happen grab_int\");",
4139 " if (filled_chunks[nr])",
4140 " { z = filled_chunks[nr];",
4141 " filled_chunks[nr] = filled_chunks[nr]->nxt;",
4143 " { z = (IntChunks *) emalloc(sizeof(IntChunks));",
4144 " z->ptr = (int *) emalloc(nr * sizeof(int));",
4146 " z->nxt = empty_chunks[nr];",
4147 " empty_chunks[nr] = z;",
4151 "ungrab_ints(int *p, int nr)",
4153 " if (!empty_chunks[nr]) Uerror(\"cannot happen ungrab_int\");",
4154 " z = empty_chunks[nr];",
4155 " empty_chunks[nr] = empty_chunks[nr]->nxt;",
4157 " z->nxt = filled_chunks[nr];",
4158 " filled_chunks[nr] = z;",
4161 "delproc(int sav, int h)",
4164 " int o_vsize = vsize;",
4166 " if (h+1 != (int) now._nr_pr) return 0;\n",
4167 " while (now._nr_qs",
4168 " && q_offset[now._nr_qs-1] > proc_offset[h])",
4172 " d = vsize - proc_offset[h];",
4174 " { if (!stack->nxt)",
4175 " { stack->nxt = (Stack *)",
4176 " emalloc(sizeof(Stack));",
4177 " stack->nxt->body = ",
4178 " emalloc(Maxbody*sizeof(char));",
4179 " stack->nxt->lst = stack;",
4182 " stack = stack->nxt;",
4183 " stack->o_offset = proc_offset[h];",
4184 "#if VECTORSZ>32000",
4185 " stack->o_skip = (int) proc_skip[h];",
4187 " stack->o_skip = (short) proc_skip[h];",
4190 " stack->o_name = p_name[h];",
4192 " stack->o_delta = d;",
4193 " stack->o_delqs = i;",
4194 " memcpy(stack->body, (char *)pptr(h), d);",
4196 " vsize = proc_offset[h];",
4197 " now._nr_pr = now._nr_pr - 1;",
4198 " memset((char *)pptr(h), 0, d);",
4199 " vsize -= (int) proc_skip[h];",
4201 " now._vsz = vsize;",
4204 " for (i = vsize; i < o_vsize; i++)",
4205 " Mask[i] = 0; /* reset */",
4211 "{ int h = now._nr_qs - 1;",
4212 " int d = vsize - q_offset[now._nr_qs - 1];",
4214 " int k, o_vsize = vsize;",
4217 " { if (!stack->nxt)",
4218 " { stack->nxt = (Stack *)",
4219 " emalloc(sizeof(Stack));",
4220 " stack->nxt->body = ",
4221 " emalloc(Maxbody*sizeof(char));",
4222 " stack->nxt->lst = stack;",
4225 " stack = stack->nxt;",
4226 " stack->o_offset = q_offset[h];",
4227 "#if VECTORSZ>32000",
4228 " stack->o_skip = (int) q_skip[h];",
4230 " stack->o_skip = (short) q_skip[h];",
4233 " stack->o_name = q_name[h];",
4235 " stack->o_delta = d;",
4236 " memcpy(stack->body, (char *)qptr(h), d);",
4238 " vsize = q_offset[h];",
4239 " now._nr_qs = now._nr_qs - 1;",
4240 " memset((char *)qptr(h), 0, d);",
4241 " vsize -= (int) q_skip[h];",
4243 " now._vsz = vsize;",
4246 " for (k = vsize; k < o_vsize; k++)",
4247 " Mask[k] = 0; /* reset */",
4253 " for (i = 0; i < (int) now._nr_qs; i++)",
4254 " { if (q_sz(i) > 0)",
4261 "{ int i; P0 *ptr;",
4262 " for (i = BASE; i < (int) now._nr_pr; i++)",
4263 " { ptr = (P0 *) pptr(i);",
4264 " if (!stopstate[ptr->_t][ptr->_p])",
4267 " if (strict) return qs_empty();",
4268 "#if defined(EVENT_TRACE) && !defined(OTIM)",
4269 " if (!stopstate[EVENT_TRACE][now._event] && !a_cycles)",
4270 " { printf(\"pan: event_trace not completed\\n\");",
4278 "checkcycles(void)",
4279 "{ uchar o_a_t = now._a_t;",
4281 " uchar o_cnt = now._cnt[1];",
4285 " struct H_el *sv = trpt->ostate; /* save */",
4287 " uchar prov = trpt->proviso; /* save */",
4291 " { int i; uchar *v = (uchar *) &now;",
4292 " printf(\" set Seed state \");",
4294 " if (fairness) printf(\"(cnt = %%d:%%d, nrpr=%%d) \",",
4295 " now._cnt[0], now._cnt[1], now._nr_pr);",
4297 " /* for (i = 0; i < n; i++) printf(\"%%d,\", v[i]); */",
4298 " printf(\"\\n\");",
4300 " printf(\"%%d: cycle check starts\\n\", depth);",
4302 " now._a_t |= (1|16|32);",
4303 " /* 1 = 2nd DFS; (16|32) to help hasher */",
4307 " { now._a_t &= ~2; /* pre-apply Rule 3 */",
4308 " now._cnt[1] = 0;", /* reset both a-bit and cnt=0 */
4309 " /* avoid matching seed on claim stutter on this state */",
4312 " now._cnt[1] = now._cnt[0];",
4315 " memcpy((char *)&A_Root, (char *)&now, vsize);",
4316 " A_depth = depthfound = depth;",
4317 " new_state(); /* start 2nd DFS */",
4318 " now._a_t = o_a_t;",
4320 " now._cnt[1] = o_cnt;",
4322 " A_depth = 0; depthfound = -1;",
4324 " printf(\"%%d: cycle check returns\\n\", depth);",
4328 " trpt->ostate = sv; /* restore */",
4330 " trpt->proviso = prov;",
4335 "#if defined(FULLSTACK) && defined(BITSTATE)",
4336 "struct H_el *Free_list = (struct H_el *) 0;",
4338 "onstack_init(void) /* to store stack states in a bitstate search */",
4339 "{ S_Tab = (struct H_el **) emalloc(maxdepth*sizeof(struct H_el *));",
4342 "grab_state(int n)",
4343 "{ struct H_el *v, *last = 0;",
4344 " if (H_tab == S_Tab)",
4345 " { for (v = Free_list; v && ((int) v->tagged >= n); v=v->nxt)",
4346 " { if ((int) v->tagged == n)",
4348 " last->nxt = v->nxt;",
4350 "gotcha: Free_list = v->nxt;",
4360 " /* new: second try */",
4361 " v = Free_list;", /* try to avoid emalloc */
4362 " if (v && ((int) v->tagged >= n))",
4366 " return (struct H_el *)",
4367 " emalloc(sizeof(struct H_el)+n-sizeof(unsigned));",
4370 "#define grab_state(n) (struct H_el *) \\",
4371 " emalloc(sizeof(struct H_el)+n-sizeof(unsigned));",
4375 "ordinal(char *v, long n, short tp)",
4376 "{ struct H_el *tmp, *ntmp; long m;",
4377 " struct H_el *olst = (struct H_el *) 0;",
4378 " s_hash((uchar *)v, n);",
4379 " tmp = H_tab[j1];",
4381 " { tmp = grab_state(n);",
4382 " H_tab[j1] = tmp;",
4384 " for ( ;; olst = tmp, tmp = tmp->nxt)",
4385 " { m = memcmp(((char *)&(tmp->state)), v, n);",
4386 " if (n == tmp->ln)",
4392 "Insert: ntmp = grab_state(n);",
4393 " ntmp->nxt = tmp;",
4395 " H_tab[j1] = ntmp;",
4397 " olst->nxt = ntmp;",
4400 " } else if (!tmp->nxt)",
4402 "Append: tmp->nxt = grab_state(n);",
4408 " if (n < tmp->ln)",
4410 " else if (!tmp->nxt)",
4413 " m = ++ncomps[tp];",
4415 " tmp->tagged = m;",
4419 " memcpy(((char *)&(tmp->state)), v, n);",
4423 " return tmp->tagged;",
4425 " return tmp->st_id;",
4430 "compress(char *vin, int nin) /* collapse compression */",
4431 "{ char *w, *v = (char *) &comp_now;",
4433 " unsigned long n;",
4435 " static uchar nbytes[513]; /* 1 + 256 + 256 */",
4436 " static unsigned short nbytelen;",
4437 " long col_q(int, char *);",
4438 " long col_p(int, char *);",
4441 " *v++ = now._a_t;",
4444 " for (i = 0; i < NFAIR; i++)",
4445 " *v++ = now._cnt[i];",
4450 "#ifndef JOINPROCS",
4451 " for (i = 0; i < (int) now._nr_pr; i++)",
4452 " { n = col_p(i, (char *) 0);",
4454 " nbytes[nbytelen] = 0;",
4456 " nbytes[nbytelen] = 1;",
4457 " *v++ = ((P0 *) pptr(i))->_t;",
4460 " if (n >= (1<<8))",
4461 " { nbytes[nbytelen]++;",
4462 " *v++ = (n>>8)&255;",
4464 " if (n >= (1<<16))",
4465 " { nbytes[nbytelen]++;",
4466 " *v++ = (n>>16)&255;",
4468 " if (n >= (1<<24))",
4469 " { nbytes[nbytelen]++;",
4470 " *v++ = (n>>24)&255;",
4476 " for (i = 0; i < (int) now._nr_pr; i++)",
4477 " x += col_p(i, x);",
4478 " n = ordinal(scratch, x-scratch, 2); /* procs */",
4480 " nbytes[nbytelen] = 0;",
4481 " if (n >= (1<<8))",
4482 " { nbytes[nbytelen]++;",
4483 " *v++ = (n>>8)&255;",
4485 " if (n >= (1<<16))",
4486 " { nbytes[nbytelen]++;",
4487 " *v++ = (n>>16)&255;",
4489 " if (n >= (1<<24))",
4490 " { nbytes[nbytelen]++;",
4491 " *v++ = (n>>24)&255;",
4496 " for (i = 0; i < (int) now._nr_qs; i++)",
4497 " { n = col_q(i, (char *) 0);",
4498 " nbytes[nbytelen] = 0;",
4500 " if (n >= (1<<8))",
4501 " { nbytes[nbytelen]++;",
4502 " *v++ = (n>>8)&255;",
4504 " if (n >= (1<<16))",
4505 " { nbytes[nbytelen]++;",
4506 " *v++ = (n>>16)&255;",
4508 " if (n >= (1<<24))",
4509 " { nbytes[nbytelen]++;",
4510 " *v++ = (n>>24)&255;",
4517 " /* 3 = _a_t, _nr_pr, _nr_qs */",
4518 " w = (char *) &now + 3 * sizeof(uchar);",
4523 "#if VECTORSZ<65536",
4524 " w = (char *) &(now._vsz) + sizeof(unsigned short);",
4526 " w = (char *) &(now._vsz) + sizeof(unsigned long);",
4530 " *x++ = now._nr_pr;",
4531 " *x++ = now._nr_qs;",
4533 " if (now._nr_qs > 0 && qptr(0) < pptr(0))",
4534 " n = qptr(0) - (uchar *) w;",
4536 " n = pptr(0) - (uchar *) w;",
4537 " j = w - (char *) &now;",
4538 " for (i = 0; i < (int) n; i++, w++)",
4539 " if (!Mask[j++]) *x++ = *w;",
4541 " for (i = 0; i < (int) now._nr_qs; i++)",
4542 " x += col_q(i, x);",
4546 " for (i = 0, j = 6; i < nbytelen; i++)",
4552 " *x |= (nbytes[i] << j);",
4555 " for (j = 0; j < WS-1; j++)",
4558 " n = ordinal(scratch, x-scratch, 0); /* globals */",
4560 " if (n >= (1<< 8)) { *v++ = (n>> 8)&255; j++; }",
4561 " if (n >= (1<<16)) { *v++ = (n>>16)&255; j++; }",
4562 " if (n >= (1<<24)) { *v++ = (n>>24)&255; j++; }",
4563 " *v++ = j; /* add last count as a byte */",
4565 " for (i = 0; i < WS-1; i++)",
4569 " printf(\"collapse %%d -> %%d\\n\",",
4570 " vsize, v - (char *)&comp_now);",
4572 " return v - (char *)&comp_now;",
4576 "#if !defined(NOCOMP)",
4578 "compress(char *vin, int n) /* default compression */",
4582 " s_hash((uchar *)vin, n); /* sets K1 and K2 */",
4585 " { delta++; /* _a_t */",
4587 " if (S_A > NFAIR)",
4588 " delta += NFAIR; /* _cnt[] */",
4592 " memcpy((char *) &comp_now + delta, (char *) &K1, WS);",
4595 " memcpy((char *) &comp_now + delta, (char *) &K2, HC);",
4601 " char *v = (char *) &comp_now;",
4603 " for (i = 0; i < n; i++, vv++)",
4604 " if (!Mask[i]) *v++ = *vv;",
4605 " for (i = 0; i < WS-1; i++)",
4609 " printf(\"compress %%d -> %%d\\n\",",
4610 " n, v - (char *)&comp_now);",
4612 " return v - (char *)&comp_now;",
4617 "#if defined(FULLSTACK) && defined(BITSTATE)",
4619 "#if !defined(onstack_now)",
4620 "int onstack_now(void) {}", /* to suppress compiler errors */
4622 "#if !defined(onstack_put)",
4623 "void onstack_put(void) {}", /* for this invalid combination */
4625 "#if !defined(onstack_zap)",
4626 "void onstack_zap(void) {}", /* of directives */
4630 "onstack_zap(void)",
4631 "{ struct H_el *v, *w, *last = 0;",
4632 " struct H_el **tmp = H_tab;",
4633 " char *nv; int n, m;\n",
4636 " nv = (char *) &comp_now;",
4637 " n = compress((char *)&now, vsize);",
4639 "#if defined(BITSTATE) && defined(LC)",
4640 " nv = (char *) &comp_now;",
4641 " n = compact_stack((char *)&now, vsize);",
4643 " nv = (char *) &now;",
4647 "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))",
4648 " s_hash((uchar *)nv, n);",
4651 " for (v = S_Tab[j1]; v; Zh++, last=v, v=v->nxt)",
4652 " { m = memcmp(&(v->state), nv, n);",
4659 " Uerror(\"stack out of wack - zap\");",
4664 " last->nxt = v->nxt;",
4666 " S_Tab[j1] = v->nxt;",
4667 " v->tagged = (unsigned) n;",
4668 "#if !defined(NOREDUCE) && !defined(SAFETY)",
4671 " v->nxt = last = (struct H_el *) 0;",
4672 " for (w = Free_list; w; Fa++, last=w, w = w->nxt)",
4673 " { if ((int) w->tagged <= n)",
4675 " { v->nxt = w; /* was: v->nxt = w->nxt; */",
4678 " { v->nxt = Free_list;",
4690 "onstack_put(void)",
4691 "{ struct H_el **tmp = H_tab;",
4693 " if (hstore((char *)&now, vsize) != 0)",
4694 "#if defined(BITSTATE) && defined(LC)",
4695 " printf(\"pan: warning, double stack entry\\n\");",
4697 " Uerror(\"cannot happen - unstack_put\");",
4700 " trpt->ostate = Lstate;",
4704 "onstack_now(void)",
4705 "{ struct H_el *tmp;",
4706 " struct H_el **tmp2 = H_tab;",
4707 " char *v; int n, m = 1;\n",
4710 "#if defined(BITSTATE) && defined(LC)",
4711 " v = (char *) &comp_now;",
4712 " n = compact_stack((char *)&now, vsize);",
4714 " v = (char *) &now;",
4718 " v = (char *) &comp_now;",
4719 " n = compress((char *)&now, vsize);",
4721 "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))",
4722 " s_hash((uchar *)v, n);",
4725 " for (tmp = S_Tab[j1]; tmp; Zn++, tmp = tmp->nxt)",
4726 " { m = memcmp(((char *)&(tmp->state)),v,n);",
4728 " { Lstate = (struct H_el *) tmp;",
4732 " return (m == 0);",
4743 " { void r_xpoint(void);",
4747 " dfa_init((unsigned short) (MA+a_cycles));",
4750 "#if !defined(MA) || defined(COLLAPSE)",
4751 " H_tab = (struct H_el **)",
4752 " emalloc((1L<<ssize)*sizeof(struct H_el *));",
4757 "#if !defined(BITSTATE) || defined(FULLSTACK)",
4761 "dumpstate(int wasnew, char *v, int n, int tag)",
4765 " { printf(\"\tstate tags %%d (%%d::%%d): \",",
4766 " V_A, wasnew, v[0]);",
4768 " printf(\" %%d \", tag);",
4770 " printf(\"\\n\");",
4775 " printf(\"\t State: \");",
4776 " for (i = 0; i < vsize; i++) printf(\"%%d%%s,\",",
4777 " ((char *)&now)[i], Mask[i]?\"*\":\"\");",
4779 " printf(\"\\n\tVector: \");",
4780 " for (i = 0; i < n; i++) printf(\"%%d,\", v[i]);",
4781 " printf(\"\\n\");",
4788 "gstore(char *vin, int nin, uchar pbit)",
4791 " static uchar Info[MA+1];",
4793 " n = compress(vin, nin);",
4794 " v = (uchar *) &comp_now;",
4800 " { printf(\"pan: error, MA too small, recompile pan.c\");",
4801 " printf(\" with -DMA=N with N>%%d\\n\", n);",
4802 " Uerror(\"aborting\");",
4804 " if (n > (int) maxgs) maxgs = (unsigned int) n;",
4806 " for (i = 0; i < n; i++)",
4808 " for ( ; i < MA-1; i++)",
4810 " Info[MA-1] = pbit;",
4811 " if (a_cycles) /* place _a_t at the end */",
4812 " { Info[MA] = Info[0]; Info[0] = 0; }",
4813 " if (!dfa_store(Info))",
4816 " && depth > A_depth)",
4817 " { Info[MA] &= ~(1|16|32); /* _a_t */",
4818 " if (dfa_member(MA))", /* was !dfa_member(MA) */
4819 " { Info[MA-1] = 4; /* off-stack bit */",
4821 " if (!dfa_member(MA-1))",
4824 " printf(\"intersected 1st dfs stack\\n\");",
4829 " printf(\"new state\\n\");",
4831 " return 0; /* new state */",
4835 " { Info[MA-1] = 1; /* proviso bit */",
4837 " trpt->proviso = dfa_member(MA-1);",
4839 " Info[MA-1] = 4; /* off-stack bit */",
4840 " if (dfa_member(MA-1)) {",
4842 " printf(\"old state\\n\");",
4844 " return 1; /* off-stack */",
4847 " printf(\"on-stack\\n\");",
4849 " return 2; /* on-stack */",
4854 " printf(\"old state\\n\");",
4856 " return 1; /* old state */",
4860 "#if defined(BITSTATE) && defined(LC)",
4862 "compact_stack(char *vin, int n)", /* special case of HC4 */
4864 " s_hash((uchar *)vin, n); /* sets K1 and K2 */",
4866 " delta++; /* room for state[0] |= 128 */",
4868 " memcpy((char *) &comp_now + delta, (char *) &K1, WS);",
4870 " memcpy((char *) &comp_now + delta, (char *) &K2, WS);",
4871 " delta += WS; /* use all available bits */",
4877 "hstore(char *vin, int nin) /* hash table storage */",
4878 "{ struct H_el *tmp, *ntmp, *olst = (struct H_el *) 0;",
4879 " char *v; int n, m=0;",
4883 "#ifdef NOCOMP", /* defined by BITSTATE */
4884 "#if defined(BITSTATE) && defined(LC)",
4885 " if (S_Tab == H_tab)",
4886 " { v = (char *) &comp_now;",
4887 " n = compact_stack(vin, nin);",
4889 " { v = vin; n = nin;",
4892 " v = vin; n = nin;",
4895 " v = (char *) &comp_now;",
4897 " rem_a = now._a_t;", /* 4.3.0 */
4898 " now._a_t = 0;", /* for hashing/state matching to work right */
4900 " n = compress(vin, nin);", /* with HC, this calls s_hash */
4902 " now._a_t = rem_a;", /* 4.3.0 */
4906 " { v[0] = 0; /* _a_t */",
4908 " if (S_A > NFAIR)",
4909 " for (m = 0; m < NFAIR; m++)",
4910 " v[m+1] = 0; /* _cnt[] */",
4916 "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))",
4917 " s_hash((uchar *)v, n);",
4919 " tmp = H_tab[j1];",
4921 " { tmp = grab_state(n);",
4922 " H_tab[j1] = tmp;",
4924 " { for (;; hcmp++, olst = tmp, tmp = tmp->nxt)",
4925 " { /* skip the _a_t and the _cnt bytes */",
4927 " if (tmp->ln != 0)",
4928 " { if (!tmp->nxt) goto Append;",
4932 " m = memcmp(((char *)&(tmp->state)) + S_A, ",
4933 " v + S_A, n - S_A);",
4944 " { if ((((char *)&(tmp->state))[0] & V_A) != V_A)",
4945 " { wasnew = 1; nShadow++;",
4946 " ((char *)&(tmp->state))[0] |= V_A;",
4949 " if (S_A > NFAIR)",
4950 " { /* 0 <= now._cnt[now._a_t&1] < MAXPROC */",
4951 " unsigned ci, bp; /* index, bit pos */",
4952 " ci = (now._cnt[now._a_t&1] / 8);",
4953 " bp = (now._cnt[now._a_t&1] - 8*ci);",
4954 " if (now._a_t&1) /* use tail-bits in _cnt */",
4955 " { ci = (NFAIR - 1) - ci;",
4956 " bp = 7 - bp; /* bp = 0..7 */",
4958 " ci++; /* skip over _a_t */",
4959 " bp = 1 << bp; /* the bit mask */",
4960 " if ((((char *)&(tmp->state))[ci] & bp)==0)",
4965 " ((char *)&(tmp->state))[ci] |= bp;",
4968 " /* else: wasnew == 0, i.e., old state */",
4975 "#ifndef SAFETY", /* or else wasnew == 0 */
4977 " { Lstate = (struct H_el *) tmp;",
4978 " tmp->tagged |= V_A;",
4979 " if ((now._a_t&1)",
4980 " && (tmp->tagged&A_V)",
4981 " && depth > A_depth)",
4985 " printf(\"1st dfs-stack intersected on state %%d+\\n\",",
4986 " (int) tmp->st_id);",
4991 " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);",
4994 " dumpstate(1, (char *)&(tmp->state),n,tmp->tagged);",
4999 " if ((S_A)?(tmp->tagged&V_A):tmp->tagged)",
5000 " { Lstate = (struct H_el *) tmp;",
5002 " /* already on current dfs stack */",
5003 " /* but may also be on 1st dfs stack */",
5004 " if ((now._a_t&1)",
5005 " && (tmp->tagged&A_V)",
5007 " && depth > A_depth",
5008 /* new (Zhang's example) */
5010 " && (!fairness || now._cnt[1] <= 1)",
5017 " printf(\"\tStack state %%d\\n\", (int) tmp->st_id);",
5020 " dumpstate(0, (char *)&(tmp->state),n,tmp->tagged);",
5022 " return 2; /* match on stack */",
5028 " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);",
5031 " dumpstate(1, (char *)&(tmp->state), n, 0);",
5037 " printf(\"\tOld state %%d\\n\", (int) tmp->st_id);",
5040 " dumpstate(0, (char *)&(tmp->state), n, 0);",
5043 " if (tmp->D > depth)",
5044 " { tmp->D = depth;",
5046 " printf(\"\t\tReVisiting (from smaller depth)\\n\");",
5050 possible variation of iterative search for shortest counter-example (pan -i
5051 and pan -I) suggested by Pierre Moro (for safety properties):
5052 state revisits on shorter depths do not start until after
5053 the first counter-example is found. this assumes that the max search
5054 depth is set large enough that a first (possibly long) counter-example
5056 if set too short, this variant can miss the counter-example, even if
5057 it would otherwise be shorter than the depth-limit.
5058 (p.m. unsure if this preserves the guarantee of finding the
5059 shortest counter-example - so not enabled yet)
5060 " if (errors > 0 && iterative)", /* Moro */
5065 "#if defined(BFS) && defined(Q_PROVISO)",
5066 " Lstate = (struct H_el *) tmp;",
5068 " return 1; /* match outside stack */",
5069 " } else if (m < 0)",
5070 " { /* insert state before tmp */",
5071 " ntmp = grab_state(n);",
5072 " ntmp->nxt = tmp;",
5074 " H_tab[j1] = ntmp;",
5076 " olst->nxt = ntmp;",
5079 " } else if (!tmp->nxt)",
5080 " { /* append after tmp */",
5084 " tmp->nxt = grab_state(n);",
5090 " tmp->st_id = (unsigned) nstates;",
5092 " printf(\" Push state %%d\\n\", ((int) nstates) - 1);",
5094 " printf(\" New state %%d\\n\", (int) nstates);",
5097 "#if !defined(SAFETY) || defined(REACH)",
5105 " if (S_A > NFAIR)",
5106 " { unsigned ci, bp; /* as above */",
5107 " ci = (now._cnt[now._a_t&1] / 8);",
5108 " bp = (now._cnt[now._a_t&1] - 8*ci);",
5110 " { ci = (NFAIR - 1) - ci;",
5111 " bp = 7 - bp; /* bp = 0..7 */",
5113 " v[1+ci] = 1 << bp;",
5119 " memcpy(((char *)&(tmp->state)), v, n);",
5121 " tmp->tagged = (S_A)?V_A:(depth+1);",
5123 " dumpstate(-1, v, n, tmp->tagged);",
5125 " Lstate = (struct H_el *) tmp;",
5128 " dumpstate(-1, v, n, 0);",
5134 "#include TRANSITIONS",