pangen4.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /***** spin: pangen4.h *****/
  10. /* Copyright (c) 1997-2003 by Lucent Technologies, Bell Laboratories. */
  11. /* All Rights Reserved. This software is for educational purposes only. */
  12. /* No guarantee whatsoever is expressed or implied by the distribution of */
  13. /* this code. Permission is given to distribute this code provided that */
  14. /* this introductory message is not removed and no monies are exchanged. */
  15. /* Software written by Gerard J. Holzmann. For tool documentation see: */
  16. /* http://spinroot.com/ */
  17. /* Send all bug-reports and/or questions to: bugs@spinroot.com */
  18. /* The DFA code below was written by Anuj Puri and Gerard J. Holzmann in */
  19. /* May 1997, and was inspired by earlier work on data compression using */
  20. /* sharing tree data structures and graph-encoded sets by J-Ch. Gregoire */
  21. /* (INRS Telecom, Quebec, Canada) and D.Zampunieris (Univ.Namur, Belgium) */
  22. /* The splay routine code included here is based on the public domain */
  23. /* version written by D. Sleator <sleator@cs.cmu.edu> in 1992. */
  24. static char *Dfa[] = {
  25. "#ifdef MA",
  26. "/*",
  27. "#include <stdio.h>",
  28. "#define uchar unsigned char",
  29. "*/",
  30. "#define ulong unsigned long",
  31. "#define ushort unsigned short",
  32. "",
  33. "#define TWIDTH 256",
  34. "#define HASH(y,n) (n)*(((long)y))",
  35. "#define INRANGE(e,h) ((h>=e->From && h<=e->To)||(e->s==1 && e->S==h))",
  36. "",
  37. "extern char *emalloc(unsigned long); /* imported routine */",
  38. "extern void dfa_init(ushort); /* 4 exported routines */",
  39. "extern int dfa_member(ulong);",
  40. "extern int dfa_store(uchar *);",
  41. "extern void dfa_stats(void);",
  42. "",
  43. "typedef struct Edge {",
  44. " uchar From, To; /* max range 0..255 */",
  45. " uchar s, S; /* if s=1, S is singleton */",
  46. " struct Vertex *Dst;",
  47. " struct Edge *Nxt;",
  48. "} Edge;",
  49. "",
  50. "typedef struct Vertex {",
  51. " ulong key, num; /* key for splay tree, nr incoming edges */",
  52. " uchar from[2], to[2]; /* in-node predefined edge info */",
  53. " struct Vertex *dst[2];/* most nodes have 2 or more edges */",
  54. " struct Edge *Succ; /* in case there are more edges */",
  55. " struct Vertex *lnk, *left, *right; /* splay tree plumbing */",
  56. "} Vertex;",
  57. "",
  58. "static Edge *free_edges;",
  59. "static Vertex *free_vertices;",
  60. "static Vertex **layers; /* one splay tree of nodes per layer */",
  61. "static Vertex **path; /* run of word in the DFA */",
  62. "static Vertex *R, *F, *NF; /* Root, Final, Not-Final */",
  63. "static uchar *word, *lastword;/* string, and last string inserted */",
  64. "static int dfa_depth, iv=0, nv=0, pfrst=0, Tally;",
  65. "",
  66. "static void insert_it(Vertex *, int); /* splay-tree code */",
  67. "static void delete_it(Vertex *, int);",
  68. "static Vertex *find_it(Vertex *, Vertex *, uchar, int);",
  69. "",
  70. "static void",
  71. "recyc_edges(Edge *e)",
  72. "{",
  73. " if (!e) return;",
  74. " recyc_edges(e->Nxt);",
  75. " e->Nxt = free_edges;",
  76. " free_edges = e;",
  77. "}",
  78. "",
  79. "static Edge *",
  80. "new_edge(Vertex *dst)",
  81. "{ Edge *e;",
  82. "",
  83. " if (free_edges)",
  84. " { e = free_edges;",
  85. " free_edges = e->Nxt;",
  86. " e->From = e->To = e->s = e->S = 0;",
  87. " e->Nxt = (Edge *) 0;",
  88. " } else",
  89. " e = (Edge *) emalloc(sizeof(Edge));",
  90. " e->Dst = dst;",
  91. "",
  92. " return e;",
  93. "}",
  94. "",
  95. "static void",
  96. "recyc_vertex(Vertex *v)",
  97. "{",
  98. " recyc_edges(v->Succ);",
  99. " v->Succ = (Edge *) free_vertices;",
  100. " free_vertices = v;",
  101. " nr_states--;",
  102. "}",
  103. "",
  104. "static Vertex *",
  105. "new_vertex(void)",
  106. "{ Vertex *v;",
  107. "",
  108. " if (free_vertices)",
  109. " { v = free_vertices;",
  110. " free_vertices = (Vertex *) v->Succ;",
  111. " v->Succ = (Edge *) 0;",
  112. " v->num = 0;",
  113. " } else",
  114. " v = (Vertex *) emalloc(sizeof(Vertex));",
  115. "",
  116. " nr_states++;",
  117. " return v; ",
  118. "}",
  119. "",
  120. "static Vertex *",
  121. "allDelta(Vertex *v, int n)",
  122. "{ Vertex *dst = new_vertex();",
  123. "",
  124. " v->from[0] = 0;",
  125. " v->to[0] = 255;",
  126. " v->dst[0] = dst;",
  127. " dst->num = 256;",
  128. " insert_it(v, n);",
  129. " return dst;",
  130. "}",
  131. "",
  132. "static void",
  133. "insert_edge(Vertex *v, Edge *e)",
  134. "{ /* put new edge first */",
  135. " if (!v->dst[0])",
  136. " { v->dst[0] = e->Dst;",
  137. " v->from[0] = e->From;",
  138. " v->to[0] = e->To;",
  139. " recyc_edges(e);",
  140. " return;",
  141. " }",
  142. " if (!v->dst[1])",
  143. " { v->from[1] = v->from[0]; v->from[0] = e->From;",
  144. " v->to[1] = v->to[0]; v->to[0] = e->To;",
  145. " v->dst[1] = v->dst[0]; v->dst[0] = e->Dst;",
  146. " recyc_edges(e);",
  147. " return;",
  148. " } /* shift */",
  149. " { int f = v->from[1];",
  150. " int t = v->to[1];",
  151. " Vertex *d = v->dst[1];",
  152. " v->from[1] = v->from[0]; v->from[0] = e->From;",
  153. " v->to[1] = v->to[0]; v->to[0] = e->To;",
  154. " v->dst[1] = v->dst[0]; v->dst[0] = e->Dst;",
  155. " e->From = f;",
  156. " e->To = t;",
  157. " e->Dst = d;",
  158. " }",
  159. " e->Nxt = v->Succ;",
  160. " v->Succ = e;",
  161. "}",
  162. "",
  163. "static void",
  164. "copyRecursive(Vertex *v, Edge *e)",
  165. "{ Edge *f;",
  166. " if (e->Nxt) copyRecursive(v, e->Nxt);",
  167. " f = new_edge(e->Dst);",
  168. " f->From = e->From;",
  169. " f->To = e->To;",
  170. " f->s = e->s;",
  171. " f->S = e->S;",
  172. " f->Nxt = v->Succ;",
  173. " v->Succ = f;",
  174. "}",
  175. "",
  176. "static void",
  177. "copyEdges(Vertex *to, Vertex *from)",
  178. "{ int i;",
  179. " for (i = 0; i < 2; i++)",
  180. " { to->from[i] = from->from[i];",
  181. " to->to[i] = from->to[i];",
  182. " to->dst[i] = from->dst[i];",
  183. " }",
  184. " if (from->Succ) copyRecursive(to, from->Succ);",
  185. "}",
  186. "",
  187. "static Edge *",
  188. "cacheDelta(Vertex *v, int h, int first)",
  189. "{ static Edge *ov, tmp; int i;",
  190. "",
  191. " if (!first && INRANGE(ov,h))",
  192. " return ov; /* intercepts about 10%% */",
  193. " for (i = 0; i < 2; i++)",
  194. " if (v->dst[i] && h >= v->from[i] && h <= v->to[i])",
  195. " { tmp.From = v->from[i];",
  196. " tmp.To = v->to[i];",
  197. " tmp.Dst = v->dst[i];",
  198. " tmp.s = tmp.S = 0;",
  199. " ov = &tmp;",
  200. " return ov;",
  201. " }",
  202. " for (ov = v->Succ; ov; ov = ov->Nxt)",
  203. " if (INRANGE(ov,h)) return ov;",
  204. "",
  205. " Uerror(\"cannot get here, cacheDelta\");",
  206. " return (Edge *) 0;",
  207. "}",
  208. "",
  209. "static Vertex *",
  210. "Delta(Vertex *v, int h) /* v->delta[h] */",
  211. "{ Edge *e;",
  212. "",
  213. " if (v->dst[0] && h >= v->from[0] && h <= v->to[0])",
  214. " return v->dst[0]; /* oldest edge */",
  215. " if (v->dst[1] && h >= v->from[1] && h <= v->to[1])",
  216. " return v->dst[1];",
  217. " for (e = v->Succ; e; e = e->Nxt)",
  218. " if (INRANGE(e,h))",
  219. " return e->Dst;",
  220. " Uerror(\"cannot happen Delta\");",
  221. " return (Vertex *) 0;",
  222. "}",
  223. "",
  224. "static void",
  225. "numDelta(Vertex *v, int d)",
  226. "{ Edge *e;",
  227. " ulong cnt;",
  228. " int i;",
  229. "",
  230. " for (i = 0; i < 2; i++)",
  231. " if (v->dst[i])",
  232. " { cnt = v->dst[i]->num + d*(1 + v->to[i] - v->from[i]);",
  233. " if (d == 1 && cnt < v->dst[i]->num) goto bad;",
  234. " v->dst[i]->num = cnt;",
  235. " }",
  236. " for (e = v->Succ; e; e = e->Nxt)",
  237. " { cnt = e->Dst->num + d*(1 + e->To - e->From + e->s);",
  238. " if (d == 1 && cnt < e->Dst->num)",
  239. "bad: Uerror(\"too many incoming edges\");",
  240. " e->Dst->num = cnt;",
  241. " }",
  242. "}",
  243. "",
  244. "static void",
  245. "setDelta(Vertex *v, int h, Vertex *newdst) /* v->delta[h] = newdst; */",
  246. "{ Edge *e, *f = (Edge *) 0, *g;",
  247. " int i;",
  248. "",
  249. " /* remove the old entry, if there */",
  250. " for (i = 0; i < 2; i++)",
  251. " if (v->dst[i] && h >= v->from[i] && h <= v->to[i])",
  252. " { if (h == v->from[i])",
  253. " { if (h == v->to[i])",
  254. " { v->dst[i] = (Vertex *) 0;",
  255. " v->from[i] = v->to[i] = 0;",
  256. " } else",
  257. " v->from[i]++;",
  258. " } else if (h == v->to[i])",
  259. " { v->to[i]--;",
  260. " } else",
  261. " { g = new_edge(v->dst[i]);/* same dst */",
  262. " g->From = v->from[i];",
  263. " g->To = h-1; /* left half */",
  264. " v->from[i] = h+1; /* right half */",
  265. " insert_edge(v, g);",
  266. " }",
  267. " goto part2;",
  268. " }",
  269. " for (e = v->Succ; e; f = e, e = e->Nxt)",
  270. " { if (e->s == 1 && e->S == h)",
  271. " { e->s = e->S = 0;",
  272. " goto rem_tst;",
  273. " }",
  274. " if (h >= e->From && h <= e->To)",
  275. " { if (h == e->From)",
  276. " { if (h == e->To)",
  277. " { if (e->s)",
  278. " { e->From = e->To = e->S;",
  279. " e->s = 0;",
  280. " break;",
  281. " } else",
  282. " goto rem_do;",
  283. " } else",
  284. " e->From++;",
  285. " } else if (h == e->To)",
  286. " { e->To--;",
  287. " } else /* split */",
  288. " { g = new_edge(e->Dst); /* same dst */",
  289. " g->From = e->From;",
  290. " g->To = h-1; /* g=left half */",
  291. " e->From = h+1; /* e=right half */",
  292. " g->Nxt = e->Nxt; /* insert g */",
  293. " e->Nxt = g; /* behind e */",
  294. " break; /* done */",
  295. " }",
  296. "",
  297. "rem_tst: if (e->From > e->To)",
  298. " { if (e->s == 0) {",
  299. "rem_do: if (f)",
  300. " f->Nxt = e->Nxt;",
  301. " else",
  302. " v->Succ = e->Nxt;",
  303. " e->Nxt = (Edge *) 0;",
  304. " recyc_edges(e);",
  305. " } else",
  306. " { e->From = e->To = e->S;",
  307. " e->s = 0;",
  308. " } }",
  309. " break;",
  310. " } }",
  311. "part2:",
  312. " /* check if newdst is already there */",
  313. " for (i = 0; i < 2; i++)",
  314. " if (v->dst[i] == newdst)",
  315. " { if (h+1 == (int) v->from[i])",
  316. " { v->from[i] = h;",
  317. " return;",
  318. " }",
  319. " if (h == (int) v->to[i]+1)",
  320. " { v->to[i] = h;",
  321. " return;",
  322. " } }",
  323. " for (e = v->Succ; e; e = e->Nxt)",
  324. " { if (e->Dst == newdst)",
  325. " { if (h+1 == (int) e->From)",
  326. " { e->From = h;",
  327. " if (e->s == 1 && e->S+1 == e->From)",
  328. " { e->From = e->S;",
  329. " e->s = e->S = 0;",
  330. " }",
  331. " return;",
  332. " }",
  333. " if (h == (int) e->To+1)",
  334. " { e->To = h;",
  335. " if (e->s == 1 && e->S == e->To+1)",
  336. " { e->To = e->S;",
  337. " e->s = e->S = 0;",
  338. " }",
  339. " return;",
  340. " }",
  341. " if (e->s == 0)",
  342. " { e->s = 1;",
  343. " e->S = h;",
  344. " return;",
  345. " } } }",
  346. " /* add as a new edge */",
  347. " e = new_edge(newdst);",
  348. " e->From = e->To = h;",
  349. " insert_edge(v, e);",
  350. "}",
  351. "",
  352. "static ulong",
  353. "cheap_key(Vertex *v)",
  354. "{ ulong vk2 = 0;",
  355. "",
  356. " if (v->dst[0])",
  357. " { vk2 = (ulong) v->dst[0];",
  358. " if ((ulong) v->dst[1] > vk2)",
  359. " vk2 = (ulong) v->dst[1];",
  360. " } else if (v->dst[1])",
  361. " vk2 = (ulong) v->dst[1]; ",
  362. " if (v->Succ)",
  363. " { Edge *e;",
  364. " for (e = v->Succ; e; e = e->Nxt)",
  365. " if ((ulong) e->Dst > vk2)",
  366. " vk2 = (ulong) e->Dst;",
  367. " }",
  368. " Tally = (vk2>>2)&(TWIDTH-1);",
  369. " return v->key;",
  370. "}",
  371. "",
  372. "static ulong",
  373. "mk_key(Vertex *v) /* not sensitive to order */",
  374. "{ ulong m = 0, vk2 = 0;",
  375. " Edge *e;",
  376. "",
  377. " if (v->dst[0])",
  378. " { m += HASH(v->dst[0], v->to[0] - v->from[0] + 1);",
  379. " vk2 = (ulong) v->dst[0]; ",
  380. " }",
  381. " if (v->dst[1])",
  382. " { m += HASH(v->dst[1], v->to[1] - v->from[1] + 1);",
  383. " if ((ulong) v->dst[1] > vk2) vk2 = (ulong) v->dst[1]; ",
  384. " }",
  385. " for (e = v->Succ; e; e = e->Nxt)",
  386. " { m += HASH(e->Dst, e->To - e->From + 1 + e->s);",
  387. " if ((ulong) e->Dst > vk2) vk2 = (ulong) e->Dst; ",
  388. " }",
  389. " Tally = (vk2>>2)&(TWIDTH-1);",
  390. " return m;",
  391. "}",
  392. "",
  393. "static ulong",
  394. "mk_special(int sigma, Vertex *n, Vertex *v)",
  395. "{ ulong m = 0, vk2 = 0;",
  396. " Edge *f;",
  397. " int i;",
  398. "",
  399. " for (i = 0; i < 2; i++)",
  400. " if (v->dst[i])",
  401. " { if (sigma >= v->from[i] && sigma <= v->to[i])",
  402. " { m += HASH(v->dst[i], v->to[i]-v->from[i]);",
  403. " if ((ulong) v->dst[i] > vk2",
  404. " && v->to[i] > v->from[i])",
  405. " vk2 = (ulong) v->dst[i]; ",
  406. " } else",
  407. " { m += HASH(v->dst[i], v->to[i]-v->from[i]+1);",
  408. " if ((ulong) v->dst[i] > vk2)",
  409. " vk2 = (ulong) v->dst[i]; ",
  410. " } }",
  411. " for (f = v->Succ; f; f = f->Nxt)",
  412. " { if (sigma >= f->From && sigma <= f->To)",
  413. " { m += HASH(f->Dst, f->To - f->From + f->s);",
  414. " if ((ulong) f->Dst > vk2",
  415. " && f->To - f->From + f->s > 0)",
  416. " vk2 = (ulong) f->Dst; ",
  417. " } else if (f->s == 1 && sigma == f->S)",
  418. " { m += HASH(f->Dst, f->To - f->From + 1);",
  419. " if ((ulong) f->Dst > vk2) vk2 = (ulong) f->Dst; ",
  420. " } else",
  421. " { m += HASH(f->Dst, f->To - f->From + 1 + f->s);",
  422. " if ((ulong) f->Dst > vk2) vk2 = (ulong) f->Dst; ",
  423. " } }",
  424. "",
  425. " if ((ulong) n > vk2) vk2 = (ulong) n; ",
  426. " Tally = (vk2>>2)&(TWIDTH-1);",
  427. " m += HASH(n, 1);",
  428. " return m;",
  429. "}",
  430. "",
  431. "void ",
  432. "dfa_init(ushort nr_layers)",
  433. "{ int i; Vertex *r, *t;",
  434. "",
  435. " dfa_depth = nr_layers; /* one byte per layer */",
  436. " path = (Vertex **) emalloc((dfa_depth+1)*sizeof(Vertex *));",
  437. " layers = (Vertex **) emalloc(TWIDTH*(dfa_depth+1)*sizeof(Vertex *));",
  438. " lastword = (uchar *) emalloc((dfa_depth+1)*sizeof(uchar));",
  439. " lastword[dfa_depth] = lastword[0] = 255;",
  440. " path[0] = R = new_vertex(); F = new_vertex();",
  441. "",
  442. " for (i = 1, r = R; i < dfa_depth; i++, r = t)",
  443. " t = allDelta(r, i-1);",
  444. " NF = allDelta(r, i-1);",
  445. "}",
  446. "",
  447. "#if 0",
  448. "static void complement_dfa(void) { Vertex *tmp = F; F = NF; NF = tmp; }",
  449. "#endif",
  450. "",
  451. "double",
  452. "tree_stats(Vertex *t)",
  453. "{ Edge *e; double cnt=0.0;",
  454. " if (!t) return 0;",
  455. " if (!t->key) return 0;",
  456. " t->key = 0; /* precaution */",
  457. " if (t->dst[0]) cnt++;",
  458. " if (t->dst[1]) cnt++;",
  459. " for (e = t->Succ; e; e = e->Nxt)",
  460. " cnt++;",
  461. " cnt += tree_stats(t->lnk);",
  462. " cnt += tree_stats(t->left);",
  463. " cnt += tree_stats(t->right);",
  464. " return cnt;",
  465. "}",
  466. "",
  467. "void",
  468. "dfa_stats(void)",
  469. "{ int i, j; double cnt = 0.0;",
  470. " for (j = 0; j < TWIDTH; j++)",
  471. " for (i = 0; i < dfa_depth+1; i++)",
  472. " cnt += tree_stats(layers[i*TWIDTH+j]);",
  473. " printf(\"Minimized Automaton:\t%%6d nodes and %%6g edges\\n\",",
  474. " nr_states, cnt);",
  475. "}",
  476. "",
  477. "int",
  478. "dfa_member(ulong n)",
  479. "{ Vertex **p, **q;",
  480. " uchar *w = &word[n];",
  481. " int i;",
  482. "",
  483. " p = &path[n]; q = (p+1);",
  484. " for (i = n; i < dfa_depth; i++)",
  485. " *q++ = Delta(*p++, *w++);",
  486. " return (*p == F);",
  487. "}",
  488. "",
  489. "int",
  490. "dfa_store(uchar *sv)",
  491. "{ Vertex **p, **q, *s, *y, *old, *new = F;",
  492. " uchar *w, *u = lastword;",
  493. " int i, j, k;",
  494. "",
  495. " w = word = sv;",
  496. " while (*w++ == *u++) /* find first byte that differs */",
  497. " ;",
  498. " pfrst = (int) (u - lastword) - 1;",
  499. " memcpy(&lastword[pfrst], &sv[pfrst], dfa_depth-pfrst);",
  500. " if (pfrst > iv) pfrst = iv;",
  501. " if (pfrst > nv) pfrst = nv;",
  502. "/* phase1: */",
  503. " p = &path[pfrst]; q = (p+1); w = &word[pfrst];",
  504. " for (i = pfrst; i < dfa_depth; i++)",
  505. " *q++ = Delta(*p++, *w++); /* (*p)->delta[*w++]; */",
  506. "",
  507. " if (*p == F) return 1; /* it's already there */",
  508. "/* phase2: */",
  509. " iv = dfa_depth;",
  510. " do { iv--;",
  511. " old = new;",
  512. " new = find_it(path[iv], old, word[iv], iv);",
  513. " } while (new && iv > 0);",
  514. "",
  515. "/* phase3: */",
  516. " nv = k = 0; s = path[0];",
  517. " for (j = 1; j <= iv; ++j) ",
  518. " if (path[j]->num > 1)",
  519. " { y = new_vertex();",
  520. " copyEdges(y, path[j]);",
  521. " insert_it(y, j);",
  522. " numDelta(y, 1);",
  523. " delete_it(s, j-1);",
  524. " setDelta(s, word[j-1], y);",
  525. " insert_it(s, j-1);",
  526. " y->num = 1; /* initial value 1 */",
  527. " s = y;",
  528. " path[j]->num--; /* only 1 moved from j to y */",
  529. " k = 1;",
  530. " } else",
  531. " { s = path[j];",
  532. " if (!k) nv = j;",
  533. " }",
  534. " y = Delta(s, word[iv]);",
  535. " y->num--;",
  536. " delete_it(s, iv); ",
  537. " setDelta(s, word[iv], old);",
  538. " insert_it(s, iv); ",
  539. " old->num++;",
  540. "",
  541. " for (j = iv+1; j < dfa_depth; j++)",
  542. " if (path[j]->num == 0)",
  543. " { numDelta(path[j], -1);",
  544. " delete_it(path[j], j);",
  545. " recyc_vertex(path[j]);",
  546. " } else",
  547. " break;",
  548. " return 0;",
  549. "}",
  550. "",
  551. "static Vertex *",
  552. "splay(ulong i, Vertex *t)",
  553. "{ Vertex N, *l, *r, *y;",
  554. "",
  555. " if (!t) return t;",
  556. " N.left = N.right = (Vertex *) 0;",
  557. " l = r = &N;",
  558. " for (;;)",
  559. " { if (i < t->key)",
  560. " { if (!t->left) break;",
  561. " if (i < t->left->key)",
  562. " { y = t->left;",
  563. " t->left = y->right;",
  564. " y->right = t;",
  565. " t = y;",
  566. " if (!t->left) break;",
  567. " }",
  568. " r->left = t;",
  569. " r = t;",
  570. " t = t->left;",
  571. " } else if (i > t->key)",
  572. " { if (!t->right) break;",
  573. " if (i > t->right->key)",
  574. " { y = t->right;",
  575. " t->right = y->left;",
  576. " y->left = t;",
  577. " t = y;",
  578. " if (!t->right) break;",
  579. " }",
  580. " l->right = t;",
  581. " l = t;",
  582. " t = t->right;",
  583. " } else",
  584. " break;",
  585. " }",
  586. " l->right = t->left;",
  587. " r->left = t->right;",
  588. " t->left = N.right;",
  589. " t->right = N.left;",
  590. " return t;",
  591. "}",
  592. "",
  593. "static void",
  594. "insert_it(Vertex *v, int L)",
  595. "{ Vertex *new, *t;",
  596. " ulong i; int nr;",
  597. "",
  598. " i = mk_key(v);",
  599. " nr = ((L*TWIDTH)+Tally);",
  600. " t = layers[nr];",
  601. "",
  602. " v->key = i; ",
  603. " if (!t)",
  604. " { layers[nr] = v;",
  605. " return;",
  606. " }",
  607. " t = splay(i, t);",
  608. " if (i < t->key)",
  609. " { new = v;",
  610. " new->left = t->left;",
  611. " new->right = t;",
  612. " t->left = (Vertex *) 0;",
  613. " } else if (i > t->key)",
  614. " { new = v;",
  615. " new->right = t->right;",
  616. " new->left = t;",
  617. " t->right = (Vertex *) 0;",
  618. " } else /* it's already there */",
  619. " { v->lnk = t->lnk; /* put in linked list off v */",
  620. " t->lnk = v;",
  621. " new = t;",
  622. " }",
  623. " layers[nr] = new;",
  624. "}",
  625. "",
  626. "static int",
  627. "checkit(Vertex *h, Vertex *v, Vertex *n, uchar sigma)",
  628. "{ Edge *g, *f;",
  629. " int i, k, j = 1;",
  630. "",
  631. " for (k = 0; k < 2; k++)",
  632. " if (h->dst[k])",
  633. " { if (sigma >= h->from[k] && sigma <= h->to[k])",
  634. " { if (h->dst[k] != n) goto no_match;",
  635. " }",
  636. " for (i = h->from[k]; i <= h->to[k]; i++)",
  637. " { if (i == sigma) continue;",
  638. " g = cacheDelta(v, i, j); j = 0;",
  639. " if (h->dst[k] != g->Dst)",
  640. " goto no_match;",
  641. " if (g->s == 0 || g->S != i)",
  642. " i = g->To;",
  643. " } }",
  644. " for (f = h->Succ; f; f = f->Nxt)",
  645. " { if (INRANGE(f,sigma))",
  646. " { if (f->Dst != n) goto no_match;",
  647. " }",
  648. " for (i = f->From; i <= f->To; i++)",
  649. " { if (i == sigma) continue;",
  650. " g = cacheDelta(v, i, j); j = 0;",
  651. " if (f->Dst != g->Dst)",
  652. " goto no_match;",
  653. " if (g->s == 1 && i == g->S)",
  654. " continue;",
  655. " i = g->To;",
  656. " }",
  657. " if (f->s && f->S != sigma)",
  658. " { g = cacheDelta(v, f->S, 1);",
  659. " if (f->Dst != g->Dst)",
  660. " goto no_match;",
  661. " }",
  662. " }",
  663. " if (h->Succ || h->dst[0] || h->dst[1]) return 1;",
  664. "no_match:",
  665. " return 0;",
  666. "}",
  667. "",
  668. "static Vertex *",
  669. "find_it(Vertex *v, Vertex *n, uchar sigma, int L)",
  670. "{ Vertex *z, *t;",
  671. " ulong i; int nr;",
  672. "",
  673. " i = mk_special(sigma,n,v);",
  674. " nr = ((L*TWIDTH)+Tally);",
  675. " t = layers[nr];",
  676. "",
  677. " if (!t) return (Vertex *) 0;",
  678. " layers[nr] = t = splay(i, t);",
  679. " if (i == t->key)",
  680. " for (z = t; z; z = z->lnk)",
  681. " if (checkit(z, v, n, sigma))",
  682. " return z;",
  683. "",
  684. " return (Vertex *) 0;",
  685. "}",
  686. "",
  687. "static void",
  688. "delete_it(Vertex *v, int L)",
  689. "{ Vertex *x, *t;",
  690. " ulong i; int nr;",
  691. "",
  692. " i = cheap_key(v);",
  693. " nr = ((L*TWIDTH)+Tally);",
  694. " t = layers[nr];",
  695. " if (!t) return;",
  696. "",
  697. " t = splay(i, t);",
  698. " if (i == t->key)",
  699. " { Vertex *z, *y = (Vertex *) 0;",
  700. " for (z = t; z && z != v; y = z, z = z->lnk)",
  701. " ;",
  702. " if (z != v) goto bad;",
  703. " if (y)",
  704. " { y->lnk = z->lnk;",
  705. " z->lnk = (Vertex *) 0;",
  706. " layers[nr] = t;",
  707. " return;",
  708. " } else if (z->lnk) /* z == t == v */",
  709. " { y = z->lnk;",
  710. " y->left = t->left;",
  711. " y->right = t->right;",
  712. " t->left = t->right = t->lnk = (Vertex *) 0;",
  713. " layers[nr] = y;",
  714. " return;",
  715. " }",
  716. " /* delete the node itself */",
  717. " if (!t->left)",
  718. " { x = t->right;",
  719. " } else",
  720. " { x = splay(i, t->left);",
  721. " x->right = t->right;",
  722. " }",
  723. " t->left = t->right = t->lnk = (Vertex *) 0;",
  724. " layers[nr] = x;",
  725. " return;",
  726. " }",
  727. "bad: Uerror(\"cannot happen delete\");",
  728. "}",
  729. "#endif", /* MA */
  730. 0,
  731. };