17dd7cddfSDavid du Colombier /***** spin: pangen4.h *****/ 27dd7cddfSDavid du Colombier 3*de2caf28SDavid du Colombier /* 4*de2caf28SDavid du Colombier * This file is part of the public release of Spin. It is subject to the 5*de2caf28SDavid du Colombier * terms in the LICENSE file that is included in this source directory. 6*de2caf28SDavid du Colombier * Tool documentation is available at http://spinroot.com 7*de2caf28SDavid du Colombier * 8*de2caf28SDavid du Colombier * The DFA code below was written by Anuj Puri and Gerard J. Holzmann in 9*de2caf28SDavid du Colombier * May 1997, and was inspired by earlier work on data compression using 10*de2caf28SDavid du Colombier * sharing tree data structures and graph-encoded sets by J-Ch. Gregoire 11*de2caf28SDavid du Colombier * (INRS Telecom, Quebec, Canada) and D.Zampunieris (Univ.Namur, Belgium) 12*de2caf28SDavid du Colombier * The splay routine code included here is based on the public domain 13*de2caf28SDavid du Colombier * version written by D. Sleator <sleator@cs.cmu.edu> in 1992. 14*de2caf28SDavid du Colombier */ 157dd7cddfSDavid du Colombier 16*de2caf28SDavid du Colombier static const char *Dfa[] = { 177dd7cddfSDavid du Colombier "#ifdef MA", 18*de2caf28SDavid du Colombier #if 0 197dd7cddfSDavid du Colombier "/*", 207dd7cddfSDavid du Colombier "#include <stdio.h>", 217dd7cddfSDavid du Colombier "#define uchar unsigned char", 227dd7cddfSDavid du Colombier "*/", 237dd7cddfSDavid du Colombier "#define ulong unsigned long", 247dd7cddfSDavid du Colombier "#define ushort unsigned short", 257dd7cddfSDavid du Colombier "", 26*de2caf28SDavid du Colombier #endif 277dd7cddfSDavid du Colombier "#define TWIDTH 256", 28f3793cddSDavid du Colombier "#define HASH(y,n) (n)*(((long)y))", 297dd7cddfSDavid du Colombier "#define INRANGE(e,h) ((h>=e->From && h<=e->To)||(e->s==1 && e->S==h))", 307dd7cddfSDavid du Colombier "", 317dd7cddfSDavid du Colombier "extern char *emalloc(unsigned long); /* imported routine */", 327dd7cddfSDavid du Colombier "extern void dfa_init(ushort); /* 4 exported routines */", 33312a1df1SDavid du Colombier "extern int dfa_member(ulong);", 347dd7cddfSDavid du Colombier "extern int dfa_store(uchar *);", 357dd7cddfSDavid du Colombier "extern void dfa_stats(void);", 367dd7cddfSDavid du Colombier "", 377dd7cddfSDavid du Colombier "typedef struct Edge {", 387dd7cddfSDavid du Colombier " uchar From, To; /* max range 0..255 */", 397dd7cddfSDavid du Colombier " uchar s, S; /* if s=1, S is singleton */", 407dd7cddfSDavid du Colombier " struct Vertex *Dst;", 417dd7cddfSDavid du Colombier " struct Edge *Nxt;", 427dd7cddfSDavid du Colombier "} Edge;", 437dd7cddfSDavid du Colombier "", 447dd7cddfSDavid du Colombier "typedef struct Vertex {", 457dd7cddfSDavid du Colombier " ulong key, num; /* key for splay tree, nr incoming edges */", 467dd7cddfSDavid du Colombier " uchar from[2], to[2]; /* in-node predefined edge info */", 477dd7cddfSDavid du Colombier " struct Vertex *dst[2];/* most nodes have 2 or more edges */", 487dd7cddfSDavid du Colombier " struct Edge *Succ; /* in case there are more edges */", 497dd7cddfSDavid du Colombier " struct Vertex *lnk, *left, *right; /* splay tree plumbing */", 507dd7cddfSDavid du Colombier "} Vertex;", 517dd7cddfSDavid du Colombier "", 527dd7cddfSDavid du Colombier "static Edge *free_edges;", 537dd7cddfSDavid du Colombier "static Vertex *free_vertices;", 547dd7cddfSDavid du Colombier "static Vertex **layers; /* one splay tree of nodes per layer */", 557dd7cddfSDavid du Colombier "static Vertex **path; /* run of word in the DFA */", 567dd7cddfSDavid du Colombier "static Vertex *R, *F, *NF; /* Root, Final, Not-Final */", 577dd7cddfSDavid du Colombier "static uchar *word, *lastword;/* string, and last string inserted */", 587dd7cddfSDavid du Colombier "static int dfa_depth, iv=0, nv=0, pfrst=0, Tally;", 597dd7cddfSDavid du Colombier "", 607dd7cddfSDavid du Colombier "static void insert_it(Vertex *, int); /* splay-tree code */", 617dd7cddfSDavid du Colombier "static void delete_it(Vertex *, int);", 627dd7cddfSDavid du Colombier "static Vertex *find_it(Vertex *, Vertex *, uchar, int);", 637dd7cddfSDavid du Colombier "", 647dd7cddfSDavid du Colombier "static void", 657dd7cddfSDavid du Colombier "recyc_edges(Edge *e)", 667dd7cddfSDavid du Colombier "{", 677dd7cddfSDavid du Colombier " if (!e) return;", 687dd7cddfSDavid du Colombier " recyc_edges(e->Nxt);", 697dd7cddfSDavid du Colombier " e->Nxt = free_edges;", 707dd7cddfSDavid du Colombier " free_edges = e;", 717dd7cddfSDavid du Colombier "}", 727dd7cddfSDavid du Colombier "", 737dd7cddfSDavid du Colombier "static Edge *", 747dd7cddfSDavid du Colombier "new_edge(Vertex *dst)", 757dd7cddfSDavid du Colombier "{ Edge *e;", 767dd7cddfSDavid du Colombier "", 777dd7cddfSDavid du Colombier " if (free_edges)", 787dd7cddfSDavid du Colombier " { e = free_edges;", 797dd7cddfSDavid du Colombier " free_edges = e->Nxt;", 807dd7cddfSDavid du Colombier " e->From = e->To = e->s = e->S = 0;", 817dd7cddfSDavid du Colombier " e->Nxt = (Edge *) 0;", 827dd7cddfSDavid du Colombier " } else", 837dd7cddfSDavid du Colombier " e = (Edge *) emalloc(sizeof(Edge));", 847dd7cddfSDavid du Colombier " e->Dst = dst;", 857dd7cddfSDavid du Colombier "", 867dd7cddfSDavid du Colombier " return e;", 877dd7cddfSDavid du Colombier "}", 887dd7cddfSDavid du Colombier "", 897dd7cddfSDavid du Colombier "static void", 907dd7cddfSDavid du Colombier "recyc_vertex(Vertex *v)", 917dd7cddfSDavid du Colombier "{", 927dd7cddfSDavid du Colombier " recyc_edges(v->Succ);", 937dd7cddfSDavid du Colombier " v->Succ = (Edge *) free_vertices;", 947dd7cddfSDavid du Colombier " free_vertices = v;", 957dd7cddfSDavid du Colombier " nr_states--;", 967dd7cddfSDavid du Colombier "}", 977dd7cddfSDavid du Colombier "", 987dd7cddfSDavid du Colombier "static Vertex *", 997dd7cddfSDavid du Colombier "new_vertex(void)", 1007dd7cddfSDavid du Colombier "{ Vertex *v;", 1017dd7cddfSDavid du Colombier "", 1027dd7cddfSDavid du Colombier " if (free_vertices)", 1037dd7cddfSDavid du Colombier " { v = free_vertices;", 1047dd7cddfSDavid du Colombier " free_vertices = (Vertex *) v->Succ;", 1057dd7cddfSDavid du Colombier " v->Succ = (Edge *) 0;", 1067dd7cddfSDavid du Colombier " v->num = 0;", 1077dd7cddfSDavid du Colombier " } else", 1087dd7cddfSDavid du Colombier " v = (Vertex *) emalloc(sizeof(Vertex));", 1097dd7cddfSDavid du Colombier "", 1107dd7cddfSDavid du Colombier " nr_states++;", 1117dd7cddfSDavid du Colombier " return v; ", 1127dd7cddfSDavid du Colombier "}", 1137dd7cddfSDavid du Colombier "", 1147dd7cddfSDavid du Colombier "static Vertex *", 1157dd7cddfSDavid du Colombier "allDelta(Vertex *v, int n)", 1167dd7cddfSDavid du Colombier "{ Vertex *dst = new_vertex();", 1177dd7cddfSDavid du Colombier "", 1187dd7cddfSDavid du Colombier " v->from[0] = 0;", 1197dd7cddfSDavid du Colombier " v->to[0] = 255;", 1207dd7cddfSDavid du Colombier " v->dst[0] = dst;", 1217dd7cddfSDavid du Colombier " dst->num = 256;", 1227dd7cddfSDavid du Colombier " insert_it(v, n);", 1237dd7cddfSDavid du Colombier " return dst;", 1247dd7cddfSDavid du Colombier "}", 1257dd7cddfSDavid du Colombier "", 1267dd7cddfSDavid du Colombier "static void", 1277dd7cddfSDavid du Colombier "insert_edge(Vertex *v, Edge *e)", 1287dd7cddfSDavid du Colombier "{ /* put new edge first */", 1297dd7cddfSDavid du Colombier " if (!v->dst[0])", 1307dd7cddfSDavid du Colombier " { v->dst[0] = e->Dst;", 1317dd7cddfSDavid du Colombier " v->from[0] = e->From;", 1327dd7cddfSDavid du Colombier " v->to[0] = e->To;", 1337dd7cddfSDavid du Colombier " recyc_edges(e);", 1347dd7cddfSDavid du Colombier " return;", 1357dd7cddfSDavid du Colombier " }", 1367dd7cddfSDavid du Colombier " if (!v->dst[1])", 1377dd7cddfSDavid du Colombier " { v->from[1] = v->from[0]; v->from[0] = e->From;", 1387dd7cddfSDavid du Colombier " v->to[1] = v->to[0]; v->to[0] = e->To;", 1397dd7cddfSDavid du Colombier " v->dst[1] = v->dst[0]; v->dst[0] = e->Dst;", 1407dd7cddfSDavid du Colombier " recyc_edges(e);", 1417dd7cddfSDavid du Colombier " return;", 1427dd7cddfSDavid du Colombier " } /* shift */", 1437dd7cddfSDavid du Colombier " { int f = v->from[1];", 1447dd7cddfSDavid du Colombier " int t = v->to[1];", 1457dd7cddfSDavid du Colombier " Vertex *d = v->dst[1];", 1467dd7cddfSDavid du Colombier " v->from[1] = v->from[0]; v->from[0] = e->From;", 1477dd7cddfSDavid du Colombier " v->to[1] = v->to[0]; v->to[0] = e->To;", 1487dd7cddfSDavid du Colombier " v->dst[1] = v->dst[0]; v->dst[0] = e->Dst;", 1497dd7cddfSDavid du Colombier " e->From = f;", 1507dd7cddfSDavid du Colombier " e->To = t;", 1517dd7cddfSDavid du Colombier " e->Dst = d;", 1527dd7cddfSDavid du Colombier " }", 1537dd7cddfSDavid du Colombier " e->Nxt = v->Succ;", 1547dd7cddfSDavid du Colombier " v->Succ = e;", 1557dd7cddfSDavid du Colombier "}", 1567dd7cddfSDavid du Colombier "", 1577dd7cddfSDavid du Colombier "static void", 1587dd7cddfSDavid du Colombier "copyRecursive(Vertex *v, Edge *e)", 1597dd7cddfSDavid du Colombier "{ Edge *f;", 1607dd7cddfSDavid du Colombier " if (e->Nxt) copyRecursive(v, e->Nxt);", 1617dd7cddfSDavid du Colombier " f = new_edge(e->Dst);", 1627dd7cddfSDavid du Colombier " f->From = e->From;", 1637dd7cddfSDavid du Colombier " f->To = e->To;", 1647dd7cddfSDavid du Colombier " f->s = e->s;", 1657dd7cddfSDavid du Colombier " f->S = e->S;", 1667dd7cddfSDavid du Colombier " f->Nxt = v->Succ;", 1677dd7cddfSDavid du Colombier " v->Succ = f;", 1687dd7cddfSDavid du Colombier "}", 1697dd7cddfSDavid du Colombier "", 1707dd7cddfSDavid du Colombier "static void", 1717dd7cddfSDavid du Colombier "copyEdges(Vertex *to, Vertex *from)", 1727dd7cddfSDavid du Colombier "{ int i;", 1737dd7cddfSDavid du Colombier " for (i = 0; i < 2; i++)", 1747dd7cddfSDavid du Colombier " { to->from[i] = from->from[i];", 1757dd7cddfSDavid du Colombier " to->to[i] = from->to[i];", 1767dd7cddfSDavid du Colombier " to->dst[i] = from->dst[i];", 1777dd7cddfSDavid du Colombier " }", 1787dd7cddfSDavid du Colombier " if (from->Succ) copyRecursive(to, from->Succ);", 1797dd7cddfSDavid du Colombier "}", 1807dd7cddfSDavid du Colombier "", 1817dd7cddfSDavid du Colombier "static Edge *", 1827dd7cddfSDavid du Colombier "cacheDelta(Vertex *v, int h, int first)", 1837dd7cddfSDavid du Colombier "{ static Edge *ov, tmp; int i;", 1847dd7cddfSDavid du Colombier "", 1857dd7cddfSDavid du Colombier " if (!first && INRANGE(ov,h))", 1867dd7cddfSDavid du Colombier " return ov; /* intercepts about 10%% */", 1877dd7cddfSDavid du Colombier " for (i = 0; i < 2; i++)", 1887dd7cddfSDavid du Colombier " if (v->dst[i] && h >= v->from[i] && h <= v->to[i])", 1897dd7cddfSDavid du Colombier " { tmp.From = v->from[i];", 1907dd7cddfSDavid du Colombier " tmp.To = v->to[i];", 1917dd7cddfSDavid du Colombier " tmp.Dst = v->dst[i];", 1927dd7cddfSDavid du Colombier " tmp.s = tmp.S = 0;", 1937dd7cddfSDavid du Colombier " ov = &tmp;", 1947dd7cddfSDavid du Colombier " return ov;", 1957dd7cddfSDavid du Colombier " }", 1967dd7cddfSDavid du Colombier " for (ov = v->Succ; ov; ov = ov->Nxt)", 1977dd7cddfSDavid du Colombier " if (INRANGE(ov,h)) return ov;", 1987dd7cddfSDavid du Colombier "", 1997dd7cddfSDavid du Colombier " Uerror(\"cannot get here, cacheDelta\");", 2007dd7cddfSDavid du Colombier " return (Edge *) 0;", 2017dd7cddfSDavid du Colombier "}", 2027dd7cddfSDavid du Colombier "", 2037dd7cddfSDavid du Colombier "static Vertex *", 2047dd7cddfSDavid du Colombier "Delta(Vertex *v, int h) /* v->delta[h] */", 205312a1df1SDavid du Colombier "{ Edge *e;", 2067dd7cddfSDavid du Colombier "", 2077dd7cddfSDavid du Colombier " if (v->dst[0] && h >= v->from[0] && h <= v->to[0])", 2087dd7cddfSDavid du Colombier " return v->dst[0]; /* oldest edge */", 2097dd7cddfSDavid du Colombier " if (v->dst[1] && h >= v->from[1] && h <= v->to[1])", 2107dd7cddfSDavid du Colombier " return v->dst[1];", 2117dd7cddfSDavid du Colombier " for (e = v->Succ; e; e = e->Nxt)", 2127dd7cddfSDavid du Colombier " if (INRANGE(e,h))", 2137dd7cddfSDavid du Colombier " return e->Dst;", 2147dd7cddfSDavid du Colombier " Uerror(\"cannot happen Delta\");", 2157dd7cddfSDavid du Colombier " return (Vertex *) 0;", 2167dd7cddfSDavid du Colombier "}", 2177dd7cddfSDavid du Colombier "", 2187dd7cddfSDavid du Colombier "static void", 2197dd7cddfSDavid du Colombier "numDelta(Vertex *v, int d)", 220312a1df1SDavid du Colombier "{ Edge *e;", 221312a1df1SDavid du Colombier " ulong cnt;", 2227dd7cddfSDavid du Colombier " int i;", 2237dd7cddfSDavid du Colombier "", 2247dd7cddfSDavid du Colombier " for (i = 0; i < 2; i++)", 2257dd7cddfSDavid du Colombier " if (v->dst[i])", 2267dd7cddfSDavid du Colombier " { cnt = v->dst[i]->num + d*(1 + v->to[i] - v->from[i]);", 2277dd7cddfSDavid du Colombier " if (d == 1 && cnt < v->dst[i]->num) goto bad;", 2287dd7cddfSDavid du Colombier " v->dst[i]->num = cnt;", 2297dd7cddfSDavid du Colombier " }", 2307dd7cddfSDavid du Colombier " for (e = v->Succ; e; e = e->Nxt)", 2317dd7cddfSDavid du Colombier " { cnt = e->Dst->num + d*(1 + e->To - e->From + e->s);", 2327dd7cddfSDavid du Colombier " if (d == 1 && cnt < e->Dst->num)", 2337dd7cddfSDavid du Colombier "bad: Uerror(\"too many incoming edges\");", 2347dd7cddfSDavid du Colombier " e->Dst->num = cnt;", 2357dd7cddfSDavid du Colombier " }", 2367dd7cddfSDavid du Colombier "}", 2377dd7cddfSDavid du Colombier "", 2387dd7cddfSDavid du Colombier "static void", 2397dd7cddfSDavid du Colombier "setDelta(Vertex *v, int h, Vertex *newdst) /* v->delta[h] = newdst; */", 2407dd7cddfSDavid du Colombier "{ Edge *e, *f = (Edge *) 0, *g;", 2417dd7cddfSDavid du Colombier " int i;", 2427dd7cddfSDavid du Colombier "", 2437dd7cddfSDavid du Colombier " /* remove the old entry, if there */", 2447dd7cddfSDavid du Colombier " for (i = 0; i < 2; i++)", 2457dd7cddfSDavid du Colombier " if (v->dst[i] && h >= v->from[i] && h <= v->to[i])", 2467dd7cddfSDavid du Colombier " { if (h == v->from[i])", 2477dd7cddfSDavid du Colombier " { if (h == v->to[i])", 2487dd7cddfSDavid du Colombier " { v->dst[i] = (Vertex *) 0;", 2497dd7cddfSDavid du Colombier " v->from[i] = v->to[i] = 0;", 2507dd7cddfSDavid du Colombier " } else", 2517dd7cddfSDavid du Colombier " v->from[i]++;", 2527dd7cddfSDavid du Colombier " } else if (h == v->to[i])", 2537dd7cddfSDavid du Colombier " { v->to[i]--;", 2547dd7cddfSDavid du Colombier " } else", 2557dd7cddfSDavid du Colombier " { g = new_edge(v->dst[i]);/* same dst */", 2567dd7cddfSDavid du Colombier " g->From = v->from[i];", 2577dd7cddfSDavid du Colombier " g->To = h-1; /* left half */", 2587dd7cddfSDavid du Colombier " v->from[i] = h+1; /* right half */", 2597dd7cddfSDavid du Colombier " insert_edge(v, g);", 2607dd7cddfSDavid du Colombier " }", 2617dd7cddfSDavid du Colombier " goto part2;", 2627dd7cddfSDavid du Colombier " }", 2637dd7cddfSDavid du Colombier " for (e = v->Succ; e; f = e, e = e->Nxt)", 2647dd7cddfSDavid du Colombier " { if (e->s == 1 && e->S == h)", 2657dd7cddfSDavid du Colombier " { e->s = e->S = 0;", 2667dd7cddfSDavid du Colombier " goto rem_tst;", 2677dd7cddfSDavid du Colombier " }", 2687dd7cddfSDavid du Colombier " if (h >= e->From && h <= e->To)", 2697dd7cddfSDavid du Colombier " { if (h == e->From)", 2707dd7cddfSDavid du Colombier " { if (h == e->To)", 2717dd7cddfSDavid du Colombier " { if (e->s)", 2727dd7cddfSDavid du Colombier " { e->From = e->To = e->S;", 2737dd7cddfSDavid du Colombier " e->s = 0;", 2747dd7cddfSDavid du Colombier " break;", 2757dd7cddfSDavid du Colombier " } else", 2767dd7cddfSDavid du Colombier " goto rem_do;", 2777dd7cddfSDavid du Colombier " } else", 2787dd7cddfSDavid du Colombier " e->From++;", 2797dd7cddfSDavid du Colombier " } else if (h == e->To)", 2807dd7cddfSDavid du Colombier " { e->To--;", 2817dd7cddfSDavid du Colombier " } else /* split */", 2827dd7cddfSDavid du Colombier " { g = new_edge(e->Dst); /* same dst */", 2837dd7cddfSDavid du Colombier " g->From = e->From;", 2847dd7cddfSDavid du Colombier " g->To = h-1; /* g=left half */", 2857dd7cddfSDavid du Colombier " e->From = h+1; /* e=right half */", 2867dd7cddfSDavid du Colombier " g->Nxt = e->Nxt; /* insert g */", 2877dd7cddfSDavid du Colombier " e->Nxt = g; /* behind e */", 2887dd7cddfSDavid du Colombier " break; /* done */", 2897dd7cddfSDavid du Colombier " }", 2907dd7cddfSDavid du Colombier "", 2917dd7cddfSDavid du Colombier "rem_tst: if (e->From > e->To)", 2927dd7cddfSDavid du Colombier " { if (e->s == 0) {", 2937dd7cddfSDavid du Colombier "rem_do: if (f)", 2947dd7cddfSDavid du Colombier " f->Nxt = e->Nxt;", 2957dd7cddfSDavid du Colombier " else", 2967dd7cddfSDavid du Colombier " v->Succ = e->Nxt;", 2977dd7cddfSDavid du Colombier " e->Nxt = (Edge *) 0;", 2987dd7cddfSDavid du Colombier " recyc_edges(e);", 2997dd7cddfSDavid du Colombier " } else", 3007dd7cddfSDavid du Colombier " { e->From = e->To = e->S;", 3017dd7cddfSDavid du Colombier " e->s = 0;", 3027dd7cddfSDavid du Colombier " } }", 3037dd7cddfSDavid du Colombier " break;", 3047dd7cddfSDavid du Colombier " } }", 3057dd7cddfSDavid du Colombier "part2:", 3067dd7cddfSDavid du Colombier " /* check if newdst is already there */", 3077dd7cddfSDavid du Colombier " for (i = 0; i < 2; i++)", 3087dd7cddfSDavid du Colombier " if (v->dst[i] == newdst)", 3097dd7cddfSDavid du Colombier " { if (h+1 == (int) v->from[i])", 3107dd7cddfSDavid du Colombier " { v->from[i] = h;", 3117dd7cddfSDavid du Colombier " return;", 3127dd7cddfSDavid du Colombier " }", 3137dd7cddfSDavid du Colombier " if (h == (int) v->to[i]+1)", 3147dd7cddfSDavid du Colombier " { v->to[i] = h;", 3157dd7cddfSDavid du Colombier " return;", 3167dd7cddfSDavid du Colombier " } }", 3177dd7cddfSDavid du Colombier " for (e = v->Succ; e; e = e->Nxt)", 3187dd7cddfSDavid du Colombier " { if (e->Dst == newdst)", 3197dd7cddfSDavid du Colombier " { if (h+1 == (int) e->From)", 3207dd7cddfSDavid du Colombier " { e->From = h;", 3217dd7cddfSDavid du Colombier " if (e->s == 1 && e->S+1 == e->From)", 3227dd7cddfSDavid du Colombier " { e->From = e->S;", 3237dd7cddfSDavid du Colombier " e->s = e->S = 0;", 3247dd7cddfSDavid du Colombier " }", 3257dd7cddfSDavid du Colombier " return;", 3267dd7cddfSDavid du Colombier " }", 3277dd7cddfSDavid du Colombier " if (h == (int) e->To+1)", 3287dd7cddfSDavid du Colombier " { e->To = h;", 3297dd7cddfSDavid du Colombier " if (e->s == 1 && e->S == e->To+1)", 3307dd7cddfSDavid du Colombier " { e->To = e->S;", 3317dd7cddfSDavid du Colombier " e->s = e->S = 0;", 3327dd7cddfSDavid du Colombier " }", 3337dd7cddfSDavid du Colombier " return;", 3347dd7cddfSDavid du Colombier " }", 3357dd7cddfSDavid du Colombier " if (e->s == 0)", 3367dd7cddfSDavid du Colombier " { e->s = 1;", 3377dd7cddfSDavid du Colombier " e->S = h;", 3387dd7cddfSDavid du Colombier " return;", 3397dd7cddfSDavid du Colombier " } } }", 3407dd7cddfSDavid du Colombier " /* add as a new edge */", 3417dd7cddfSDavid du Colombier " e = new_edge(newdst);", 3427dd7cddfSDavid du Colombier " e->From = e->To = h;", 3437dd7cddfSDavid du Colombier " insert_edge(v, e);", 3447dd7cddfSDavid du Colombier "}", 3457dd7cddfSDavid du Colombier "", 3467dd7cddfSDavid du Colombier "static ulong", 3477dd7cddfSDavid du Colombier "cheap_key(Vertex *v)", 3487dd7cddfSDavid du Colombier "{ ulong vk2 = 0;", 3497dd7cddfSDavid du Colombier "", 3507dd7cddfSDavid du Colombier " if (v->dst[0])", 3517dd7cddfSDavid du Colombier " { vk2 = (ulong) v->dst[0];", 3527dd7cddfSDavid du Colombier " if ((ulong) v->dst[1] > vk2)", 3537dd7cddfSDavid du Colombier " vk2 = (ulong) v->dst[1];", 3547dd7cddfSDavid du Colombier " } else if (v->dst[1])", 3557dd7cddfSDavid du Colombier " vk2 = (ulong) v->dst[1]; ", 3567dd7cddfSDavid du Colombier " if (v->Succ)", 3577dd7cddfSDavid du Colombier " { Edge *e;", 3587dd7cddfSDavid du Colombier " for (e = v->Succ; e; e = e->Nxt)", 3597dd7cddfSDavid du Colombier " if ((ulong) e->Dst > vk2)", 3607dd7cddfSDavid du Colombier " vk2 = (ulong) e->Dst;", 3617dd7cddfSDavid du Colombier " }", 3627dd7cddfSDavid du Colombier " Tally = (vk2>>2)&(TWIDTH-1);", 3637dd7cddfSDavid du Colombier " return v->key;", 3647dd7cddfSDavid du Colombier "}", 3657dd7cddfSDavid du Colombier "", 3667dd7cddfSDavid du Colombier "static ulong", 3677dd7cddfSDavid du Colombier "mk_key(Vertex *v) /* not sensitive to order */", 368312a1df1SDavid du Colombier "{ ulong m = 0, vk2 = 0;", 369312a1df1SDavid du Colombier " Edge *e;", 3707dd7cddfSDavid du Colombier "", 3717dd7cddfSDavid du Colombier " if (v->dst[0])", 3727dd7cddfSDavid du Colombier " { m += HASH(v->dst[0], v->to[0] - v->from[0] + 1);", 3737dd7cddfSDavid du Colombier " vk2 = (ulong) v->dst[0]; ", 3747dd7cddfSDavid du Colombier " }", 3757dd7cddfSDavid du Colombier " if (v->dst[1])", 3767dd7cddfSDavid du Colombier " { m += HASH(v->dst[1], v->to[1] - v->from[1] + 1);", 3777dd7cddfSDavid du Colombier " if ((ulong) v->dst[1] > vk2) vk2 = (ulong) v->dst[1]; ", 3787dd7cddfSDavid du Colombier " }", 3797dd7cddfSDavid du Colombier " for (e = v->Succ; e; e = e->Nxt)", 3807dd7cddfSDavid du Colombier " { m += HASH(e->Dst, e->To - e->From + 1 + e->s);", 3817dd7cddfSDavid du Colombier " if ((ulong) e->Dst > vk2) vk2 = (ulong) e->Dst; ", 3827dd7cddfSDavid du Colombier " }", 3837dd7cddfSDavid du Colombier " Tally = (vk2>>2)&(TWIDTH-1);", 3847dd7cddfSDavid du Colombier " return m;", 3857dd7cddfSDavid du Colombier "}", 3867dd7cddfSDavid du Colombier "", 3877dd7cddfSDavid du Colombier "static ulong", 3887dd7cddfSDavid du Colombier "mk_special(int sigma, Vertex *n, Vertex *v)", 389312a1df1SDavid du Colombier "{ ulong m = 0, vk2 = 0;", 390312a1df1SDavid du Colombier " Edge *f;", 3917dd7cddfSDavid du Colombier " int i;", 3927dd7cddfSDavid du Colombier "", 3937dd7cddfSDavid du Colombier " for (i = 0; i < 2; i++)", 3947dd7cddfSDavid du Colombier " if (v->dst[i])", 3957dd7cddfSDavid du Colombier " { if (sigma >= v->from[i] && sigma <= v->to[i])", 3967dd7cddfSDavid du Colombier " { m += HASH(v->dst[i], v->to[i]-v->from[i]);", 3977dd7cddfSDavid du Colombier " if ((ulong) v->dst[i] > vk2", 3987dd7cddfSDavid du Colombier " && v->to[i] > v->from[i])", 3997dd7cddfSDavid du Colombier " vk2 = (ulong) v->dst[i]; ", 4007dd7cddfSDavid du Colombier " } else", 4017dd7cddfSDavid du Colombier " { m += HASH(v->dst[i], v->to[i]-v->from[i]+1);", 4027dd7cddfSDavid du Colombier " if ((ulong) v->dst[i] > vk2)", 4037dd7cddfSDavid du Colombier " vk2 = (ulong) v->dst[i]; ", 4047dd7cddfSDavid du Colombier " } }", 4057dd7cddfSDavid du Colombier " for (f = v->Succ; f; f = f->Nxt)", 4067dd7cddfSDavid du Colombier " { if (sigma >= f->From && sigma <= f->To)", 4077dd7cddfSDavid du Colombier " { m += HASH(f->Dst, f->To - f->From + f->s);", 4087dd7cddfSDavid du Colombier " if ((ulong) f->Dst > vk2", 4097dd7cddfSDavid du Colombier " && f->To - f->From + f->s > 0)", 4107dd7cddfSDavid du Colombier " vk2 = (ulong) f->Dst; ", 4117dd7cddfSDavid du Colombier " } else if (f->s == 1 && sigma == f->S)", 4127dd7cddfSDavid du Colombier " { m += HASH(f->Dst, f->To - f->From + 1);", 4137dd7cddfSDavid du Colombier " if ((ulong) f->Dst > vk2) vk2 = (ulong) f->Dst; ", 4147dd7cddfSDavid du Colombier " } else", 4157dd7cddfSDavid du Colombier " { m += HASH(f->Dst, f->To - f->From + 1 + f->s);", 4167dd7cddfSDavid du Colombier " if ((ulong) f->Dst > vk2) vk2 = (ulong) f->Dst; ", 4177dd7cddfSDavid du Colombier " } }", 4187dd7cddfSDavid du Colombier "", 4197dd7cddfSDavid du Colombier " if ((ulong) n > vk2) vk2 = (ulong) n; ", 4207dd7cddfSDavid du Colombier " Tally = (vk2>>2)&(TWIDTH-1);", 4217dd7cddfSDavid du Colombier " m += HASH(n, 1);", 4227dd7cddfSDavid du Colombier " return m;", 4237dd7cddfSDavid du Colombier "}", 4247dd7cddfSDavid du Colombier "", 4257dd7cddfSDavid du Colombier "void ", 4267dd7cddfSDavid du Colombier "dfa_init(ushort nr_layers)", 4277dd7cddfSDavid du Colombier "{ int i; Vertex *r, *t;", 4287dd7cddfSDavid du Colombier "", 4297dd7cddfSDavid du Colombier " dfa_depth = nr_layers; /* one byte per layer */", 4307dd7cddfSDavid du Colombier " path = (Vertex **) emalloc((dfa_depth+1)*sizeof(Vertex *));", 4317dd7cddfSDavid du Colombier " layers = (Vertex **) emalloc(TWIDTH*(dfa_depth+1)*sizeof(Vertex *));", 4327dd7cddfSDavid du Colombier " lastword = (uchar *) emalloc((dfa_depth+1)*sizeof(uchar));", 4337dd7cddfSDavid du Colombier " lastword[dfa_depth] = lastword[0] = 255;", 4347dd7cddfSDavid du Colombier " path[0] = R = new_vertex(); F = new_vertex();", 4357dd7cddfSDavid du Colombier "", 4367dd7cddfSDavid du Colombier " for (i = 1, r = R; i < dfa_depth; i++, r = t)", 4377dd7cddfSDavid du Colombier " t = allDelta(r, i-1);", 4387dd7cddfSDavid du Colombier " NF = allDelta(r, i-1);", 4397dd7cddfSDavid du Colombier "}", 4407dd7cddfSDavid du Colombier "", 4417dd7cddfSDavid du Colombier "#if 0", 4427dd7cddfSDavid du Colombier "static void complement_dfa(void) { Vertex *tmp = F; F = NF; NF = tmp; }", 4437dd7cddfSDavid du Colombier "#endif", 4447dd7cddfSDavid du Colombier "", 4457dd7cddfSDavid du Colombier "double", 4467dd7cddfSDavid du Colombier "tree_stats(Vertex *t)", 4477dd7cddfSDavid du Colombier "{ Edge *e; double cnt=0.0;", 4487dd7cddfSDavid du Colombier " if (!t) return 0;", 4497dd7cddfSDavid du Colombier " if (!t->key) return 0;", 4507dd7cddfSDavid du Colombier " t->key = 0; /* precaution */", 4517dd7cddfSDavid du Colombier " if (t->dst[0]) cnt++;", 4527dd7cddfSDavid du Colombier " if (t->dst[1]) cnt++;", 4537dd7cddfSDavid du Colombier " for (e = t->Succ; e; e = e->Nxt)", 4547dd7cddfSDavid du Colombier " cnt++;", 4557dd7cddfSDavid du Colombier " cnt += tree_stats(t->lnk);", 4567dd7cddfSDavid du Colombier " cnt += tree_stats(t->left);", 4577dd7cddfSDavid du Colombier " cnt += tree_stats(t->right);", 4587dd7cddfSDavid du Colombier " return cnt;", 4597dd7cddfSDavid du Colombier "}", 4607dd7cddfSDavid du Colombier "", 4617dd7cddfSDavid du Colombier "void", 4627dd7cddfSDavid du Colombier "dfa_stats(void)", 4637dd7cddfSDavid du Colombier "{ int i, j; double cnt = 0.0;", 4647dd7cddfSDavid du Colombier " for (j = 0; j < TWIDTH; j++)", 4657dd7cddfSDavid du Colombier " for (i = 0; i < dfa_depth+1; i++)", 4667dd7cddfSDavid du Colombier " cnt += tree_stats(layers[i*TWIDTH+j]);", 467*de2caf28SDavid du Colombier " printf(\"Minimized Automaton:\t%%6lu nodes and %%6g edges\\n\",", 4687dd7cddfSDavid du Colombier " nr_states, cnt);", 4697dd7cddfSDavid du Colombier "}", 4707dd7cddfSDavid du Colombier "", 4717dd7cddfSDavid du Colombier "int", 472312a1df1SDavid du Colombier "dfa_member(ulong n)", 4737dd7cddfSDavid du Colombier "{ Vertex **p, **q;", 4747dd7cddfSDavid du Colombier " uchar *w = &word[n];", 4757dd7cddfSDavid du Colombier " int i;", 4767dd7cddfSDavid du Colombier "", 4777dd7cddfSDavid du Colombier " p = &path[n]; q = (p+1);", 4787dd7cddfSDavid du Colombier " for (i = n; i < dfa_depth; i++)", 4797dd7cddfSDavid du Colombier " *q++ = Delta(*p++, *w++);", 4807dd7cddfSDavid du Colombier " return (*p == F);", 4817dd7cddfSDavid du Colombier "}", 4827dd7cddfSDavid du Colombier "", 4837dd7cddfSDavid du Colombier "int", 4847dd7cddfSDavid du Colombier "dfa_store(uchar *sv)", 4857dd7cddfSDavid du Colombier "{ Vertex **p, **q, *s, *y, *old, *new = F;", 4867dd7cddfSDavid du Colombier " uchar *w, *u = lastword;", 4877dd7cddfSDavid du Colombier " int i, j, k;", 4887dd7cddfSDavid du Colombier "", 4897dd7cddfSDavid du Colombier " w = word = sv;", 4907dd7cddfSDavid du Colombier " while (*w++ == *u++) /* find first byte that differs */", 4917dd7cddfSDavid du Colombier " ;", 4927dd7cddfSDavid du Colombier " pfrst = (int) (u - lastword) - 1;", 4937dd7cddfSDavid du Colombier " memcpy(&lastword[pfrst], &sv[pfrst], dfa_depth-pfrst);", 4947dd7cddfSDavid du Colombier " if (pfrst > iv) pfrst = iv;", 4957dd7cddfSDavid du Colombier " if (pfrst > nv) pfrst = nv;", 496312a1df1SDavid du Colombier "/* phase1: */", 4977dd7cddfSDavid du Colombier " p = &path[pfrst]; q = (p+1); w = &word[pfrst];", 4987dd7cddfSDavid du Colombier " for (i = pfrst; i < dfa_depth; i++)", 4997dd7cddfSDavid du Colombier " *q++ = Delta(*p++, *w++); /* (*p)->delta[*w++]; */", 5007dd7cddfSDavid du Colombier "", 5017dd7cddfSDavid du Colombier " if (*p == F) return 1; /* it's already there */", 502312a1df1SDavid du Colombier "/* phase2: */", 5037dd7cddfSDavid du Colombier " iv = dfa_depth;", 5047dd7cddfSDavid du Colombier " do { iv--;", 5057dd7cddfSDavid du Colombier " old = new;", 5067dd7cddfSDavid du Colombier " new = find_it(path[iv], old, word[iv], iv);", 5077dd7cddfSDavid du Colombier " } while (new && iv > 0);", 5087dd7cddfSDavid du Colombier "", 509312a1df1SDavid du Colombier "/* phase3: */", 5107dd7cddfSDavid du Colombier " nv = k = 0; s = path[0];", 5117dd7cddfSDavid du Colombier " for (j = 1; j <= iv; ++j) ", 5127dd7cddfSDavid du Colombier " if (path[j]->num > 1)", 5137dd7cddfSDavid du Colombier " { y = new_vertex();", 5147dd7cddfSDavid du Colombier " copyEdges(y, path[j]);", 5157dd7cddfSDavid du Colombier " insert_it(y, j);", 5167dd7cddfSDavid du Colombier " numDelta(y, 1);", 5177dd7cddfSDavid du Colombier " delete_it(s, j-1);", 5187dd7cddfSDavid du Colombier " setDelta(s, word[j-1], y);", 5197dd7cddfSDavid du Colombier " insert_it(s, j-1);", 5207dd7cddfSDavid du Colombier " y->num = 1; /* initial value 1 */", 5217dd7cddfSDavid du Colombier " s = y;", 5227dd7cddfSDavid du Colombier " path[j]->num--; /* only 1 moved from j to y */", 5237dd7cddfSDavid du Colombier " k = 1;", 5247dd7cddfSDavid du Colombier " } else", 5257dd7cddfSDavid du Colombier " { s = path[j];", 5267dd7cddfSDavid du Colombier " if (!k) nv = j;", 5277dd7cddfSDavid du Colombier " }", 5287dd7cddfSDavid du Colombier " y = Delta(s, word[iv]);", 5297dd7cddfSDavid du Colombier " y->num--;", 5307dd7cddfSDavid du Colombier " delete_it(s, iv); ", 5317dd7cddfSDavid du Colombier " setDelta(s, word[iv], old);", 5327dd7cddfSDavid du Colombier " insert_it(s, iv); ", 5337dd7cddfSDavid du Colombier " old->num++;", 5347dd7cddfSDavid du Colombier "", 5357dd7cddfSDavid du Colombier " for (j = iv+1; j < dfa_depth; j++)", 5367dd7cddfSDavid du Colombier " if (path[j]->num == 0)", 5377dd7cddfSDavid du Colombier " { numDelta(path[j], -1);", 5387dd7cddfSDavid du Colombier " delete_it(path[j], j);", 5397dd7cddfSDavid du Colombier " recyc_vertex(path[j]);", 5407dd7cddfSDavid du Colombier " } else", 5417dd7cddfSDavid du Colombier " break;", 5427dd7cddfSDavid du Colombier " return 0;", 5437dd7cddfSDavid du Colombier "}", 5447dd7cddfSDavid du Colombier "", 5457dd7cddfSDavid du Colombier "static Vertex *", 5467dd7cddfSDavid du Colombier "splay(ulong i, Vertex *t)", 5477dd7cddfSDavid du Colombier "{ Vertex N, *l, *r, *y;", 5487dd7cddfSDavid du Colombier "", 5497dd7cddfSDavid du Colombier " if (!t) return t;", 5507dd7cddfSDavid du Colombier " N.left = N.right = (Vertex *) 0;", 5517dd7cddfSDavid du Colombier " l = r = &N;", 5527dd7cddfSDavid du Colombier " for (;;)", 5537dd7cddfSDavid du Colombier " { if (i < t->key)", 5547dd7cddfSDavid du Colombier " { if (!t->left) break;", 5557dd7cddfSDavid du Colombier " if (i < t->left->key)", 5567dd7cddfSDavid du Colombier " { y = t->left;", 5577dd7cddfSDavid du Colombier " t->left = y->right;", 5587dd7cddfSDavid du Colombier " y->right = t;", 5597dd7cddfSDavid du Colombier " t = y;", 5607dd7cddfSDavid du Colombier " if (!t->left) break;", 5617dd7cddfSDavid du Colombier " }", 5627dd7cddfSDavid du Colombier " r->left = t;", 5637dd7cddfSDavid du Colombier " r = t;", 5647dd7cddfSDavid du Colombier " t = t->left;", 5657dd7cddfSDavid du Colombier " } else if (i > t->key)", 5667dd7cddfSDavid du Colombier " { if (!t->right) break;", 5677dd7cddfSDavid du Colombier " if (i > t->right->key)", 5687dd7cddfSDavid du Colombier " { y = t->right;", 5697dd7cddfSDavid du Colombier " t->right = y->left;", 5707dd7cddfSDavid du Colombier " y->left = t;", 5717dd7cddfSDavid du Colombier " t = y;", 5727dd7cddfSDavid du Colombier " if (!t->right) break;", 5737dd7cddfSDavid du Colombier " }", 5747dd7cddfSDavid du Colombier " l->right = t;", 5757dd7cddfSDavid du Colombier " l = t;", 5767dd7cddfSDavid du Colombier " t = t->right;", 5777dd7cddfSDavid du Colombier " } else", 5787dd7cddfSDavid du Colombier " break;", 5797dd7cddfSDavid du Colombier " }", 5807dd7cddfSDavid du Colombier " l->right = t->left;", 5817dd7cddfSDavid du Colombier " r->left = t->right;", 5827dd7cddfSDavid du Colombier " t->left = N.right;", 5837dd7cddfSDavid du Colombier " t->right = N.left;", 5847dd7cddfSDavid du Colombier " return t;", 5857dd7cddfSDavid du Colombier "}", 5867dd7cddfSDavid du Colombier "", 5877dd7cddfSDavid du Colombier "static void", 5887dd7cddfSDavid du Colombier "insert_it(Vertex *v, int L)", 5897dd7cddfSDavid du Colombier "{ Vertex *new, *t;", 5907dd7cddfSDavid du Colombier " ulong i; int nr;", 5917dd7cddfSDavid du Colombier "", 5927dd7cddfSDavid du Colombier " i = mk_key(v);", 5937dd7cddfSDavid du Colombier " nr = ((L*TWIDTH)+Tally);", 5947dd7cddfSDavid du Colombier " t = layers[nr];", 5957dd7cddfSDavid du Colombier "", 5967dd7cddfSDavid du Colombier " v->key = i; ", 5977dd7cddfSDavid du Colombier " if (!t)", 5987dd7cddfSDavid du Colombier " { layers[nr] = v;", 5997dd7cddfSDavid du Colombier " return;", 6007dd7cddfSDavid du Colombier " }", 6017dd7cddfSDavid du Colombier " t = splay(i, t);", 6027dd7cddfSDavid du Colombier " if (i < t->key)", 6037dd7cddfSDavid du Colombier " { new = v;", 6047dd7cddfSDavid du Colombier " new->left = t->left;", 6057dd7cddfSDavid du Colombier " new->right = t;", 6067dd7cddfSDavid du Colombier " t->left = (Vertex *) 0;", 6077dd7cddfSDavid du Colombier " } else if (i > t->key)", 6087dd7cddfSDavid du Colombier " { new = v;", 6097dd7cddfSDavid du Colombier " new->right = t->right;", 6107dd7cddfSDavid du Colombier " new->left = t;", 6117dd7cddfSDavid du Colombier " t->right = (Vertex *) 0;", 6127dd7cddfSDavid du Colombier " } else /* it's already there */", 6137dd7cddfSDavid du Colombier " { v->lnk = t->lnk; /* put in linked list off v */", 6147dd7cddfSDavid du Colombier " t->lnk = v;", 6157dd7cddfSDavid du Colombier " new = t;", 6167dd7cddfSDavid du Colombier " }", 6177dd7cddfSDavid du Colombier " layers[nr] = new;", 6187dd7cddfSDavid du Colombier "}", 6197dd7cddfSDavid du Colombier "", 6207dd7cddfSDavid du Colombier "static int", 6217dd7cddfSDavid du Colombier "checkit(Vertex *h, Vertex *v, Vertex *n, uchar sigma)", 6227dd7cddfSDavid du Colombier "{ Edge *g, *f;", 6237dd7cddfSDavid du Colombier " int i, k, j = 1;", 6247dd7cddfSDavid du Colombier "", 6257dd7cddfSDavid du Colombier " for (k = 0; k < 2; k++)", 6267dd7cddfSDavid du Colombier " if (h->dst[k])", 6277dd7cddfSDavid du Colombier " { if (sigma >= h->from[k] && sigma <= h->to[k])", 6287dd7cddfSDavid du Colombier " { if (h->dst[k] != n) goto no_match;", 6297dd7cddfSDavid du Colombier " }", 6307dd7cddfSDavid du Colombier " for (i = h->from[k]; i <= h->to[k]; i++)", 6317dd7cddfSDavid du Colombier " { if (i == sigma) continue;", 6327dd7cddfSDavid du Colombier " g = cacheDelta(v, i, j); j = 0;", 6337dd7cddfSDavid du Colombier " if (h->dst[k] != g->Dst)", 6347dd7cddfSDavid du Colombier " goto no_match;", 6357dd7cddfSDavid du Colombier " if (g->s == 0 || g->S != i)", 6367dd7cddfSDavid du Colombier " i = g->To;", 6377dd7cddfSDavid du Colombier " } }", 6387dd7cddfSDavid du Colombier " for (f = h->Succ; f; f = f->Nxt)", 6397dd7cddfSDavid du Colombier " { if (INRANGE(f,sigma))", 6407dd7cddfSDavid du Colombier " { if (f->Dst != n) goto no_match;", 6417dd7cddfSDavid du Colombier " }", 6427dd7cddfSDavid du Colombier " for (i = f->From; i <= f->To; i++)", 6437dd7cddfSDavid du Colombier " { if (i == sigma) continue;", 6447dd7cddfSDavid du Colombier " g = cacheDelta(v, i, j); j = 0;", 6457dd7cddfSDavid du Colombier " if (f->Dst != g->Dst)", 6467dd7cddfSDavid du Colombier " goto no_match;", 6477dd7cddfSDavid du Colombier " if (g->s == 1 && i == g->S)", 6487dd7cddfSDavid du Colombier " continue;", 6497dd7cddfSDavid du Colombier " i = g->To;", 6507dd7cddfSDavid du Colombier " }", 6517dd7cddfSDavid du Colombier " if (f->s && f->S != sigma)", 6527dd7cddfSDavid du Colombier " { g = cacheDelta(v, f->S, 1);", 6537dd7cddfSDavid du Colombier " if (f->Dst != g->Dst)", 6547dd7cddfSDavid du Colombier " goto no_match;", 6557dd7cddfSDavid du Colombier " }", 6567dd7cddfSDavid du Colombier " }", 6577dd7cddfSDavid du Colombier " if (h->Succ || h->dst[0] || h->dst[1]) return 1;", 6587dd7cddfSDavid du Colombier "no_match:", 6597dd7cddfSDavid du Colombier " return 0;", 6607dd7cddfSDavid du Colombier "}", 6617dd7cddfSDavid du Colombier "", 6627dd7cddfSDavid du Colombier "static Vertex *", 6637dd7cddfSDavid du Colombier "find_it(Vertex *v, Vertex *n, uchar sigma, int L)", 6647dd7cddfSDavid du Colombier "{ Vertex *z, *t;", 6657dd7cddfSDavid du Colombier " ulong i; int nr;", 6667dd7cddfSDavid du Colombier "", 6677dd7cddfSDavid du Colombier " i = mk_special(sigma,n,v);", 6687dd7cddfSDavid du Colombier " nr = ((L*TWIDTH)+Tally);", 6697dd7cddfSDavid du Colombier " t = layers[nr];", 6707dd7cddfSDavid du Colombier "", 6717dd7cddfSDavid du Colombier " if (!t) return (Vertex *) 0;", 6727dd7cddfSDavid du Colombier " layers[nr] = t = splay(i, t);", 6737dd7cddfSDavid du Colombier " if (i == t->key)", 6747dd7cddfSDavid du Colombier " for (z = t; z; z = z->lnk)", 6757dd7cddfSDavid du Colombier " if (checkit(z, v, n, sigma))", 6767dd7cddfSDavid du Colombier " return z;", 6777dd7cddfSDavid du Colombier "", 6787dd7cddfSDavid du Colombier " return (Vertex *) 0;", 6797dd7cddfSDavid du Colombier "}", 6807dd7cddfSDavid du Colombier "", 6817dd7cddfSDavid du Colombier "static void", 6827dd7cddfSDavid du Colombier "delete_it(Vertex *v, int L)", 6837dd7cddfSDavid du Colombier "{ Vertex *x, *t;", 6847dd7cddfSDavid du Colombier " ulong i; int nr;", 6857dd7cddfSDavid du Colombier "", 6867dd7cddfSDavid du Colombier " i = cheap_key(v);", 6877dd7cddfSDavid du Colombier " nr = ((L*TWIDTH)+Tally);", 6887dd7cddfSDavid du Colombier " t = layers[nr];", 6897dd7cddfSDavid du Colombier " if (!t) return;", 6907dd7cddfSDavid du Colombier "", 6917dd7cddfSDavid du Colombier " t = splay(i, t);", 6927dd7cddfSDavid du Colombier " if (i == t->key)", 6937dd7cddfSDavid du Colombier " { Vertex *z, *y = (Vertex *) 0;", 6947dd7cddfSDavid du Colombier " for (z = t; z && z != v; y = z, z = z->lnk)", 6957dd7cddfSDavid du Colombier " ;", 6967dd7cddfSDavid du Colombier " if (z != v) goto bad;", 6977dd7cddfSDavid du Colombier " if (y)", 6987dd7cddfSDavid du Colombier " { y->lnk = z->lnk;", 6997dd7cddfSDavid du Colombier " z->lnk = (Vertex *) 0;", 7007dd7cddfSDavid du Colombier " layers[nr] = t;", 7017dd7cddfSDavid du Colombier " return;", 7027dd7cddfSDavid du Colombier " } else if (z->lnk) /* z == t == v */", 7037dd7cddfSDavid du Colombier " { y = z->lnk;", 7047dd7cddfSDavid du Colombier " y->left = t->left;", 7057dd7cddfSDavid du Colombier " y->right = t->right;", 7067dd7cddfSDavid du Colombier " t->left = t->right = t->lnk = (Vertex *) 0;", 7077dd7cddfSDavid du Colombier " layers[nr] = y;", 7087dd7cddfSDavid du Colombier " return;", 7097dd7cddfSDavid du Colombier " }", 7107dd7cddfSDavid du Colombier " /* delete the node itself */", 7117dd7cddfSDavid du Colombier " if (!t->left)", 7127dd7cddfSDavid du Colombier " { x = t->right;", 7137dd7cddfSDavid du Colombier " } else", 7147dd7cddfSDavid du Colombier " { x = splay(i, t->left);", 7157dd7cddfSDavid du Colombier " x->right = t->right;", 7167dd7cddfSDavid du Colombier " }", 7177dd7cddfSDavid du Colombier " t->left = t->right = t->lnk = (Vertex *) 0;", 7187dd7cddfSDavid du Colombier " layers[nr] = x;", 7197dd7cddfSDavid du Colombier " return;", 7207dd7cddfSDavid du Colombier " }", 7217dd7cddfSDavid du Colombier "bad: Uerror(\"cannot happen delete\");", 7227dd7cddfSDavid du Colombier "}", 7237dd7cddfSDavid du Colombier "#endif", /* MA */ 7247dd7cddfSDavid du Colombier 0, 7257dd7cddfSDavid du Colombier }; 726