17dd7cddfSDavid du Colombier /***** tl_spin: tl_trans.c *****/
27dd7cddfSDavid du Colombier
3312a1df1SDavid du Colombier /* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */
47dd7cddfSDavid du Colombier /* All Rights Reserved. This software is for educational purposes only. */
5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6312a1df1SDavid du Colombier /* this code. Permission is given to distribute this code provided that */
7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged. */
8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann. For tool documentation see: */
9312a1df1SDavid du Colombier /* http://spinroot.com/ */
10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com */
11312a1df1SDavid du Colombier
127dd7cddfSDavid du Colombier /* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */
137dd7cddfSDavid du Colombier /* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier #include "tl.h"
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier extern FILE *tl_out;
18*00d97012SDavid du Colombier extern int tl_errs, tl_verbose, tl_terse, newstates, state_cnt;
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier int Stack_mx=0, Max_Red=0, Total=0;
217dd7cddfSDavid du Colombier
227dd7cddfSDavid du Colombier static Mapping *Mapped = (Mapping *) 0;
237dd7cddfSDavid du Colombier static Graph *Nodes_Set = (Graph *) 0;
247dd7cddfSDavid du Colombier static Graph *Nodes_Stack = (Graph *) 0;
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier static char dumpbuf[2048];
277dd7cddfSDavid du Colombier static int Red_cnt = 0;
287dd7cddfSDavid du Colombier static int Lab_cnt = 0;
297dd7cddfSDavid du Colombier static int Base = 0;
307dd7cddfSDavid du Colombier static int Stack_sz = 0;
317dd7cddfSDavid du Colombier
327dd7cddfSDavid du Colombier static Graph *findgraph(char *);
337dd7cddfSDavid du Colombier static Graph *pop_stack(void);
347dd7cddfSDavid du Colombier static Node *Duplicate(Node *);
357dd7cddfSDavid du Colombier static Node *flatten(Node *);
367dd7cddfSDavid du Colombier static Symbol *catSlist(Symbol *, Symbol *);
377dd7cddfSDavid du Colombier static Symbol *dupSlist(Symbol *);
387dd7cddfSDavid du Colombier static char *newname(void);
397dd7cddfSDavid du Colombier static int choueka(Graph *, int);
407dd7cddfSDavid du Colombier static int not_new(Graph *);
417dd7cddfSDavid du Colombier static int set_prefix(char *, int, Graph *);
427dd7cddfSDavid du Colombier static void Addout(char *, char *);
437dd7cddfSDavid du Colombier static void fsm_trans(Graph *, int, char *);
447dd7cddfSDavid du Colombier static void mkbuchi(void);
45312a1df1SDavid du Colombier static void expand_g(Graph *);
467dd7cddfSDavid du Colombier static void fixinit(Node *);
477dd7cddfSDavid du Colombier static void liveness(Node *);
487dd7cddfSDavid du Colombier static void mk_grn(Node *);
497dd7cddfSDavid du Colombier static void mk_red(Node *);
507dd7cddfSDavid du Colombier static void ng(Symbol *, Symbol *, Node *, Node *, Node *);
517dd7cddfSDavid du Colombier static void push_stack(Graph *);
527dd7cddfSDavid du Colombier static void sdump(Node *);
537dd7cddfSDavid du Colombier
54*00d97012SDavid du Colombier void
ini_trans(void)55*00d97012SDavid du Colombier ini_trans(void)
56*00d97012SDavid du Colombier {
57*00d97012SDavid du Colombier Stack_mx = 0;
58*00d97012SDavid du Colombier Max_Red = 0;
59*00d97012SDavid du Colombier Total = 0;
60*00d97012SDavid du Colombier
61*00d97012SDavid du Colombier Mapped = (Mapping *) 0;
62*00d97012SDavid du Colombier Nodes_Set = (Graph *) 0;
63*00d97012SDavid du Colombier Nodes_Stack = (Graph *) 0;
64*00d97012SDavid du Colombier
65*00d97012SDavid du Colombier memset(dumpbuf, 0, sizeof(dumpbuf));
66*00d97012SDavid du Colombier Red_cnt = 0;
67*00d97012SDavid du Colombier Lab_cnt = 0;
68*00d97012SDavid du Colombier Base = 0;
69*00d97012SDavid du Colombier Stack_sz = 0;
70*00d97012SDavid du Colombier }
71*00d97012SDavid du Colombier
727dd7cddfSDavid du Colombier static void
dump_graph(Graph * g)737dd7cddfSDavid du Colombier dump_graph(Graph *g)
747dd7cddfSDavid du Colombier { Node *n1;
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier printf("\n\tnew:\t");
777dd7cddfSDavid du Colombier for (n1 = g->New; n1; n1 = n1->nxt)
787dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
797dd7cddfSDavid du Colombier printf("\n\told:\t");
807dd7cddfSDavid du Colombier for (n1 = g->Old; n1; n1 = n1->nxt)
817dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
827dd7cddfSDavid du Colombier printf("\n\tnxt:\t");
837dd7cddfSDavid du Colombier for (n1 = g->Next; n1; n1 = n1->nxt)
847dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
857dd7cddfSDavid du Colombier printf("\n\tother:\t");
867dd7cddfSDavid du Colombier for (n1 = g->Other; n1; n1 = n1->nxt)
877dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
887dd7cddfSDavid du Colombier printf("\n");
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier static void
push_stack(Graph * g)927dd7cddfSDavid du Colombier push_stack(Graph *g)
937dd7cddfSDavid du Colombier {
947dd7cddfSDavid du Colombier if (!g) return;
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier g->nxt = Nodes_Stack;
977dd7cddfSDavid du Colombier Nodes_Stack = g;
987dd7cddfSDavid du Colombier if (tl_verbose)
997dd7cddfSDavid du Colombier { Symbol *z;
1007dd7cddfSDavid du Colombier printf("\nPush %s, from ", g->name->name);
1017dd7cddfSDavid du Colombier for (z = g->incoming; z; z = z->next)
1027dd7cddfSDavid du Colombier printf("%s, ", z->name);
1037dd7cddfSDavid du Colombier dump_graph(g);
1047dd7cddfSDavid du Colombier }
1057dd7cddfSDavid du Colombier Stack_sz++;
1067dd7cddfSDavid du Colombier if (Stack_sz > Stack_mx) Stack_mx = Stack_sz;
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier static Graph *
pop_stack(void)1107dd7cddfSDavid du Colombier pop_stack(void)
1117dd7cddfSDavid du Colombier { Graph *g = Nodes_Stack;
1127dd7cddfSDavid du Colombier
1137dd7cddfSDavid du Colombier if (g) Nodes_Stack = g->nxt;
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier Stack_sz--;
1167dd7cddfSDavid du Colombier
1177dd7cddfSDavid du Colombier return g;
1187dd7cddfSDavid du Colombier }
1197dd7cddfSDavid du Colombier
1207dd7cddfSDavid du Colombier static char *
newname(void)1217dd7cddfSDavid du Colombier newname(void)
122*00d97012SDavid du Colombier { static char buf[32];
123*00d97012SDavid du Colombier sprintf(buf, "S%d", state_cnt++);
1247dd7cddfSDavid du Colombier return buf;
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier static int
has_clause(int tok,Graph * p,Node * n)1287dd7cddfSDavid du Colombier has_clause(int tok, Graph *p, Node *n)
1297dd7cddfSDavid du Colombier { Node *q, *qq;
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier switch (n->ntyp) {
1327dd7cddfSDavid du Colombier case AND:
1337dd7cddfSDavid du Colombier return has_clause(tok, p, n->lft) &&
1347dd7cddfSDavid du Colombier has_clause(tok, p, n->rgt);
1357dd7cddfSDavid du Colombier case OR:
1367dd7cddfSDavid du Colombier return has_clause(tok, p, n->lft) ||
1377dd7cddfSDavid du Colombier has_clause(tok, p, n->rgt);
1387dd7cddfSDavid du Colombier }
1397dd7cddfSDavid du Colombier
1407dd7cddfSDavid du Colombier for (q = p->Other; q; q = q->nxt)
1417dd7cddfSDavid du Colombier { qq = right_linked(q);
1427dd7cddfSDavid du Colombier if (anywhere(tok, n, qq))
1437dd7cddfSDavid du Colombier return 1;
1447dd7cddfSDavid du Colombier }
1457dd7cddfSDavid du Colombier return 0;
1467dd7cddfSDavid du Colombier }
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier static void
mk_grn(Node * n)1497dd7cddfSDavid du Colombier mk_grn(Node *n)
1507dd7cddfSDavid du Colombier { Graph *p;
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier n = right_linked(n);
153312a1df1SDavid du Colombier more:
1547dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
1557dd7cddfSDavid du Colombier if (p->outgoing
1567dd7cddfSDavid du Colombier && has_clause(AND, p, n))
1577dd7cddfSDavid du Colombier { p->isgrn[p->grncnt++] =
1587dd7cddfSDavid du Colombier (unsigned char) Red_cnt;
1597dd7cddfSDavid du Colombier Lab_cnt++;
1607dd7cddfSDavid du Colombier }
161312a1df1SDavid du Colombier
162312a1df1SDavid du Colombier if (n->ntyp == U_OPER) /* 3.4.0 */
163312a1df1SDavid du Colombier { n = n->rgt;
164312a1df1SDavid du Colombier goto more;
165312a1df1SDavid du Colombier }
1667dd7cddfSDavid du Colombier }
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier static void
mk_red(Node * n)1697dd7cddfSDavid du Colombier mk_red(Node *n)
1707dd7cddfSDavid du Colombier { Graph *p;
1717dd7cddfSDavid du Colombier
1727dd7cddfSDavid du Colombier n = right_linked(n);
1737dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
1747dd7cddfSDavid du Colombier { if (p->outgoing
1757dd7cddfSDavid du Colombier && has_clause(0, p, n))
1767dd7cddfSDavid du Colombier { if (p->redcnt >= 63)
1777dd7cddfSDavid du Colombier Fatal("too many Untils", (char *)0);
1787dd7cddfSDavid du Colombier p->isred[p->redcnt++] =
1797dd7cddfSDavid du Colombier (unsigned char) Red_cnt;
1807dd7cddfSDavid du Colombier Lab_cnt++; Max_Red = Red_cnt;
1817dd7cddfSDavid du Colombier } }
1827dd7cddfSDavid du Colombier }
1837dd7cddfSDavid du Colombier
1847dd7cddfSDavid du Colombier static void
liveness(Node * n)1857dd7cddfSDavid du Colombier liveness(Node *n)
1867dd7cddfSDavid du Colombier {
1877dd7cddfSDavid du Colombier if (n)
1887dd7cddfSDavid du Colombier switch (n->ntyp) {
1897dd7cddfSDavid du Colombier #ifdef NXT
1907dd7cddfSDavid du Colombier case NEXT:
1917dd7cddfSDavid du Colombier liveness(n->lft);
1927dd7cddfSDavid du Colombier break;
1937dd7cddfSDavid du Colombier #endif
1947dd7cddfSDavid du Colombier case U_OPER:
1957dd7cddfSDavid du Colombier Red_cnt++;
1967dd7cddfSDavid du Colombier mk_red(n);
1977dd7cddfSDavid du Colombier mk_grn(n->rgt);
1987dd7cddfSDavid du Colombier /* fall through */
1997dd7cddfSDavid du Colombier case V_OPER:
2007dd7cddfSDavid du Colombier case OR: case AND:
2017dd7cddfSDavid du Colombier liveness(n->lft);
2027dd7cddfSDavid du Colombier liveness(n->rgt);
2037dd7cddfSDavid du Colombier break;
2047dd7cddfSDavid du Colombier }
2057dd7cddfSDavid du Colombier }
2067dd7cddfSDavid du Colombier
2077dd7cddfSDavid du Colombier static Graph *
findgraph(char * nm)2087dd7cddfSDavid du Colombier findgraph(char *nm)
2097dd7cddfSDavid du Colombier { Graph *p;
2107dd7cddfSDavid du Colombier Mapping *m;
2117dd7cddfSDavid du Colombier
2127dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
2137dd7cddfSDavid du Colombier if (!strcmp(p->name->name, nm))
2147dd7cddfSDavid du Colombier return p;
2157dd7cddfSDavid du Colombier for (m = Mapped; m; m = m->nxt)
2167dd7cddfSDavid du Colombier if (strcmp(m->from, nm) == 0)
2177dd7cddfSDavid du Colombier return m->to;
2187dd7cddfSDavid du Colombier
2197dd7cddfSDavid du Colombier printf("warning: node %s not found\n", nm);
2207dd7cddfSDavid du Colombier return (Graph *) 0;
2217dd7cddfSDavid du Colombier }
2227dd7cddfSDavid du Colombier
2237dd7cddfSDavid du Colombier static void
Addout(char * to,char * from)2247dd7cddfSDavid du Colombier Addout(char *to, char *from)
2257dd7cddfSDavid du Colombier { Graph *p = findgraph(from);
2267dd7cddfSDavid du Colombier Symbol *s;
2277dd7cddfSDavid du Colombier
2287dd7cddfSDavid du Colombier if (!p) return;
2297dd7cddfSDavid du Colombier s = getsym(tl_lookup(to));
2307dd7cddfSDavid du Colombier s->next = p->outgoing;
2317dd7cddfSDavid du Colombier p->outgoing = s;
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier
2347dd7cddfSDavid du Colombier #ifdef NXT
2357dd7cddfSDavid du Colombier int
only_nxt(Node * n)2367dd7cddfSDavid du Colombier only_nxt(Node *n)
2377dd7cddfSDavid du Colombier {
2387dd7cddfSDavid du Colombier switch (n->ntyp) {
2397dd7cddfSDavid du Colombier case NEXT:
2407dd7cddfSDavid du Colombier return 1;
2417dd7cddfSDavid du Colombier case OR:
2427dd7cddfSDavid du Colombier case AND:
2437dd7cddfSDavid du Colombier return only_nxt(n->rgt) && only_nxt(n->lft);
2447dd7cddfSDavid du Colombier default:
2457dd7cddfSDavid du Colombier return 0;
2467dd7cddfSDavid du Colombier }
2477dd7cddfSDavid du Colombier }
2487dd7cddfSDavid du Colombier #endif
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier int
dump_cond(Node * pp,Node * r,int first)2517dd7cddfSDavid du Colombier dump_cond(Node *pp, Node *r, int first)
2527dd7cddfSDavid du Colombier { Node *q;
2537dd7cddfSDavid du Colombier int frst = first;
2547dd7cddfSDavid du Colombier
2557dd7cddfSDavid du Colombier if (!pp) return frst;
2567dd7cddfSDavid du Colombier
2577dd7cddfSDavid du Colombier q = dupnode(pp);
2587dd7cddfSDavid du Colombier q = rewrite(q);
2597dd7cddfSDavid du Colombier
2607dd7cddfSDavid du Colombier if (q->ntyp == PREDICATE
2617dd7cddfSDavid du Colombier || q->ntyp == NOT
2627dd7cddfSDavid du Colombier #ifndef NXT
2637dd7cddfSDavid du Colombier || q->ntyp == OR
2647dd7cddfSDavid du Colombier #endif
2657dd7cddfSDavid du Colombier || q->ntyp == FALSE)
2667dd7cddfSDavid du Colombier { if (!frst) fprintf(tl_out, " && ");
2677dd7cddfSDavid du Colombier dump(q);
2687dd7cddfSDavid du Colombier frst = 0;
2697dd7cddfSDavid du Colombier #ifdef NXT
2707dd7cddfSDavid du Colombier } else if (q->ntyp == OR)
2717dd7cddfSDavid du Colombier { if (!frst) fprintf(tl_out, " && ");
2727dd7cddfSDavid du Colombier fprintf(tl_out, "((");
2737dd7cddfSDavid du Colombier frst = dump_cond(q->lft, r, 1);
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier if (!frst)
2767dd7cddfSDavid du Colombier fprintf(tl_out, ") || (");
2777dd7cddfSDavid du Colombier else
2787dd7cddfSDavid du Colombier { if (only_nxt(q->lft))
2797dd7cddfSDavid du Colombier { fprintf(tl_out, "1))");
2807dd7cddfSDavid du Colombier return 0;
2817dd7cddfSDavid du Colombier }
2827dd7cddfSDavid du Colombier }
2837dd7cddfSDavid du Colombier
2847dd7cddfSDavid du Colombier frst = dump_cond(q->rgt, r, 1);
2857dd7cddfSDavid du Colombier
2867dd7cddfSDavid du Colombier if (frst)
2877dd7cddfSDavid du Colombier { if (only_nxt(q->rgt))
2887dd7cddfSDavid du Colombier fprintf(tl_out, "1");
2897dd7cddfSDavid du Colombier else
2907dd7cddfSDavid du Colombier fprintf(tl_out, "0");
2917dd7cddfSDavid du Colombier frst = 0;
2927dd7cddfSDavid du Colombier }
2937dd7cddfSDavid du Colombier
2947dd7cddfSDavid du Colombier fprintf(tl_out, "))");
2957dd7cddfSDavid du Colombier #endif
2967dd7cddfSDavid du Colombier } else if (q->ntyp == V_OPER
2977dd7cddfSDavid du Colombier && !anywhere(AND, q->rgt, r))
2987dd7cddfSDavid du Colombier { frst = dump_cond(q->rgt, r, frst);
2997dd7cddfSDavid du Colombier } else if (q->ntyp == AND)
3007dd7cddfSDavid du Colombier {
3017dd7cddfSDavid du Colombier frst = dump_cond(q->lft, r, frst);
3027dd7cddfSDavid du Colombier frst = dump_cond(q->rgt, r, frst);
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier
3057dd7cddfSDavid du Colombier return frst;
3067dd7cddfSDavid du Colombier }
3077dd7cddfSDavid du Colombier
3087dd7cddfSDavid du Colombier static int
choueka(Graph * p,int count)3097dd7cddfSDavid du Colombier choueka(Graph *p, int count)
3107dd7cddfSDavid du Colombier { int j, k, incr_cnt = 0;
3117dd7cddfSDavid du Colombier
3127dd7cddfSDavid du Colombier for (j = count; j <= Max_Red; j++) /* for each acceptance class */
3137dd7cddfSDavid du Colombier { int delta = 0;
3147dd7cddfSDavid du Colombier
3157dd7cddfSDavid du Colombier /* is state p labeled Grn-j OR not Red-j ? */
3167dd7cddfSDavid du Colombier
3177dd7cddfSDavid du Colombier for (k = 0; k < (int) p->grncnt; k++)
3187dd7cddfSDavid du Colombier if (p->isgrn[k] == j)
3197dd7cddfSDavid du Colombier { delta = 1;
3207dd7cddfSDavid du Colombier break;
3217dd7cddfSDavid du Colombier }
3227dd7cddfSDavid du Colombier if (delta)
3237dd7cddfSDavid du Colombier { incr_cnt++;
3247dd7cddfSDavid du Colombier continue;
3257dd7cddfSDavid du Colombier }
3267dd7cddfSDavid du Colombier for (k = 0; k < (int) p->redcnt; k++)
3277dd7cddfSDavid du Colombier if (p->isred[k] == j)
3287dd7cddfSDavid du Colombier { delta = 1;
3297dd7cddfSDavid du Colombier break;
3307dd7cddfSDavid du Colombier }
3317dd7cddfSDavid du Colombier
3327dd7cddfSDavid du Colombier if (delta) break;
3337dd7cddfSDavid du Colombier
3347dd7cddfSDavid du Colombier incr_cnt++;
3357dd7cddfSDavid du Colombier }
3367dd7cddfSDavid du Colombier return incr_cnt;
3377dd7cddfSDavid du Colombier }
3387dd7cddfSDavid du Colombier
3397dd7cddfSDavid du Colombier static int
set_prefix(char * pref,int count,Graph * r2)3407dd7cddfSDavid du Colombier set_prefix(char *pref, int count, Graph *r2)
3417dd7cddfSDavid du Colombier { int incr_cnt = 0; /* acceptance class 'count' */
3427dd7cddfSDavid du Colombier
3437dd7cddfSDavid du Colombier if (Lab_cnt == 0
3447dd7cddfSDavid du Colombier || Max_Red == 0)
3457dd7cddfSDavid du Colombier sprintf(pref, "accept"); /* new */
3467dd7cddfSDavid du Colombier else if (count >= Max_Red)
3477dd7cddfSDavid du Colombier sprintf(pref, "T0"); /* cycle */
3487dd7cddfSDavid du Colombier else
3497dd7cddfSDavid du Colombier { incr_cnt = choueka(r2, count+1);
3507dd7cddfSDavid du Colombier if (incr_cnt + count >= Max_Red)
3517dd7cddfSDavid du Colombier sprintf(pref, "accept"); /* last hop */
3527dd7cddfSDavid du Colombier else
3537dd7cddfSDavid du Colombier sprintf(pref, "T%d", count+incr_cnt);
3547dd7cddfSDavid du Colombier }
3557dd7cddfSDavid du Colombier return incr_cnt;
3567dd7cddfSDavid du Colombier }
3577dd7cddfSDavid du Colombier
3587dd7cddfSDavid du Colombier static void
fsm_trans(Graph * p,int count,char * curnm)3597dd7cddfSDavid du Colombier fsm_trans(Graph *p, int count, char *curnm)
3607dd7cddfSDavid du Colombier { Graph *r;
3617dd7cddfSDavid du Colombier Symbol *s;
362*00d97012SDavid du Colombier char prefix[128], nwnm[256];
3637dd7cddfSDavid du Colombier
3647dd7cddfSDavid du Colombier if (!p->outgoing)
3657dd7cddfSDavid du Colombier addtrans(p, curnm, False, "accept_all");
3667dd7cddfSDavid du Colombier
3677dd7cddfSDavid du Colombier for (s = p->outgoing; s; s = s->next)
3687dd7cddfSDavid du Colombier { r = findgraph(s->name);
3697dd7cddfSDavid du Colombier if (!r) continue;
3707dd7cddfSDavid du Colombier if (r->outgoing)
3717dd7cddfSDavid du Colombier { (void) set_prefix(prefix, count, r);
3727dd7cddfSDavid du Colombier sprintf(nwnm, "%s_%s", prefix, s->name);
3737dd7cddfSDavid du Colombier } else
3747dd7cddfSDavid du Colombier strcpy(nwnm, "accept_all");
375312a1df1SDavid du Colombier
376312a1df1SDavid du Colombier if (tl_verbose)
377312a1df1SDavid du Colombier { printf("maxred=%d, count=%d, curnm=%s, nwnm=%s ",
378312a1df1SDavid du Colombier Max_Red, count, curnm, nwnm);
379312a1df1SDavid du Colombier printf("(greencnt=%d,%d, redcnt=%d,%d)\n",
380312a1df1SDavid du Colombier r->grncnt, r->isgrn[0],
381312a1df1SDavid du Colombier r->redcnt, r->isred[0]);
382312a1df1SDavid du Colombier }
3837dd7cddfSDavid du Colombier addtrans(p, curnm, r->Old, nwnm);
3847dd7cddfSDavid du Colombier }
3857dd7cddfSDavid du Colombier }
3867dd7cddfSDavid du Colombier
3877dd7cddfSDavid du Colombier static void
mkbuchi(void)3887dd7cddfSDavid du Colombier mkbuchi(void)
3897dd7cddfSDavid du Colombier { Graph *p;
3907dd7cddfSDavid du Colombier int k;
3917dd7cddfSDavid du Colombier char curnm[64];
3927dd7cddfSDavid du Colombier
3937dd7cddfSDavid du Colombier for (k = 0; k <= Max_Red; k++)
3947dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
3957dd7cddfSDavid du Colombier { if (!p->outgoing)
3967dd7cddfSDavid du Colombier continue;
3977dd7cddfSDavid du Colombier if (k != 0
3987dd7cddfSDavid du Colombier && !strcmp(p->name->name, "init")
3997dd7cddfSDavid du Colombier && Max_Red != 0)
4007dd7cddfSDavid du Colombier continue;
4017dd7cddfSDavid du Colombier
4027dd7cddfSDavid du Colombier if (k == Max_Red
4037dd7cddfSDavid du Colombier && strcmp(p->name->name, "init") != 0)
4047dd7cddfSDavid du Colombier strcpy(curnm, "accept_");
4057dd7cddfSDavid du Colombier else
4067dd7cddfSDavid du Colombier sprintf(curnm, "T%d_", k);
4077dd7cddfSDavid du Colombier
4087dd7cddfSDavid du Colombier strcat(curnm, p->name->name);
4097dd7cddfSDavid du Colombier
4107dd7cddfSDavid du Colombier fsm_trans(p, k, curnm);
4117dd7cddfSDavid du Colombier }
4127dd7cddfSDavid du Colombier fsm_print();
4137dd7cddfSDavid du Colombier }
4147dd7cddfSDavid du Colombier
4157dd7cddfSDavid du Colombier static Symbol *
dupSlist(Symbol * s)4167dd7cddfSDavid du Colombier dupSlist(Symbol *s)
4177dd7cddfSDavid du Colombier { Symbol *p1, *p2, *p3, *d = ZS;
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier for (p1 = s; p1; p1 = p1->next)
4207dd7cddfSDavid du Colombier { for (p3 = d; p3; p3 = p3->next)
4217dd7cddfSDavid du Colombier { if (!strcmp(p3->name, p1->name))
4227dd7cddfSDavid du Colombier break;
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier if (p3) continue; /* a duplicate */
4257dd7cddfSDavid du Colombier
4267dd7cddfSDavid du Colombier p2 = getsym(p1);
4277dd7cddfSDavid du Colombier p2->next = d;
4287dd7cddfSDavid du Colombier d = p2;
4297dd7cddfSDavid du Colombier }
4307dd7cddfSDavid du Colombier return d;
4317dd7cddfSDavid du Colombier }
4327dd7cddfSDavid du Colombier
4337dd7cddfSDavid du Colombier static Symbol *
catSlist(Symbol * a,Symbol * b)4347dd7cddfSDavid du Colombier catSlist(Symbol *a, Symbol *b)
4357dd7cddfSDavid du Colombier { Symbol *p1, *p2, *p3, *tmp;
4367dd7cddfSDavid du Colombier
4377dd7cddfSDavid du Colombier /* remove duplicates from b */
4387dd7cddfSDavid du Colombier for (p1 = a; p1; p1 = p1->next)
4397dd7cddfSDavid du Colombier { p3 = ZS;
4407dd7cddfSDavid du Colombier for (p2 = b; p2; p2 = p2->next)
4417dd7cddfSDavid du Colombier { if (strcmp(p1->name, p2->name))
4427dd7cddfSDavid du Colombier { p3 = p2;
4437dd7cddfSDavid du Colombier continue;
4447dd7cddfSDavid du Colombier }
4457dd7cddfSDavid du Colombier tmp = p2->next;
4467dd7cddfSDavid du Colombier tfree((void *) p2);
4477dd7cddfSDavid du Colombier if (p3)
4487dd7cddfSDavid du Colombier p3->next = tmp;
4497dd7cddfSDavid du Colombier else
4507dd7cddfSDavid du Colombier b = tmp;
4517dd7cddfSDavid du Colombier } }
4527dd7cddfSDavid du Colombier if (!a) return b;
4537dd7cddfSDavid du Colombier if (!b) return a;
4547dd7cddfSDavid du Colombier if (!b->next)
4557dd7cddfSDavid du Colombier { b->next = a;
4567dd7cddfSDavid du Colombier return b;
4577dd7cddfSDavid du Colombier }
4587dd7cddfSDavid du Colombier /* find end of list */
4597dd7cddfSDavid du Colombier for (p1 = a; p1->next; p1 = p1->next)
4607dd7cddfSDavid du Colombier ;
4617dd7cddfSDavid du Colombier p1->next = b;
4627dd7cddfSDavid du Colombier return a;
4637dd7cddfSDavid du Colombier }
4647dd7cddfSDavid du Colombier
4657dd7cddfSDavid du Colombier static void
fixinit(Node * orig)4667dd7cddfSDavid du Colombier fixinit(Node *orig)
4677dd7cddfSDavid du Colombier { Graph *p1, *g;
4687dd7cddfSDavid du Colombier Symbol *q1, *q2 = ZS;
4697dd7cddfSDavid du Colombier
4707dd7cddfSDavid du Colombier ng(tl_lookup("init"), ZS, ZN, ZN, ZN);
4717dd7cddfSDavid du Colombier p1 = pop_stack();
4727dd7cddfSDavid du Colombier p1->nxt = Nodes_Set;
4737dd7cddfSDavid du Colombier p1->Other = p1->Old = orig;
4747dd7cddfSDavid du Colombier Nodes_Set = p1;
4757dd7cddfSDavid du Colombier
4767dd7cddfSDavid du Colombier for (g = Nodes_Set; g; g = g->nxt)
4777dd7cddfSDavid du Colombier { for (q1 = g->incoming; q1; q1 = q2)
4787dd7cddfSDavid du Colombier { q2 = q1->next;
4797dd7cddfSDavid du Colombier Addout(g->name->name, q1->name);
4807dd7cddfSDavid du Colombier tfree((void *) q1);
4817dd7cddfSDavid du Colombier }
4827dd7cddfSDavid du Colombier g->incoming = ZS;
4837dd7cddfSDavid du Colombier }
4847dd7cddfSDavid du Colombier }
4857dd7cddfSDavid du Colombier
4867dd7cddfSDavid du Colombier static Node *
flatten(Node * p)4877dd7cddfSDavid du Colombier flatten(Node *p)
4887dd7cddfSDavid du Colombier { Node *q, *r, *z = ZN;
4897dd7cddfSDavid du Colombier
4907dd7cddfSDavid du Colombier for (q = p; q; q = q->nxt)
4917dd7cddfSDavid du Colombier { r = dupnode(q);
4927dd7cddfSDavid du Colombier if (z)
4937dd7cddfSDavid du Colombier z = tl_nn(AND, r, z);
4947dd7cddfSDavid du Colombier else
4957dd7cddfSDavid du Colombier z = r;
4967dd7cddfSDavid du Colombier }
4977dd7cddfSDavid du Colombier if (!z) return z;
4987dd7cddfSDavid du Colombier z = rewrite(z);
4997dd7cddfSDavid du Colombier return z;
5007dd7cddfSDavid du Colombier }
5017dd7cddfSDavid du Colombier
5027dd7cddfSDavid du Colombier static Node *
Duplicate(Node * n)5037dd7cddfSDavid du Colombier Duplicate(Node *n)
5047dd7cddfSDavid du Colombier { Node *n1, *n2, *lst = ZN, *d = ZN;
5057dd7cddfSDavid du Colombier
5067dd7cddfSDavid du Colombier for (n1 = n; n1; n1 = n1->nxt)
5077dd7cddfSDavid du Colombier { n2 = dupnode(n1);
5087dd7cddfSDavid du Colombier if (lst)
5097dd7cddfSDavid du Colombier { lst->nxt = n2;
5107dd7cddfSDavid du Colombier lst = n2;
5117dd7cddfSDavid du Colombier } else
5127dd7cddfSDavid du Colombier d = lst = n2;
5137dd7cddfSDavid du Colombier }
5147dd7cddfSDavid du Colombier return d;
5157dd7cddfSDavid du Colombier }
5167dd7cddfSDavid du Colombier
5177dd7cddfSDavid du Colombier static void
ng(Symbol * s,Symbol * in,Node * isnew,Node * isold,Node * next)5187dd7cddfSDavid du Colombier ng(Symbol *s, Symbol *in, Node *isnew, Node *isold, Node *next)
5197dd7cddfSDavid du Colombier { Graph *g = (Graph *) tl_emalloc(sizeof(Graph));
5207dd7cddfSDavid du Colombier
5217dd7cddfSDavid du Colombier if (s) g->name = s;
5227dd7cddfSDavid du Colombier else g->name = tl_lookup(newname());
5237dd7cddfSDavid du Colombier
5247dd7cddfSDavid du Colombier if (in) g->incoming = dupSlist(in);
5257dd7cddfSDavid du Colombier if (isnew) g->New = flatten(isnew);
5267dd7cddfSDavid du Colombier if (isold) g->Old = Duplicate(isold);
5277dd7cddfSDavid du Colombier if (next) g->Next = flatten(next);
5287dd7cddfSDavid du Colombier
5297dd7cddfSDavid du Colombier push_stack(g);
5307dd7cddfSDavid du Colombier }
5317dd7cddfSDavid du Colombier
5327dd7cddfSDavid du Colombier static void
sdump(Node * n)5337dd7cddfSDavid du Colombier sdump(Node *n)
5347dd7cddfSDavid du Colombier {
5357dd7cddfSDavid du Colombier switch (n->ntyp) {
5367dd7cddfSDavid du Colombier case PREDICATE: strcat(dumpbuf, n->sym->name);
5377dd7cddfSDavid du Colombier break;
5387dd7cddfSDavid du Colombier case U_OPER: strcat(dumpbuf, "U");
5397dd7cddfSDavid du Colombier goto common2;
5407dd7cddfSDavid du Colombier case V_OPER: strcat(dumpbuf, "V");
5417dd7cddfSDavid du Colombier goto common2;
5427dd7cddfSDavid du Colombier case OR: strcat(dumpbuf, "|");
5437dd7cddfSDavid du Colombier goto common2;
5447dd7cddfSDavid du Colombier case AND: strcat(dumpbuf, "&");
5457dd7cddfSDavid du Colombier common2: sdump(n->rgt);
5467dd7cddfSDavid du Colombier common1: sdump(n->lft);
5477dd7cddfSDavid du Colombier break;
5487dd7cddfSDavid du Colombier #ifdef NXT
5497dd7cddfSDavid du Colombier case NEXT: strcat(dumpbuf, "X");
5507dd7cddfSDavid du Colombier goto common1;
5517dd7cddfSDavid du Colombier #endif
5527dd7cddfSDavid du Colombier case NOT: strcat(dumpbuf, "!");
5537dd7cddfSDavid du Colombier goto common1;
5547dd7cddfSDavid du Colombier case TRUE: strcat(dumpbuf, "T");
5557dd7cddfSDavid du Colombier break;
5567dd7cddfSDavid du Colombier case FALSE: strcat(dumpbuf, "F");
5577dd7cddfSDavid du Colombier break;
5587dd7cddfSDavid du Colombier default: strcat(dumpbuf, "?");
5597dd7cddfSDavid du Colombier break;
5607dd7cddfSDavid du Colombier }
5617dd7cddfSDavid du Colombier }
5627dd7cddfSDavid du Colombier
5637dd7cddfSDavid du Colombier Symbol *
DoDump(Node * n)5647dd7cddfSDavid du Colombier DoDump(Node *n)
5657dd7cddfSDavid du Colombier {
5667dd7cddfSDavid du Colombier if (!n) return ZS;
5677dd7cddfSDavid du Colombier
5687dd7cddfSDavid du Colombier if (n->ntyp == PREDICATE)
5697dd7cddfSDavid du Colombier return n->sym;
5707dd7cddfSDavid du Colombier
5717dd7cddfSDavid du Colombier dumpbuf[0] = '\0';
5727dd7cddfSDavid du Colombier sdump(n);
5737dd7cddfSDavid du Colombier return tl_lookup(dumpbuf);
5747dd7cddfSDavid du Colombier }
5757dd7cddfSDavid du Colombier
5767dd7cddfSDavid du Colombier static int
not_new(Graph * g)5777dd7cddfSDavid du Colombier not_new(Graph *g)
5787dd7cddfSDavid du Colombier { Graph *q1; Node *tmp, *n1, *n2;
5797dd7cddfSDavid du Colombier Mapping *map;
5807dd7cddfSDavid du Colombier
5817dd7cddfSDavid du Colombier tmp = flatten(g->Old); /* duplicate, collapse, normalize */
5827dd7cddfSDavid du Colombier g->Other = g->Old; /* non normalized full version */
5837dd7cddfSDavid du Colombier g->Old = tmp;
5847dd7cddfSDavid du Colombier
5857dd7cddfSDavid du Colombier g->oldstring = DoDump(g->Old);
5867dd7cddfSDavid du Colombier
5877dd7cddfSDavid du Colombier tmp = flatten(g->Next);
5887dd7cddfSDavid du Colombier g->nxtstring = DoDump(tmp);
5897dd7cddfSDavid du Colombier
5907dd7cddfSDavid du Colombier if (tl_verbose) dump_graph(g);
5917dd7cddfSDavid du Colombier
5927dd7cddfSDavid du Colombier Debug2("\tformula-old: [%s]\n", g->oldstring?g->oldstring->name:"true");
5937dd7cddfSDavid du Colombier Debug2("\tformula-nxt: [%s]\n", g->nxtstring?g->nxtstring->name:"true");
5947dd7cddfSDavid du Colombier for (q1 = Nodes_Set; q1; q1 = q1->nxt)
5957dd7cddfSDavid du Colombier { Debug2(" compare old to: %s", q1->name->name);
5967dd7cddfSDavid du Colombier Debug2(" [%s]", q1->oldstring?q1->oldstring->name:"true");
5977dd7cddfSDavid du Colombier
5987dd7cddfSDavid du Colombier Debug2(" compare nxt to: %s", q1->name->name);
5997dd7cddfSDavid du Colombier Debug2(" [%s]", q1->nxtstring?q1->nxtstring->name:"true");
6007dd7cddfSDavid du Colombier
6017dd7cddfSDavid du Colombier if (q1->oldstring != g->oldstring
6027dd7cddfSDavid du Colombier || q1->nxtstring != g->nxtstring)
6037dd7cddfSDavid du Colombier { Debug(" => different\n");
6047dd7cddfSDavid du Colombier continue;
6057dd7cddfSDavid du Colombier }
6067dd7cddfSDavid du Colombier Debug(" => match\n");
6077dd7cddfSDavid du Colombier
6087dd7cddfSDavid du Colombier if (g->incoming)
6097dd7cddfSDavid du Colombier q1->incoming = catSlist(g->incoming, q1->incoming);
6107dd7cddfSDavid du Colombier
6117dd7cddfSDavid du Colombier /* check if there's anything in g->Other that needs
6127dd7cddfSDavid du Colombier adding to q1->Other
6137dd7cddfSDavid du Colombier */
6147dd7cddfSDavid du Colombier for (n2 = g->Other; n2; n2 = n2->nxt)
6157dd7cddfSDavid du Colombier { for (n1 = q1->Other; n1; n1 = n1->nxt)
6167dd7cddfSDavid du Colombier if (isequal(n1, n2))
6177dd7cddfSDavid du Colombier break;
6187dd7cddfSDavid du Colombier if (!n1)
6197dd7cddfSDavid du Colombier { Node *n3 = dupnode(n2);
6207dd7cddfSDavid du Colombier /* don't mess up n2->nxt */
6217dd7cddfSDavid du Colombier n3->nxt = q1->Other;
6227dd7cddfSDavid du Colombier q1->Other = n3;
6237dd7cddfSDavid du Colombier } }
6247dd7cddfSDavid du Colombier
6257dd7cddfSDavid du Colombier map = (Mapping *) tl_emalloc(sizeof(Mapping));
6267dd7cddfSDavid du Colombier map->from = g->name->name;
6277dd7cddfSDavid du Colombier map->to = q1;
6287dd7cddfSDavid du Colombier map->nxt = Mapped;
6297dd7cddfSDavid du Colombier Mapped = map;
6307dd7cddfSDavid du Colombier
6317dd7cddfSDavid du Colombier for (n1 = g->Other; n1; n1 = n2)
6327dd7cddfSDavid du Colombier { n2 = n1->nxt;
6337dd7cddfSDavid du Colombier releasenode(1, n1);
6347dd7cddfSDavid du Colombier }
6357dd7cddfSDavid du Colombier for (n1 = g->Old; n1; n1 = n2)
6367dd7cddfSDavid du Colombier { n2 = n1->nxt;
6377dd7cddfSDavid du Colombier releasenode(1, n1);
6387dd7cddfSDavid du Colombier }
6397dd7cddfSDavid du Colombier for (n1 = g->Next; n1; n1 = n2)
6407dd7cddfSDavid du Colombier { n2 = n1->nxt;
6417dd7cddfSDavid du Colombier releasenode(1, n1);
6427dd7cddfSDavid du Colombier }
6437dd7cddfSDavid du Colombier return 1;
6447dd7cddfSDavid du Colombier }
6457dd7cddfSDavid du Colombier
6467dd7cddfSDavid du Colombier if (newstates) tl_verbose=1;
6477dd7cddfSDavid du Colombier Debug2(" New Node %s [", g->name->name);
6487dd7cddfSDavid du Colombier for (n1 = g->Old; n1; n1 = n1->nxt)
6497dd7cddfSDavid du Colombier { Dump(n1); Debug(", "); }
6507dd7cddfSDavid du Colombier Debug2("] nr %d\n", Base);
6517dd7cddfSDavid du Colombier if (newstates) tl_verbose=0;
6527dd7cddfSDavid du Colombier
6537dd7cddfSDavid du Colombier Base++;
6547dd7cddfSDavid du Colombier g->nxt = Nodes_Set;
6557dd7cddfSDavid du Colombier Nodes_Set = g;
6567dd7cddfSDavid du Colombier
6577dd7cddfSDavid du Colombier return 0;
6587dd7cddfSDavid du Colombier }
6597dd7cddfSDavid du Colombier
6607dd7cddfSDavid du Colombier static void
expand_g(Graph * g)661312a1df1SDavid du Colombier expand_g(Graph *g)
6627dd7cddfSDavid du Colombier { Node *now, *n1, *n2, *nx;
6637dd7cddfSDavid du Colombier int can_release;
6647dd7cddfSDavid du Colombier
6657dd7cddfSDavid du Colombier if (!g->New)
6667dd7cddfSDavid du Colombier { Debug2("\nDone with %s", g->name->name);
6677dd7cddfSDavid du Colombier if (tl_verbose) dump_graph(g);
6687dd7cddfSDavid du Colombier if (not_new(g))
6697dd7cddfSDavid du Colombier { if (tl_verbose) printf("\tIs Not New\n");
6707dd7cddfSDavid du Colombier return;
6717dd7cddfSDavid du Colombier }
6727dd7cddfSDavid du Colombier if (g->Next)
6737dd7cddfSDavid du Colombier { Debug(" Has Next [");
6747dd7cddfSDavid du Colombier for (n1 = g->Next; n1; n1 = n1->nxt)
6757dd7cddfSDavid du Colombier { Dump(n1); Debug(", "); }
6767dd7cddfSDavid du Colombier Debug("]\n");
6777dd7cddfSDavid du Colombier
6787dd7cddfSDavid du Colombier ng(ZS, getsym(g->name), g->Next, ZN, ZN);
6797dd7cddfSDavid du Colombier }
6807dd7cddfSDavid du Colombier return;
6817dd7cddfSDavid du Colombier }
6827dd7cddfSDavid du Colombier
6837dd7cddfSDavid du Colombier if (tl_verbose)
6847dd7cddfSDavid du Colombier { Symbol *z;
6857dd7cddfSDavid du Colombier printf("\nExpand %s, from ", g->name->name);
6867dd7cddfSDavid du Colombier for (z = g->incoming; z; z = z->next)
6877dd7cddfSDavid du Colombier printf("%s, ", z->name);
6887dd7cddfSDavid du Colombier printf("\n\thandle:\t"); Explain(g->New->ntyp);
6897dd7cddfSDavid du Colombier dump_graph(g);
6907dd7cddfSDavid du Colombier }
6917dd7cddfSDavid du Colombier
6927dd7cddfSDavid du Colombier if (g->New->ntyp == AND)
6937dd7cddfSDavid du Colombier { if (g->New->nxt)
6947dd7cddfSDavid du Colombier { n2 = g->New->rgt;
6957dd7cddfSDavid du Colombier while (n2->nxt)
6967dd7cddfSDavid du Colombier n2 = n2->nxt;
6977dd7cddfSDavid du Colombier n2->nxt = g->New->nxt;
6987dd7cddfSDavid du Colombier }
6997dd7cddfSDavid du Colombier n1 = n2 = g->New->lft;
7007dd7cddfSDavid du Colombier while (n2->nxt)
7017dd7cddfSDavid du Colombier n2 = n2->nxt;
7027dd7cddfSDavid du Colombier n2->nxt = g->New->rgt;
7037dd7cddfSDavid du Colombier
7047dd7cddfSDavid du Colombier releasenode(0, g->New);
7057dd7cddfSDavid du Colombier
7067dd7cddfSDavid du Colombier g->New = n1;
7077dd7cddfSDavid du Colombier push_stack(g);
7087dd7cddfSDavid du Colombier return;
7097dd7cddfSDavid du Colombier }
7107dd7cddfSDavid du Colombier
7117dd7cddfSDavid du Colombier can_release = 0; /* unless it need not go into Old */
7127dd7cddfSDavid du Colombier now = g->New;
7137dd7cddfSDavid du Colombier g->New = g->New->nxt;
7147dd7cddfSDavid du Colombier now->nxt = ZN;
7157dd7cddfSDavid du Colombier
716312a1df1SDavid du Colombier if (now->ntyp != TRUE)
7177dd7cddfSDavid du Colombier { if (g->Old)
7187dd7cddfSDavid du Colombier { for (n1 = g->Old; n1->nxt; n1 = n1->nxt)
7197dd7cddfSDavid du Colombier if (isequal(now, n1))
7207dd7cddfSDavid du Colombier { can_release = 1;
7217dd7cddfSDavid du Colombier goto out;
7227dd7cddfSDavid du Colombier }
7237dd7cddfSDavid du Colombier n1->nxt = now;
7247dd7cddfSDavid du Colombier } else
7257dd7cddfSDavid du Colombier g->Old = now;
7267dd7cddfSDavid du Colombier }
7277dd7cddfSDavid du Colombier out:
7287dd7cddfSDavid du Colombier switch (now->ntyp) {
7297dd7cddfSDavid du Colombier case FALSE:
7307dd7cddfSDavid du Colombier push_stack(g);
7317dd7cddfSDavid du Colombier break;
7327dd7cddfSDavid du Colombier case TRUE:
7337dd7cddfSDavid du Colombier releasenode(1, now);
7347dd7cddfSDavid du Colombier push_stack(g);
7357dd7cddfSDavid du Colombier break;
7367dd7cddfSDavid du Colombier case PREDICATE:
7377dd7cddfSDavid du Colombier case NOT:
7387dd7cddfSDavid du Colombier if (can_release) releasenode(1, now);
7397dd7cddfSDavid du Colombier push_stack(g);
7407dd7cddfSDavid du Colombier break;
7417dd7cddfSDavid du Colombier case V_OPER:
742*00d97012SDavid du Colombier Assert(now->rgt != ZN, now->ntyp);
743*00d97012SDavid du Colombier Assert(now->lft != ZN, now->ntyp);
7447dd7cddfSDavid du Colombier Assert(now->rgt->nxt == ZN, now->ntyp);
7457dd7cddfSDavid du Colombier Assert(now->lft->nxt == ZN, now->ntyp);
7467dd7cddfSDavid du Colombier n1 = now->rgt;
7477dd7cddfSDavid du Colombier n1->nxt = g->New;
7487dd7cddfSDavid du Colombier
7497dd7cddfSDavid du Colombier if (can_release)
7507dd7cddfSDavid du Colombier nx = now;
7517dd7cddfSDavid du Colombier else
7527dd7cddfSDavid du Colombier nx = getnode(now); /* now also appears in Old */
7537dd7cddfSDavid du Colombier nx->nxt = g->Next;
7547dd7cddfSDavid du Colombier
7557dd7cddfSDavid du Colombier n2 = now->lft;
7567dd7cddfSDavid du Colombier n2->nxt = getnode(now->rgt);
7577dd7cddfSDavid du Colombier n2->nxt->nxt = g->New;
7587dd7cddfSDavid du Colombier g->New = flatten(n2);
7597dd7cddfSDavid du Colombier push_stack(g);
7607dd7cddfSDavid du Colombier ng(ZS, g->incoming, n1, g->Old, nx);
7617dd7cddfSDavid du Colombier break;
7627dd7cddfSDavid du Colombier
7637dd7cddfSDavid du Colombier case U_OPER:
7647dd7cddfSDavid du Colombier Assert(now->rgt->nxt == ZN, now->ntyp);
7657dd7cddfSDavid du Colombier Assert(now->lft->nxt == ZN, now->ntyp);
7667dd7cddfSDavid du Colombier n1 = now->lft;
7677dd7cddfSDavid du Colombier
7687dd7cddfSDavid du Colombier if (can_release)
7697dd7cddfSDavid du Colombier nx = now;
7707dd7cddfSDavid du Colombier else
7717dd7cddfSDavid du Colombier nx = getnode(now); /* now also appears in Old */
7727dd7cddfSDavid du Colombier nx->nxt = g->Next;
7737dd7cddfSDavid du Colombier
7747dd7cddfSDavid du Colombier n2 = now->rgt;
7757dd7cddfSDavid du Colombier n2->nxt = g->New;
7767dd7cddfSDavid du Colombier
7777dd7cddfSDavid du Colombier goto common;
7787dd7cddfSDavid du Colombier
7797dd7cddfSDavid du Colombier #ifdef NXT
7807dd7cddfSDavid du Colombier case NEXT:
781*00d97012SDavid du Colombier Assert(now->lft != ZN, now->ntyp);
7827dd7cddfSDavid du Colombier nx = dupnode(now->lft);
7837dd7cddfSDavid du Colombier nx->nxt = g->Next;
7847dd7cddfSDavid du Colombier g->Next = nx;
7857dd7cddfSDavid du Colombier if (can_release) releasenode(0, now);
7867dd7cddfSDavid du Colombier push_stack(g);
7877dd7cddfSDavid du Colombier break;
7887dd7cddfSDavid du Colombier #endif
7897dd7cddfSDavid du Colombier
7907dd7cddfSDavid du Colombier case OR:
7917dd7cddfSDavid du Colombier Assert(now->rgt->nxt == ZN, now->ntyp);
7927dd7cddfSDavid du Colombier Assert(now->lft->nxt == ZN, now->ntyp);
7937dd7cddfSDavid du Colombier n1 = now->lft;
7947dd7cddfSDavid du Colombier nx = g->Next;
7957dd7cddfSDavid du Colombier
7967dd7cddfSDavid du Colombier n2 = now->rgt;
7977dd7cddfSDavid du Colombier n2->nxt = g->New;
7987dd7cddfSDavid du Colombier common:
7997dd7cddfSDavid du Colombier n1->nxt = g->New;
8007dd7cddfSDavid du Colombier
8017dd7cddfSDavid du Colombier ng(ZS, g->incoming, n1, g->Old, nx);
8027dd7cddfSDavid du Colombier g->New = flatten(n2);
8037dd7cddfSDavid du Colombier
8047dd7cddfSDavid du Colombier if (can_release) releasenode(1, now);
8057dd7cddfSDavid du Colombier
8067dd7cddfSDavid du Colombier push_stack(g);
8077dd7cddfSDavid du Colombier break;
8087dd7cddfSDavid du Colombier }
8097dd7cddfSDavid du Colombier }
8107dd7cddfSDavid du Colombier
8117dd7cddfSDavid du Colombier Node *
twocases(Node * p)8127dd7cddfSDavid du Colombier twocases(Node *p)
8137dd7cddfSDavid du Colombier { Node *q;
8147dd7cddfSDavid du Colombier /* 1: ([]p1 && []p2) == [](p1 && p2) */
8157dd7cddfSDavid du Colombier /* 2: (<>p1 || <>p2) == <>(p1 || p2) */
8167dd7cddfSDavid du Colombier
8177dd7cddfSDavid du Colombier if (!p) return p;
8187dd7cddfSDavid du Colombier
8197dd7cddfSDavid du Colombier switch(p->ntyp) {
8207dd7cddfSDavid du Colombier case AND:
8217dd7cddfSDavid du Colombier case OR:
8227dd7cddfSDavid du Colombier case U_OPER:
8237dd7cddfSDavid du Colombier case V_OPER:
8247dd7cddfSDavid du Colombier p->lft = twocases(p->lft);
8257dd7cddfSDavid du Colombier p->rgt = twocases(p->rgt);
8267dd7cddfSDavid du Colombier break;
8277dd7cddfSDavid du Colombier #ifdef NXT
8287dd7cddfSDavid du Colombier case NEXT:
8297dd7cddfSDavid du Colombier #endif
8307dd7cddfSDavid du Colombier case NOT:
8317dd7cddfSDavid du Colombier p->lft = twocases(p->lft);
8327dd7cddfSDavid du Colombier break;
8337dd7cddfSDavid du Colombier
8347dd7cddfSDavid du Colombier default:
8357dd7cddfSDavid du Colombier break;
8367dd7cddfSDavid du Colombier }
8377dd7cddfSDavid du Colombier if (p->ntyp == AND /* 1 */
8387dd7cddfSDavid du Colombier && p->lft->ntyp == V_OPER
8397dd7cddfSDavid du Colombier && p->lft->lft->ntyp == FALSE
8407dd7cddfSDavid du Colombier && p->rgt->ntyp == V_OPER
8417dd7cddfSDavid du Colombier && p->rgt->lft->ntyp == FALSE)
8427dd7cddfSDavid du Colombier { q = tl_nn(V_OPER, False,
8437dd7cddfSDavid du Colombier tl_nn(AND, p->lft->rgt, p->rgt->rgt));
8447dd7cddfSDavid du Colombier } else
8457dd7cddfSDavid du Colombier if (p->ntyp == OR /* 2 */
8467dd7cddfSDavid du Colombier && p->lft->ntyp == U_OPER
8477dd7cddfSDavid du Colombier && p->lft->lft->ntyp == TRUE
8487dd7cddfSDavid du Colombier && p->rgt->ntyp == U_OPER
8497dd7cddfSDavid du Colombier && p->rgt->lft->ntyp == TRUE)
8507dd7cddfSDavid du Colombier { q = tl_nn(U_OPER, True,
8517dd7cddfSDavid du Colombier tl_nn(OR, p->lft->rgt, p->rgt->rgt));
8527dd7cddfSDavid du Colombier } else
8537dd7cddfSDavid du Colombier q = p;
8547dd7cddfSDavid du Colombier return q;
8557dd7cddfSDavid du Colombier }
8567dd7cddfSDavid du Colombier
8577dd7cddfSDavid du Colombier void
trans(Node * p)8587dd7cddfSDavid du Colombier trans(Node *p)
8597dd7cddfSDavid du Colombier { Node *op;
8607dd7cddfSDavid du Colombier Graph *g;
8617dd7cddfSDavid du Colombier
8627dd7cddfSDavid du Colombier if (!p || tl_errs) return;
8637dd7cddfSDavid du Colombier
8647dd7cddfSDavid du Colombier p = twocases(p);
8657dd7cddfSDavid du Colombier
8667dd7cddfSDavid du Colombier if (tl_verbose || tl_terse)
8677dd7cddfSDavid du Colombier { fprintf(tl_out, "\t/* Normlzd: ");
8687dd7cddfSDavid du Colombier dump(p);
8697dd7cddfSDavid du Colombier fprintf(tl_out, " */\n");
8707dd7cddfSDavid du Colombier }
8717dd7cddfSDavid du Colombier if (tl_terse)
8727dd7cddfSDavid du Colombier return;
8737dd7cddfSDavid du Colombier
8747dd7cddfSDavid du Colombier op = dupnode(p);
8757dd7cddfSDavid du Colombier
8767dd7cddfSDavid du Colombier ng(ZS, getsym(tl_lookup("init")), p, ZN, ZN);
877312a1df1SDavid du Colombier while ((g = Nodes_Stack) != (Graph *) 0)
8787dd7cddfSDavid du Colombier { Nodes_Stack = g->nxt;
879312a1df1SDavid du Colombier expand_g(g);
8807dd7cddfSDavid du Colombier }
8817dd7cddfSDavid du Colombier if (newstates)
8827dd7cddfSDavid du Colombier return;
8837dd7cddfSDavid du Colombier
8847dd7cddfSDavid du Colombier fixinit(p);
8857dd7cddfSDavid du Colombier liveness(flatten(op)); /* was: liveness(op); */
8867dd7cddfSDavid du Colombier
8877dd7cddfSDavid du Colombier mkbuchi();
8887dd7cddfSDavid du Colombier if (tl_verbose)
8897dd7cddfSDavid du Colombier { printf("/*\n");
8907dd7cddfSDavid du Colombier printf(" * %d states in Streett automaton\n", Base);
8917dd7cddfSDavid du Colombier printf(" * %d Streett acceptance conditions\n", Max_Red);
8927dd7cddfSDavid du Colombier printf(" * %d Buchi states\n", Total);
8937dd7cddfSDavid du Colombier printf(" */\n");
8947dd7cddfSDavid du Colombier }
8957dd7cddfSDavid du Colombier }
896