17dd7cddfSDavid du Colombier /***** tl_spin: tl_trans.c *****/
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 * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper,
9*de2caf28SDavid du Colombier * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995.
10*de2caf28SDavid du Colombier */
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier #include "tl.h"
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier extern FILE *tl_out;
1500d97012SDavid du Colombier extern int tl_errs, tl_verbose, tl_terse, newstates, state_cnt;
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier int Stack_mx=0, Max_Red=0, Total=0;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier static Mapping *Mapped = (Mapping *) 0;
207dd7cddfSDavid du Colombier static Graph *Nodes_Set = (Graph *) 0;
217dd7cddfSDavid du Colombier static Graph *Nodes_Stack = (Graph *) 0;
227dd7cddfSDavid du Colombier
23*de2caf28SDavid du Colombier static char *dumpbuf = NULL;
24*de2caf28SDavid du Colombier static size_t dumpbuf_size = 0;
25*de2caf28SDavid du Colombier static size_t dumpbuf_capacity = 0;
26*de2caf28SDavid du Colombier
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
5400d97012SDavid du Colombier void
append_to_dumpbuf(char * s)55*de2caf28SDavid du Colombier append_to_dumpbuf(char* s)
56*de2caf28SDavid du Colombier {
57*de2caf28SDavid du Colombier size_t len = strlen(s);
58*de2caf28SDavid du Colombier size_t size_needed = dumpbuf_size + len + 1;
59*de2caf28SDavid du Colombier if (size_needed > dumpbuf_capacity) {
60*de2caf28SDavid du Colombier dumpbuf = tl_erealloc(dumpbuf, size_needed, dumpbuf_capacity);
61*de2caf28SDavid du Colombier dumpbuf_capacity = size_needed;
62*de2caf28SDavid du Colombier }
63*de2caf28SDavid du Colombier
64*de2caf28SDavid du Colombier strncpy(&(dumpbuf[dumpbuf_size]), s, len + 1);
65*de2caf28SDavid du Colombier dumpbuf_size += len;
66*de2caf28SDavid du Colombier }
67*de2caf28SDavid du Colombier
68*de2caf28SDavid du Colombier void
ini_trans(void)6900d97012SDavid du Colombier ini_trans(void)
7000d97012SDavid du Colombier {
7100d97012SDavid du Colombier Stack_mx = 0;
7200d97012SDavid du Colombier Max_Red = 0;
7300d97012SDavid du Colombier Total = 0;
7400d97012SDavid du Colombier
7500d97012SDavid du Colombier Mapped = (Mapping *) 0;
7600d97012SDavid du Colombier Nodes_Set = (Graph *) 0;
7700d97012SDavid du Colombier Nodes_Stack = (Graph *) 0;
7800d97012SDavid du Colombier
79*de2caf28SDavid du Colombier dumpbuf_capacity = 4096;
80*de2caf28SDavid du Colombier dumpbuf = tl_emalloc(dumpbuf_capacity);
81*de2caf28SDavid du Colombier dumpbuf_size = 0;
82*de2caf28SDavid du Colombier memset(dumpbuf, 0, dumpbuf_capacity);
8300d97012SDavid du Colombier Red_cnt = 0;
8400d97012SDavid du Colombier Lab_cnt = 0;
8500d97012SDavid du Colombier Base = 0;
8600d97012SDavid du Colombier Stack_sz = 0;
8700d97012SDavid du Colombier }
8800d97012SDavid du Colombier
897dd7cddfSDavid du Colombier static void
dump_graph(Graph * g)907dd7cddfSDavid du Colombier dump_graph(Graph *g)
917dd7cddfSDavid du Colombier { Node *n1;
927dd7cddfSDavid du Colombier
937dd7cddfSDavid du Colombier printf("\n\tnew:\t");
947dd7cddfSDavid du Colombier for (n1 = g->New; n1; n1 = n1->nxt)
957dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
967dd7cddfSDavid du Colombier printf("\n\told:\t");
977dd7cddfSDavid du Colombier for (n1 = g->Old; n1; n1 = n1->nxt)
987dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
997dd7cddfSDavid du Colombier printf("\n\tnxt:\t");
1007dd7cddfSDavid du Colombier for (n1 = g->Next; n1; n1 = n1->nxt)
1017dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
1027dd7cddfSDavid du Colombier printf("\n\tother:\t");
1037dd7cddfSDavid du Colombier for (n1 = g->Other; n1; n1 = n1->nxt)
1047dd7cddfSDavid du Colombier { dump(n1); printf(", "); }
1057dd7cddfSDavid du Colombier printf("\n");
1067dd7cddfSDavid du Colombier }
1077dd7cddfSDavid du Colombier
1087dd7cddfSDavid du Colombier static void
push_stack(Graph * g)1097dd7cddfSDavid du Colombier push_stack(Graph *g)
1107dd7cddfSDavid du Colombier {
1117dd7cddfSDavid du Colombier if (!g) return;
1127dd7cddfSDavid du Colombier
1137dd7cddfSDavid du Colombier g->nxt = Nodes_Stack;
1147dd7cddfSDavid du Colombier Nodes_Stack = g;
1157dd7cddfSDavid du Colombier if (tl_verbose)
1167dd7cddfSDavid du Colombier { Symbol *z;
1177dd7cddfSDavid du Colombier printf("\nPush %s, from ", g->name->name);
1187dd7cddfSDavid du Colombier for (z = g->incoming; z; z = z->next)
1197dd7cddfSDavid du Colombier printf("%s, ", z->name);
1207dd7cddfSDavid du Colombier dump_graph(g);
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier Stack_sz++;
1237dd7cddfSDavid du Colombier if (Stack_sz > Stack_mx) Stack_mx = Stack_sz;
1247dd7cddfSDavid du Colombier }
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier static Graph *
pop_stack(void)1277dd7cddfSDavid du Colombier pop_stack(void)
1287dd7cddfSDavid du Colombier { Graph *g = Nodes_Stack;
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier if (g) Nodes_Stack = g->nxt;
1317dd7cddfSDavid du Colombier
1327dd7cddfSDavid du Colombier Stack_sz--;
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier return g;
1357dd7cddfSDavid du Colombier }
1367dd7cddfSDavid du Colombier
1377dd7cddfSDavid du Colombier static char *
newname(void)1387dd7cddfSDavid du Colombier newname(void)
13900d97012SDavid du Colombier { static char buf[32];
14000d97012SDavid du Colombier sprintf(buf, "S%d", state_cnt++);
1417dd7cddfSDavid du Colombier return buf;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier static int
has_clause(int tok,Graph * p,Node * n)1457dd7cddfSDavid du Colombier has_clause(int tok, Graph *p, Node *n)
1467dd7cddfSDavid du Colombier { Node *q, *qq;
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier switch (n->ntyp) {
1497dd7cddfSDavid du Colombier case AND:
1507dd7cddfSDavid du Colombier return has_clause(tok, p, n->lft) &&
1517dd7cddfSDavid du Colombier has_clause(tok, p, n->rgt);
1527dd7cddfSDavid du Colombier case OR:
1537dd7cddfSDavid du Colombier return has_clause(tok, p, n->lft) ||
1547dd7cddfSDavid du Colombier has_clause(tok, p, n->rgt);
1557dd7cddfSDavid du Colombier }
1567dd7cddfSDavid du Colombier
1577dd7cddfSDavid du Colombier for (q = p->Other; q; q = q->nxt)
1587dd7cddfSDavid du Colombier { qq = right_linked(q);
1597dd7cddfSDavid du Colombier if (anywhere(tok, n, qq))
1607dd7cddfSDavid du Colombier return 1;
1617dd7cddfSDavid du Colombier }
1627dd7cddfSDavid du Colombier return 0;
1637dd7cddfSDavid du Colombier }
1647dd7cddfSDavid du Colombier
1657dd7cddfSDavid du Colombier static void
mk_grn(Node * n)1667dd7cddfSDavid du Colombier mk_grn(Node *n)
1677dd7cddfSDavid du Colombier { Graph *p;
1687dd7cddfSDavid du Colombier
169*de2caf28SDavid du Colombier if (!n) return;
170*de2caf28SDavid du Colombier
1717dd7cddfSDavid du Colombier n = right_linked(n);
172312a1df1SDavid du Colombier more:
1737dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
1747dd7cddfSDavid du Colombier if (p->outgoing
1757dd7cddfSDavid du Colombier && has_clause(AND, p, n))
1767dd7cddfSDavid du Colombier { p->isgrn[p->grncnt++] =
1777dd7cddfSDavid du Colombier (unsigned char) Red_cnt;
1787dd7cddfSDavid du Colombier Lab_cnt++;
1797dd7cddfSDavid du Colombier }
180312a1df1SDavid du Colombier
181312a1df1SDavid du Colombier if (n->ntyp == U_OPER) /* 3.4.0 */
182312a1df1SDavid du Colombier { n = n->rgt;
183312a1df1SDavid du Colombier goto more;
184312a1df1SDavid du Colombier }
1857dd7cddfSDavid du Colombier }
1867dd7cddfSDavid du Colombier
1877dd7cddfSDavid du Colombier static void
mk_red(Node * n)1887dd7cddfSDavid du Colombier mk_red(Node *n)
1897dd7cddfSDavid du Colombier { Graph *p;
1907dd7cddfSDavid du Colombier
191*de2caf28SDavid du Colombier if (!n) return;
192*de2caf28SDavid du Colombier
1937dd7cddfSDavid du Colombier n = right_linked(n);
1947dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
1957dd7cddfSDavid du Colombier { if (p->outgoing
1967dd7cddfSDavid du Colombier && has_clause(0, p, n))
1977dd7cddfSDavid du Colombier { if (p->redcnt >= 63)
1987dd7cddfSDavid du Colombier Fatal("too many Untils", (char *)0);
1997dd7cddfSDavid du Colombier p->isred[p->redcnt++] =
2007dd7cddfSDavid du Colombier (unsigned char) Red_cnt;
2017dd7cddfSDavid du Colombier Lab_cnt++; Max_Red = Red_cnt;
2027dd7cddfSDavid du Colombier } }
2037dd7cddfSDavid du Colombier }
2047dd7cddfSDavid du Colombier
2057dd7cddfSDavid du Colombier static void
liveness(Node * n)2067dd7cddfSDavid du Colombier liveness(Node *n)
2077dd7cddfSDavid du Colombier {
2087dd7cddfSDavid du Colombier if (n)
2097dd7cddfSDavid du Colombier switch (n->ntyp) {
2107dd7cddfSDavid du Colombier #ifdef NXT
2117dd7cddfSDavid du Colombier case NEXT:
2127dd7cddfSDavid du Colombier liveness(n->lft);
2137dd7cddfSDavid du Colombier break;
2147dd7cddfSDavid du Colombier #endif
2157dd7cddfSDavid du Colombier case U_OPER:
2167dd7cddfSDavid du Colombier Red_cnt++;
2177dd7cddfSDavid du Colombier mk_red(n);
2187dd7cddfSDavid du Colombier mk_grn(n->rgt);
2197dd7cddfSDavid du Colombier /* fall through */
2207dd7cddfSDavid du Colombier case V_OPER:
2217dd7cddfSDavid du Colombier case OR: case AND:
2227dd7cddfSDavid du Colombier liveness(n->lft);
2237dd7cddfSDavid du Colombier liveness(n->rgt);
2247dd7cddfSDavid du Colombier break;
2257dd7cddfSDavid du Colombier }
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier
2287dd7cddfSDavid du Colombier static Graph *
findgraph(char * nm)2297dd7cddfSDavid du Colombier findgraph(char *nm)
2307dd7cddfSDavid du Colombier { Graph *p;
2317dd7cddfSDavid du Colombier Mapping *m;
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
2347dd7cddfSDavid du Colombier if (!strcmp(p->name->name, nm))
2357dd7cddfSDavid du Colombier return p;
2367dd7cddfSDavid du Colombier for (m = Mapped; m; m = m->nxt)
2377dd7cddfSDavid du Colombier if (strcmp(m->from, nm) == 0)
2387dd7cddfSDavid du Colombier return m->to;
2397dd7cddfSDavid du Colombier
2407dd7cddfSDavid du Colombier printf("warning: node %s not found\n", nm);
2417dd7cddfSDavid du Colombier return (Graph *) 0;
2427dd7cddfSDavid du Colombier }
2437dd7cddfSDavid du Colombier
2447dd7cddfSDavid du Colombier static void
Addout(char * to,char * from)2457dd7cddfSDavid du Colombier Addout(char *to, char *from)
2467dd7cddfSDavid du Colombier { Graph *p = findgraph(from);
2477dd7cddfSDavid du Colombier Symbol *s;
2487dd7cddfSDavid du Colombier
2497dd7cddfSDavid du Colombier if (!p) return;
2507dd7cddfSDavid du Colombier s = getsym(tl_lookup(to));
2517dd7cddfSDavid du Colombier s->next = p->outgoing;
2527dd7cddfSDavid du Colombier p->outgoing = s;
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier
2557dd7cddfSDavid du Colombier #ifdef NXT
2567dd7cddfSDavid du Colombier int
only_nxt(Node * n)2577dd7cddfSDavid du Colombier only_nxt(Node *n)
2587dd7cddfSDavid du Colombier {
2597dd7cddfSDavid du Colombier switch (n->ntyp) {
2607dd7cddfSDavid du Colombier case NEXT:
2617dd7cddfSDavid du Colombier return 1;
2627dd7cddfSDavid du Colombier case OR:
2637dd7cddfSDavid du Colombier case AND:
2647dd7cddfSDavid du Colombier return only_nxt(n->rgt) && only_nxt(n->lft);
2657dd7cddfSDavid du Colombier default:
2667dd7cddfSDavid du Colombier return 0;
2677dd7cddfSDavid du Colombier }
2687dd7cddfSDavid du Colombier }
2697dd7cddfSDavid du Colombier #endif
2707dd7cddfSDavid du Colombier
2717dd7cddfSDavid du Colombier int
dump_cond(Node * pp,Node * r,int first)2727dd7cddfSDavid du Colombier dump_cond(Node *pp, Node *r, int first)
2737dd7cddfSDavid du Colombier { Node *q;
2747dd7cddfSDavid du Colombier int frst = first;
2757dd7cddfSDavid du Colombier
2767dd7cddfSDavid du Colombier if (!pp) return frst;
2777dd7cddfSDavid du Colombier
2787dd7cddfSDavid du Colombier q = dupnode(pp);
2797dd7cddfSDavid du Colombier q = rewrite(q);
2807dd7cddfSDavid du Colombier
281*de2caf28SDavid du Colombier if (q->ntyp == CEXPR)
282*de2caf28SDavid du Colombier { if (!frst) fprintf(tl_out, " && ");
283*de2caf28SDavid du Colombier fprintf(tl_out, "c_expr { ");
284*de2caf28SDavid du Colombier dump_cond(q->lft, r, 1);
285*de2caf28SDavid du Colombier fprintf(tl_out, " } ");
286*de2caf28SDavid du Colombier frst = 0;
287*de2caf28SDavid du Colombier return frst;
288*de2caf28SDavid du Colombier }
289*de2caf28SDavid du Colombier
2907dd7cddfSDavid du Colombier if (q->ntyp == PREDICATE
2917dd7cddfSDavid du Colombier || q->ntyp == NOT
2927dd7cddfSDavid du Colombier #ifndef NXT
2937dd7cddfSDavid du Colombier || q->ntyp == OR
2947dd7cddfSDavid du Colombier #endif
2957dd7cddfSDavid du Colombier || q->ntyp == FALSE)
2967dd7cddfSDavid du Colombier { if (!frst) fprintf(tl_out, " && ");
2977dd7cddfSDavid du Colombier dump(q);
2987dd7cddfSDavid du Colombier frst = 0;
2997dd7cddfSDavid du Colombier #ifdef NXT
3007dd7cddfSDavid du Colombier } else if (q->ntyp == OR)
3017dd7cddfSDavid du Colombier { if (!frst) fprintf(tl_out, " && ");
3027dd7cddfSDavid du Colombier fprintf(tl_out, "((");
3037dd7cddfSDavid du Colombier frst = dump_cond(q->lft, r, 1);
3047dd7cddfSDavid du Colombier
3057dd7cddfSDavid du Colombier if (!frst)
3067dd7cddfSDavid du Colombier fprintf(tl_out, ") || (");
3077dd7cddfSDavid du Colombier else
3087dd7cddfSDavid du Colombier { if (only_nxt(q->lft))
3097dd7cddfSDavid du Colombier { fprintf(tl_out, "1))");
3107dd7cddfSDavid du Colombier return 0;
3117dd7cddfSDavid du Colombier }
3127dd7cddfSDavid du Colombier }
3137dd7cddfSDavid du Colombier
3147dd7cddfSDavid du Colombier frst = dump_cond(q->rgt, r, 1);
3157dd7cddfSDavid du Colombier
3167dd7cddfSDavid du Colombier if (frst)
3177dd7cddfSDavid du Colombier { if (only_nxt(q->rgt))
3187dd7cddfSDavid du Colombier fprintf(tl_out, "1");
3197dd7cddfSDavid du Colombier else
3207dd7cddfSDavid du Colombier fprintf(tl_out, "0");
3217dd7cddfSDavid du Colombier frst = 0;
3227dd7cddfSDavid du Colombier }
3237dd7cddfSDavid du Colombier
3247dd7cddfSDavid du Colombier fprintf(tl_out, "))");
3257dd7cddfSDavid du Colombier #endif
3267dd7cddfSDavid du Colombier } else if (q->ntyp == V_OPER
3277dd7cddfSDavid du Colombier && !anywhere(AND, q->rgt, r))
3287dd7cddfSDavid du Colombier { frst = dump_cond(q->rgt, r, frst);
3297dd7cddfSDavid du Colombier } else if (q->ntyp == AND)
3307dd7cddfSDavid du Colombier {
3317dd7cddfSDavid du Colombier frst = dump_cond(q->lft, r, frst);
3327dd7cddfSDavid du Colombier frst = dump_cond(q->rgt, r, frst);
3337dd7cddfSDavid du Colombier }
3347dd7cddfSDavid du Colombier
3357dd7cddfSDavid du Colombier return frst;
3367dd7cddfSDavid du Colombier }
3377dd7cddfSDavid du Colombier
3387dd7cddfSDavid du Colombier static int
choueka(Graph * p,int count)3397dd7cddfSDavid du Colombier choueka(Graph *p, int count)
3407dd7cddfSDavid du Colombier { int j, k, incr_cnt = 0;
3417dd7cddfSDavid du Colombier
3427dd7cddfSDavid du Colombier for (j = count; j <= Max_Red; j++) /* for each acceptance class */
3437dd7cddfSDavid du Colombier { int delta = 0;
3447dd7cddfSDavid du Colombier
3457dd7cddfSDavid du Colombier /* is state p labeled Grn-j OR not Red-j ? */
3467dd7cddfSDavid du Colombier
3477dd7cddfSDavid du Colombier for (k = 0; k < (int) p->grncnt; k++)
3487dd7cddfSDavid du Colombier if (p->isgrn[k] == j)
3497dd7cddfSDavid du Colombier { delta = 1;
3507dd7cddfSDavid du Colombier break;
3517dd7cddfSDavid du Colombier }
3527dd7cddfSDavid du Colombier if (delta)
3537dd7cddfSDavid du Colombier { incr_cnt++;
3547dd7cddfSDavid du Colombier continue;
3557dd7cddfSDavid du Colombier }
3567dd7cddfSDavid du Colombier for (k = 0; k < (int) p->redcnt; k++)
3577dd7cddfSDavid du Colombier if (p->isred[k] == j)
3587dd7cddfSDavid du Colombier { delta = 1;
3597dd7cddfSDavid du Colombier break;
3607dd7cddfSDavid du Colombier }
3617dd7cddfSDavid du Colombier
3627dd7cddfSDavid du Colombier if (delta) break;
3637dd7cddfSDavid du Colombier
3647dd7cddfSDavid du Colombier incr_cnt++;
3657dd7cddfSDavid du Colombier }
3667dd7cddfSDavid du Colombier return incr_cnt;
3677dd7cddfSDavid du Colombier }
3687dd7cddfSDavid du Colombier
3697dd7cddfSDavid du Colombier static int
set_prefix(char * pref,int count,Graph * r2)3707dd7cddfSDavid du Colombier set_prefix(char *pref, int count, Graph *r2)
3717dd7cddfSDavid du Colombier { int incr_cnt = 0; /* acceptance class 'count' */
3727dd7cddfSDavid du Colombier
3737dd7cddfSDavid du Colombier if (Lab_cnt == 0
3747dd7cddfSDavid du Colombier || Max_Red == 0)
3757dd7cddfSDavid du Colombier sprintf(pref, "accept"); /* new */
3767dd7cddfSDavid du Colombier else if (count >= Max_Red)
3777dd7cddfSDavid du Colombier sprintf(pref, "T0"); /* cycle */
3787dd7cddfSDavid du Colombier else
3797dd7cddfSDavid du Colombier { incr_cnt = choueka(r2, count+1);
3807dd7cddfSDavid du Colombier if (incr_cnt + count >= Max_Red)
3817dd7cddfSDavid du Colombier sprintf(pref, "accept"); /* last hop */
3827dd7cddfSDavid du Colombier else
3837dd7cddfSDavid du Colombier sprintf(pref, "T%d", count+incr_cnt);
3847dd7cddfSDavid du Colombier }
3857dd7cddfSDavid du Colombier return incr_cnt;
3867dd7cddfSDavid du Colombier }
3877dd7cddfSDavid du Colombier
3887dd7cddfSDavid du Colombier static void
fsm_trans(Graph * p,int count,char * curnm)3897dd7cddfSDavid du Colombier fsm_trans(Graph *p, int count, char *curnm)
3907dd7cddfSDavid du Colombier { Graph *r;
3917dd7cddfSDavid du Colombier Symbol *s;
39200d97012SDavid du Colombier char prefix[128], nwnm[256];
3937dd7cddfSDavid du Colombier
3947dd7cddfSDavid du Colombier if (!p->outgoing)
3957dd7cddfSDavid du Colombier addtrans(p, curnm, False, "accept_all");
3967dd7cddfSDavid du Colombier
3977dd7cddfSDavid du Colombier for (s = p->outgoing; s; s = s->next)
3987dd7cddfSDavid du Colombier { r = findgraph(s->name);
3997dd7cddfSDavid du Colombier if (!r) continue;
4007dd7cddfSDavid du Colombier if (r->outgoing)
4017dd7cddfSDavid du Colombier { (void) set_prefix(prefix, count, r);
4027dd7cddfSDavid du Colombier sprintf(nwnm, "%s_%s", prefix, s->name);
4037dd7cddfSDavid du Colombier } else
4047dd7cddfSDavid du Colombier strcpy(nwnm, "accept_all");
405312a1df1SDavid du Colombier
406312a1df1SDavid du Colombier if (tl_verbose)
407312a1df1SDavid du Colombier { printf("maxred=%d, count=%d, curnm=%s, nwnm=%s ",
408312a1df1SDavid du Colombier Max_Red, count, curnm, nwnm);
409312a1df1SDavid du Colombier printf("(greencnt=%d,%d, redcnt=%d,%d)\n",
410312a1df1SDavid du Colombier r->grncnt, r->isgrn[0],
411312a1df1SDavid du Colombier r->redcnt, r->isred[0]);
412312a1df1SDavid du Colombier }
4137dd7cddfSDavid du Colombier addtrans(p, curnm, r->Old, nwnm);
4147dd7cddfSDavid du Colombier }
4157dd7cddfSDavid du Colombier }
4167dd7cddfSDavid du Colombier
4177dd7cddfSDavid du Colombier static void
mkbuchi(void)4187dd7cddfSDavid du Colombier mkbuchi(void)
4197dd7cddfSDavid du Colombier { Graph *p;
4207dd7cddfSDavid du Colombier int k;
4217dd7cddfSDavid du Colombier char curnm[64];
4227dd7cddfSDavid du Colombier
4237dd7cddfSDavid du Colombier for (k = 0; k <= Max_Red; k++)
4247dd7cddfSDavid du Colombier for (p = Nodes_Set; p; p = p->nxt)
4257dd7cddfSDavid du Colombier { if (!p->outgoing)
4267dd7cddfSDavid du Colombier continue;
4277dd7cddfSDavid du Colombier if (k != 0
4287dd7cddfSDavid du Colombier && !strcmp(p->name->name, "init")
4297dd7cddfSDavid du Colombier && Max_Red != 0)
4307dd7cddfSDavid du Colombier continue;
4317dd7cddfSDavid du Colombier
4327dd7cddfSDavid du Colombier if (k == Max_Red
4337dd7cddfSDavid du Colombier && strcmp(p->name->name, "init") != 0)
4347dd7cddfSDavid du Colombier strcpy(curnm, "accept_");
4357dd7cddfSDavid du Colombier else
4367dd7cddfSDavid du Colombier sprintf(curnm, "T%d_", k);
4377dd7cddfSDavid du Colombier
4387dd7cddfSDavid du Colombier strcat(curnm, p->name->name);
4397dd7cddfSDavid du Colombier
4407dd7cddfSDavid du Colombier fsm_trans(p, k, curnm);
4417dd7cddfSDavid du Colombier }
4427dd7cddfSDavid du Colombier fsm_print();
4437dd7cddfSDavid du Colombier }
4447dd7cddfSDavid du Colombier
4457dd7cddfSDavid du Colombier static Symbol *
dupSlist(Symbol * s)4467dd7cddfSDavid du Colombier dupSlist(Symbol *s)
4477dd7cddfSDavid du Colombier { Symbol *p1, *p2, *p3, *d = ZS;
4487dd7cddfSDavid du Colombier
4497dd7cddfSDavid du Colombier for (p1 = s; p1; p1 = p1->next)
4507dd7cddfSDavid du Colombier { for (p3 = d; p3; p3 = p3->next)
4517dd7cddfSDavid du Colombier { if (!strcmp(p3->name, p1->name))
4527dd7cddfSDavid du Colombier break;
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier if (p3) continue; /* a duplicate */
4557dd7cddfSDavid du Colombier
4567dd7cddfSDavid du Colombier p2 = getsym(p1);
4577dd7cddfSDavid du Colombier p2->next = d;
4587dd7cddfSDavid du Colombier d = p2;
4597dd7cddfSDavid du Colombier }
4607dd7cddfSDavid du Colombier return d;
4617dd7cddfSDavid du Colombier }
4627dd7cddfSDavid du Colombier
4637dd7cddfSDavid du Colombier static Symbol *
catSlist(Symbol * a,Symbol * b)4647dd7cddfSDavid du Colombier catSlist(Symbol *a, Symbol *b)
4657dd7cddfSDavid du Colombier { Symbol *p1, *p2, *p3, *tmp;
4667dd7cddfSDavid du Colombier
4677dd7cddfSDavid du Colombier /* remove duplicates from b */
4687dd7cddfSDavid du Colombier for (p1 = a; p1; p1 = p1->next)
4697dd7cddfSDavid du Colombier { p3 = ZS;
470*de2caf28SDavid du Colombier p2 = b;
471*de2caf28SDavid du Colombier while (p2)
4727dd7cddfSDavid du Colombier { if (strcmp(p1->name, p2->name))
4737dd7cddfSDavid du Colombier { p3 = p2;
474*de2caf28SDavid du Colombier p2 = p2->next;
4757dd7cddfSDavid du Colombier continue;
4767dd7cddfSDavid du Colombier }
4777dd7cddfSDavid du Colombier tmp = p2->next;
4787dd7cddfSDavid du Colombier tfree((void *) p2);
479*de2caf28SDavid du Colombier p2 = tmp;
4807dd7cddfSDavid du Colombier if (p3)
4817dd7cddfSDavid du Colombier p3->next = tmp;
4827dd7cddfSDavid du Colombier else
4837dd7cddfSDavid du Colombier b = tmp;
4847dd7cddfSDavid du Colombier } }
4857dd7cddfSDavid du Colombier if (!a) return b;
4867dd7cddfSDavid du Colombier if (!b) return a;
4877dd7cddfSDavid du Colombier if (!b->next)
4887dd7cddfSDavid du Colombier { b->next = a;
4897dd7cddfSDavid du Colombier return b;
4907dd7cddfSDavid du Colombier }
4917dd7cddfSDavid du Colombier /* find end of list */
4927dd7cddfSDavid du Colombier for (p1 = a; p1->next; p1 = p1->next)
4937dd7cddfSDavid du Colombier ;
4947dd7cddfSDavid du Colombier p1->next = b;
4957dd7cddfSDavid du Colombier return a;
4967dd7cddfSDavid du Colombier }
4977dd7cddfSDavid du Colombier
4987dd7cddfSDavid du Colombier static void
fixinit(Node * orig)4997dd7cddfSDavid du Colombier fixinit(Node *orig)
5007dd7cddfSDavid du Colombier { Graph *p1, *g;
5017dd7cddfSDavid du Colombier Symbol *q1, *q2 = ZS;
5027dd7cddfSDavid du Colombier
5037dd7cddfSDavid du Colombier ng(tl_lookup("init"), ZS, ZN, ZN, ZN);
5047dd7cddfSDavid du Colombier p1 = pop_stack();
505*de2caf28SDavid du Colombier if (p1)
506*de2caf28SDavid du Colombier { p1->nxt = Nodes_Set;
5077dd7cddfSDavid du Colombier p1->Other = p1->Old = orig;
5087dd7cddfSDavid du Colombier Nodes_Set = p1;
509*de2caf28SDavid du Colombier }
5107dd7cddfSDavid du Colombier
5117dd7cddfSDavid du Colombier for (g = Nodes_Set; g; g = g->nxt)
5127dd7cddfSDavid du Colombier { for (q1 = g->incoming; q1; q1 = q2)
5137dd7cddfSDavid du Colombier { q2 = q1->next;
5147dd7cddfSDavid du Colombier Addout(g->name->name, q1->name);
5157dd7cddfSDavid du Colombier tfree((void *) q1);
5167dd7cddfSDavid du Colombier }
5177dd7cddfSDavid du Colombier g->incoming = ZS;
5187dd7cddfSDavid du Colombier }
5197dd7cddfSDavid du Colombier }
5207dd7cddfSDavid du Colombier
5217dd7cddfSDavid du Colombier static Node *
flatten(Node * p)5227dd7cddfSDavid du Colombier flatten(Node *p)
5237dd7cddfSDavid du Colombier { Node *q, *r, *z = ZN;
5247dd7cddfSDavid du Colombier
5257dd7cddfSDavid du Colombier for (q = p; q; q = q->nxt)
5267dd7cddfSDavid du Colombier { r = dupnode(q);
5277dd7cddfSDavid du Colombier if (z)
5287dd7cddfSDavid du Colombier z = tl_nn(AND, r, z);
5297dd7cddfSDavid du Colombier else
5307dd7cddfSDavid du Colombier z = r;
5317dd7cddfSDavid du Colombier }
5327dd7cddfSDavid du Colombier if (!z) return z;
5337dd7cddfSDavid du Colombier z = rewrite(z);
5347dd7cddfSDavid du Colombier return z;
5357dd7cddfSDavid du Colombier }
5367dd7cddfSDavid du Colombier
5377dd7cddfSDavid du Colombier static Node *
Duplicate(Node * n)5387dd7cddfSDavid du Colombier Duplicate(Node *n)
5397dd7cddfSDavid du Colombier { Node *n1, *n2, *lst = ZN, *d = ZN;
5407dd7cddfSDavid du Colombier
5417dd7cddfSDavid du Colombier for (n1 = n; n1; n1 = n1->nxt)
5427dd7cddfSDavid du Colombier { n2 = dupnode(n1);
5437dd7cddfSDavid du Colombier if (lst)
5447dd7cddfSDavid du Colombier { lst->nxt = n2;
5457dd7cddfSDavid du Colombier lst = n2;
5467dd7cddfSDavid du Colombier } else
5477dd7cddfSDavid du Colombier d = lst = n2;
5487dd7cddfSDavid du Colombier }
5497dd7cddfSDavid du Colombier return d;
5507dd7cddfSDavid du Colombier }
5517dd7cddfSDavid du Colombier
5527dd7cddfSDavid du Colombier static void
ng(Symbol * s,Symbol * in,Node * isnew,Node * isold,Node * next)5537dd7cddfSDavid du Colombier ng(Symbol *s, Symbol *in, Node *isnew, Node *isold, Node *next)
5547dd7cddfSDavid du Colombier { Graph *g = (Graph *) tl_emalloc(sizeof(Graph));
5557dd7cddfSDavid du Colombier
5567dd7cddfSDavid du Colombier if (s) g->name = s;
5577dd7cddfSDavid du Colombier else g->name = tl_lookup(newname());
5587dd7cddfSDavid du Colombier
5597dd7cddfSDavid du Colombier if (in) g->incoming = dupSlist(in);
5607dd7cddfSDavid du Colombier if (isnew) g->New = flatten(isnew);
5617dd7cddfSDavid du Colombier if (isold) g->Old = Duplicate(isold);
5627dd7cddfSDavid du Colombier if (next) g->Next = flatten(next);
5637dd7cddfSDavid du Colombier
5647dd7cddfSDavid du Colombier push_stack(g);
5657dd7cddfSDavid du Colombier }
5667dd7cddfSDavid du Colombier
5677dd7cddfSDavid du Colombier static void
sdump(Node * n)5687dd7cddfSDavid du Colombier sdump(Node *n)
5697dd7cddfSDavid du Colombier {
5707dd7cddfSDavid du Colombier switch (n->ntyp) {
571*de2caf28SDavid du Colombier case PREDICATE: append_to_dumpbuf(n->sym->name);
5727dd7cddfSDavid du Colombier break;
573*de2caf28SDavid du Colombier case U_OPER: append_to_dumpbuf("U");
5747dd7cddfSDavid du Colombier goto common2;
575*de2caf28SDavid du Colombier case V_OPER: append_to_dumpbuf("V");
5767dd7cddfSDavid du Colombier goto common2;
577*de2caf28SDavid du Colombier case OR: append_to_dumpbuf("|");
5787dd7cddfSDavid du Colombier goto common2;
579*de2caf28SDavid du Colombier case AND: append_to_dumpbuf("&");
5807dd7cddfSDavid du Colombier common2: sdump(n->rgt);
5817dd7cddfSDavid du Colombier common1: sdump(n->lft);
5827dd7cddfSDavid du Colombier break;
5837dd7cddfSDavid du Colombier #ifdef NXT
584*de2caf28SDavid du Colombier case NEXT: append_to_dumpbuf("X");
5857dd7cddfSDavid du Colombier goto common1;
5867dd7cddfSDavid du Colombier #endif
587*de2caf28SDavid du Colombier case CEXPR: append_to_dumpbuf("c_expr {");
588*de2caf28SDavid du Colombier sdump(n->lft);
589*de2caf28SDavid du Colombier append_to_dumpbuf("}");
590*de2caf28SDavid du Colombier break;
591*de2caf28SDavid du Colombier case NOT: append_to_dumpbuf("!");
5927dd7cddfSDavid du Colombier goto common1;
593*de2caf28SDavid du Colombier case TRUE: append_to_dumpbuf("T");
5947dd7cddfSDavid du Colombier break;
595*de2caf28SDavid du Colombier case FALSE: append_to_dumpbuf("F");
5967dd7cddfSDavid du Colombier break;
597*de2caf28SDavid du Colombier default: append_to_dumpbuf("?");
5987dd7cddfSDavid du Colombier break;
5997dd7cddfSDavid du Colombier }
6007dd7cddfSDavid du Colombier }
6017dd7cddfSDavid du Colombier
6027dd7cddfSDavid du Colombier Symbol *
DoDump(Node * n)6037dd7cddfSDavid du Colombier DoDump(Node *n)
6047dd7cddfSDavid du Colombier {
6057dd7cddfSDavid du Colombier if (!n) return ZS;
6067dd7cddfSDavid du Colombier
6077dd7cddfSDavid du Colombier if (n->ntyp == PREDICATE)
6087dd7cddfSDavid du Colombier return n->sym;
6097dd7cddfSDavid du Colombier
610*de2caf28SDavid du Colombier if (dumpbuf) {
6117dd7cddfSDavid du Colombier dumpbuf[0] = '\0';
612*de2caf28SDavid du Colombier dumpbuf_size = 0;
6137dd7cddfSDavid du Colombier sdump(n);
6147dd7cddfSDavid du Colombier return tl_lookup(dumpbuf);
6157dd7cddfSDavid du Colombier }
6167dd7cddfSDavid du Colombier
617*de2caf28SDavid du Colombier sdump(n);
618*de2caf28SDavid du Colombier return tl_lookup("");
619*de2caf28SDavid du Colombier }
620*de2caf28SDavid du Colombier
6217dd7cddfSDavid du Colombier static int
not_new(Graph * g)6227dd7cddfSDavid du Colombier not_new(Graph *g)
6237dd7cddfSDavid du Colombier { Graph *q1; Node *tmp, *n1, *n2;
6247dd7cddfSDavid du Colombier Mapping *map;
6257dd7cddfSDavid du Colombier
6267dd7cddfSDavid du Colombier tmp = flatten(g->Old); /* duplicate, collapse, normalize */
6277dd7cddfSDavid du Colombier g->Other = g->Old; /* non normalized full version */
6287dd7cddfSDavid du Colombier g->Old = tmp;
6297dd7cddfSDavid du Colombier
6307dd7cddfSDavid du Colombier g->oldstring = DoDump(g->Old);
6317dd7cddfSDavid du Colombier
6327dd7cddfSDavid du Colombier tmp = flatten(g->Next);
6337dd7cddfSDavid du Colombier g->nxtstring = DoDump(tmp);
6347dd7cddfSDavid du Colombier
6357dd7cddfSDavid du Colombier if (tl_verbose) dump_graph(g);
6367dd7cddfSDavid du Colombier
6377dd7cddfSDavid du Colombier Debug2("\tformula-old: [%s]\n", g->oldstring?g->oldstring->name:"true");
6387dd7cddfSDavid du Colombier Debug2("\tformula-nxt: [%s]\n", g->nxtstring?g->nxtstring->name:"true");
6397dd7cddfSDavid du Colombier for (q1 = Nodes_Set; q1; q1 = q1->nxt)
6407dd7cddfSDavid du Colombier { Debug2(" compare old to: %s", q1->name->name);
6417dd7cddfSDavid du Colombier Debug2(" [%s]", q1->oldstring?q1->oldstring->name:"true");
6427dd7cddfSDavid du Colombier
6437dd7cddfSDavid du Colombier Debug2(" compare nxt to: %s", q1->name->name);
6447dd7cddfSDavid du Colombier Debug2(" [%s]", q1->nxtstring?q1->nxtstring->name:"true");
6457dd7cddfSDavid du Colombier
6467dd7cddfSDavid du Colombier if (q1->oldstring != g->oldstring
6477dd7cddfSDavid du Colombier || q1->nxtstring != g->nxtstring)
6487dd7cddfSDavid du Colombier { Debug(" => different\n");
6497dd7cddfSDavid du Colombier continue;
6507dd7cddfSDavid du Colombier }
6517dd7cddfSDavid du Colombier Debug(" => match\n");
6527dd7cddfSDavid du Colombier
6537dd7cddfSDavid du Colombier if (g->incoming)
6547dd7cddfSDavid du Colombier q1->incoming = catSlist(g->incoming, q1->incoming);
6557dd7cddfSDavid du Colombier
6567dd7cddfSDavid du Colombier /* check if there's anything in g->Other that needs
6577dd7cddfSDavid du Colombier adding to q1->Other
6587dd7cddfSDavid du Colombier */
6597dd7cddfSDavid du Colombier for (n2 = g->Other; n2; n2 = n2->nxt)
6607dd7cddfSDavid du Colombier { for (n1 = q1->Other; n1; n1 = n1->nxt)
6617dd7cddfSDavid du Colombier if (isequal(n1, n2))
6627dd7cddfSDavid du Colombier break;
6637dd7cddfSDavid du Colombier if (!n1)
6647dd7cddfSDavid du Colombier { Node *n3 = dupnode(n2);
6657dd7cddfSDavid du Colombier /* don't mess up n2->nxt */
6667dd7cddfSDavid du Colombier n3->nxt = q1->Other;
6677dd7cddfSDavid du Colombier q1->Other = n3;
6687dd7cddfSDavid du Colombier } }
6697dd7cddfSDavid du Colombier
6707dd7cddfSDavid du Colombier map = (Mapping *) tl_emalloc(sizeof(Mapping));
6717dd7cddfSDavid du Colombier map->from = g->name->name;
6727dd7cddfSDavid du Colombier map->to = q1;
6737dd7cddfSDavid du Colombier map->nxt = Mapped;
6747dd7cddfSDavid du Colombier Mapped = map;
6757dd7cddfSDavid du Colombier
6767dd7cddfSDavid du Colombier for (n1 = g->Other; n1; n1 = n2)
6777dd7cddfSDavid du Colombier { n2 = n1->nxt;
6787dd7cddfSDavid du Colombier releasenode(1, n1);
6797dd7cddfSDavid du Colombier }
6807dd7cddfSDavid du Colombier for (n1 = g->Old; n1; n1 = n2)
6817dd7cddfSDavid du Colombier { n2 = n1->nxt;
6827dd7cddfSDavid du Colombier releasenode(1, n1);
6837dd7cddfSDavid du Colombier }
6847dd7cddfSDavid du Colombier for (n1 = g->Next; n1; n1 = n2)
6857dd7cddfSDavid du Colombier { n2 = n1->nxt;
6867dd7cddfSDavid du Colombier releasenode(1, n1);
6877dd7cddfSDavid du Colombier }
6887dd7cddfSDavid du Colombier return 1;
6897dd7cddfSDavid du Colombier }
6907dd7cddfSDavid du Colombier
6917dd7cddfSDavid du Colombier if (newstates) tl_verbose=1;
6927dd7cddfSDavid du Colombier Debug2(" New Node %s [", g->name->name);
6937dd7cddfSDavid du Colombier for (n1 = g->Old; n1; n1 = n1->nxt)
6947dd7cddfSDavid du Colombier { Dump(n1); Debug(", "); }
6957dd7cddfSDavid du Colombier Debug2("] nr %d\n", Base);
6967dd7cddfSDavid du Colombier if (newstates) tl_verbose=0;
6977dd7cddfSDavid du Colombier
6987dd7cddfSDavid du Colombier Base++;
6997dd7cddfSDavid du Colombier g->nxt = Nodes_Set;
7007dd7cddfSDavid du Colombier Nodes_Set = g;
7017dd7cddfSDavid du Colombier
7027dd7cddfSDavid du Colombier return 0;
7037dd7cddfSDavid du Colombier }
7047dd7cddfSDavid du Colombier
7057dd7cddfSDavid du Colombier static void
expand_g(Graph * g)706312a1df1SDavid du Colombier expand_g(Graph *g)
7077dd7cddfSDavid du Colombier { Node *now, *n1, *n2, *nx;
7087dd7cddfSDavid du Colombier int can_release;
7097dd7cddfSDavid du Colombier
7107dd7cddfSDavid du Colombier if (!g->New)
7117dd7cddfSDavid du Colombier { Debug2("\nDone with %s", g->name->name);
7127dd7cddfSDavid du Colombier if (tl_verbose) dump_graph(g);
7137dd7cddfSDavid du Colombier if (not_new(g))
7147dd7cddfSDavid du Colombier { if (tl_verbose) printf("\tIs Not New\n");
7157dd7cddfSDavid du Colombier return;
7167dd7cddfSDavid du Colombier }
7177dd7cddfSDavid du Colombier if (g->Next)
7187dd7cddfSDavid du Colombier { Debug(" Has Next [");
7197dd7cddfSDavid du Colombier for (n1 = g->Next; n1; n1 = n1->nxt)
7207dd7cddfSDavid du Colombier { Dump(n1); Debug(", "); }
7217dd7cddfSDavid du Colombier Debug("]\n");
7227dd7cddfSDavid du Colombier
7237dd7cddfSDavid du Colombier ng(ZS, getsym(g->name), g->Next, ZN, ZN);
7247dd7cddfSDavid du Colombier }
7257dd7cddfSDavid du Colombier return;
7267dd7cddfSDavid du Colombier }
7277dd7cddfSDavid du Colombier
7287dd7cddfSDavid du Colombier if (tl_verbose)
7297dd7cddfSDavid du Colombier { Symbol *z;
7307dd7cddfSDavid du Colombier printf("\nExpand %s, from ", g->name->name);
7317dd7cddfSDavid du Colombier for (z = g->incoming; z; z = z->next)
7327dd7cddfSDavid du Colombier printf("%s, ", z->name);
7337dd7cddfSDavid du Colombier printf("\n\thandle:\t"); Explain(g->New->ntyp);
7347dd7cddfSDavid du Colombier dump_graph(g);
7357dd7cddfSDavid du Colombier }
7367dd7cddfSDavid du Colombier
7377dd7cddfSDavid du Colombier if (g->New->ntyp == AND)
7387dd7cddfSDavid du Colombier { if (g->New->nxt)
7397dd7cddfSDavid du Colombier { n2 = g->New->rgt;
7407dd7cddfSDavid du Colombier while (n2->nxt)
7417dd7cddfSDavid du Colombier n2 = n2->nxt;
7427dd7cddfSDavid du Colombier n2->nxt = g->New->nxt;
7437dd7cddfSDavid du Colombier }
7447dd7cddfSDavid du Colombier n1 = n2 = g->New->lft;
7457dd7cddfSDavid du Colombier while (n2->nxt)
7467dd7cddfSDavid du Colombier n2 = n2->nxt;
7477dd7cddfSDavid du Colombier n2->nxt = g->New->rgt;
7487dd7cddfSDavid du Colombier
7497dd7cddfSDavid du Colombier releasenode(0, g->New);
7507dd7cddfSDavid du Colombier
7517dd7cddfSDavid du Colombier g->New = n1;
7527dd7cddfSDavid du Colombier push_stack(g);
7537dd7cddfSDavid du Colombier return;
7547dd7cddfSDavid du Colombier }
7557dd7cddfSDavid du Colombier
7567dd7cddfSDavid du Colombier can_release = 0; /* unless it need not go into Old */
7577dd7cddfSDavid du Colombier now = g->New;
7587dd7cddfSDavid du Colombier g->New = g->New->nxt;
7597dd7cddfSDavid du Colombier now->nxt = ZN;
7607dd7cddfSDavid du Colombier
761312a1df1SDavid du Colombier if (now->ntyp != TRUE)
7627dd7cddfSDavid du Colombier { if (g->Old)
7637dd7cddfSDavid du Colombier { for (n1 = g->Old; n1->nxt; n1 = n1->nxt)
7647dd7cddfSDavid du Colombier if (isequal(now, n1))
7657dd7cddfSDavid du Colombier { can_release = 1;
7667dd7cddfSDavid du Colombier goto out;
7677dd7cddfSDavid du Colombier }
7687dd7cddfSDavid du Colombier n1->nxt = now;
7697dd7cddfSDavid du Colombier } else
7707dd7cddfSDavid du Colombier g->Old = now;
7717dd7cddfSDavid du Colombier }
7727dd7cddfSDavid du Colombier out:
7737dd7cddfSDavid du Colombier switch (now->ntyp) {
7747dd7cddfSDavid du Colombier case FALSE:
7757dd7cddfSDavid du Colombier push_stack(g);
7767dd7cddfSDavid du Colombier break;
7777dd7cddfSDavid du Colombier case TRUE:
7787dd7cddfSDavid du Colombier releasenode(1, now);
7797dd7cddfSDavid du Colombier push_stack(g);
7807dd7cddfSDavid du Colombier break;
7817dd7cddfSDavid du Colombier case PREDICATE:
7827dd7cddfSDavid du Colombier case NOT:
783*de2caf28SDavid du Colombier case CEXPR:
7847dd7cddfSDavid du Colombier if (can_release) releasenode(1, now);
7857dd7cddfSDavid du Colombier push_stack(g);
7867dd7cddfSDavid du Colombier break;
7877dd7cddfSDavid du Colombier case V_OPER:
78800d97012SDavid du Colombier Assert(now->rgt != ZN, now->ntyp);
78900d97012SDavid du Colombier Assert(now->lft != ZN, now->ntyp);
7907dd7cddfSDavid du Colombier Assert(now->rgt->nxt == ZN, now->ntyp);
7917dd7cddfSDavid du Colombier Assert(now->lft->nxt == ZN, now->ntyp);
7927dd7cddfSDavid du Colombier n1 = now->rgt;
7937dd7cddfSDavid du Colombier n1->nxt = g->New;
7947dd7cddfSDavid du Colombier
7957dd7cddfSDavid du Colombier if (can_release)
7967dd7cddfSDavid du Colombier nx = now;
7977dd7cddfSDavid du Colombier else
7987dd7cddfSDavid du Colombier nx = getnode(now); /* now also appears in Old */
7997dd7cddfSDavid du Colombier nx->nxt = g->Next;
8007dd7cddfSDavid du Colombier
8017dd7cddfSDavid du Colombier n2 = now->lft;
8027dd7cddfSDavid du Colombier n2->nxt = getnode(now->rgt);
8037dd7cddfSDavid du Colombier n2->nxt->nxt = g->New;
8047dd7cddfSDavid du Colombier g->New = flatten(n2);
8057dd7cddfSDavid du Colombier push_stack(g);
8067dd7cddfSDavid du Colombier ng(ZS, g->incoming, n1, g->Old, nx);
8077dd7cddfSDavid du Colombier break;
8087dd7cddfSDavid du Colombier
8097dd7cddfSDavid du Colombier case U_OPER:
8107dd7cddfSDavid du Colombier Assert(now->rgt->nxt == ZN, now->ntyp);
8117dd7cddfSDavid du Colombier Assert(now->lft->nxt == ZN, now->ntyp);
8127dd7cddfSDavid du Colombier n1 = now->lft;
8137dd7cddfSDavid du Colombier
8147dd7cddfSDavid du Colombier if (can_release)
8157dd7cddfSDavid du Colombier nx = now;
8167dd7cddfSDavid du Colombier else
8177dd7cddfSDavid du Colombier nx = getnode(now); /* now also appears in Old */
8187dd7cddfSDavid du Colombier nx->nxt = g->Next;
8197dd7cddfSDavid du Colombier
8207dd7cddfSDavid du Colombier n2 = now->rgt;
8217dd7cddfSDavid du Colombier n2->nxt = g->New;
8227dd7cddfSDavid du Colombier
8237dd7cddfSDavid du Colombier goto common;
8247dd7cddfSDavid du Colombier
8257dd7cddfSDavid du Colombier #ifdef NXT
8267dd7cddfSDavid du Colombier case NEXT:
82700d97012SDavid du Colombier Assert(now->lft != ZN, now->ntyp);
8287dd7cddfSDavid du Colombier nx = dupnode(now->lft);
8297dd7cddfSDavid du Colombier nx->nxt = g->Next;
8307dd7cddfSDavid du Colombier g->Next = nx;
8317dd7cddfSDavid du Colombier if (can_release) releasenode(0, now);
8327dd7cddfSDavid du Colombier push_stack(g);
8337dd7cddfSDavid du Colombier break;
8347dd7cddfSDavid du Colombier #endif
8357dd7cddfSDavid du Colombier
8367dd7cddfSDavid du Colombier case OR:
8377dd7cddfSDavid du Colombier Assert(now->rgt->nxt == ZN, now->ntyp);
8387dd7cddfSDavid du Colombier Assert(now->lft->nxt == ZN, now->ntyp);
8397dd7cddfSDavid du Colombier n1 = now->lft;
8407dd7cddfSDavid du Colombier nx = g->Next;
8417dd7cddfSDavid du Colombier
8427dd7cddfSDavid du Colombier n2 = now->rgt;
8437dd7cddfSDavid du Colombier n2->nxt = g->New;
8447dd7cddfSDavid du Colombier common:
8457dd7cddfSDavid du Colombier n1->nxt = g->New;
8467dd7cddfSDavid du Colombier
8477dd7cddfSDavid du Colombier ng(ZS, g->incoming, n1, g->Old, nx);
8487dd7cddfSDavid du Colombier g->New = flatten(n2);
8497dd7cddfSDavid du Colombier
8507dd7cddfSDavid du Colombier if (can_release) releasenode(1, now);
8517dd7cddfSDavid du Colombier
8527dd7cddfSDavid du Colombier push_stack(g);
8537dd7cddfSDavid du Colombier break;
8547dd7cddfSDavid du Colombier }
8557dd7cddfSDavid du Colombier }
8567dd7cddfSDavid du Colombier
8577dd7cddfSDavid du Colombier Node *
twocases(Node * p)8587dd7cddfSDavid du Colombier twocases(Node *p)
8597dd7cddfSDavid du Colombier { Node *q;
8607dd7cddfSDavid du Colombier /* 1: ([]p1 && []p2) == [](p1 && p2) */
8617dd7cddfSDavid du Colombier /* 2: (<>p1 || <>p2) == <>(p1 || p2) */
8627dd7cddfSDavid du Colombier
8637dd7cddfSDavid du Colombier if (!p) return p;
8647dd7cddfSDavid du Colombier
8657dd7cddfSDavid du Colombier switch(p->ntyp) {
8667dd7cddfSDavid du Colombier case AND:
8677dd7cddfSDavid du Colombier case OR:
8687dd7cddfSDavid du Colombier case U_OPER:
8697dd7cddfSDavid du Colombier case V_OPER:
8707dd7cddfSDavid du Colombier p->lft = twocases(p->lft);
8717dd7cddfSDavid du Colombier p->rgt = twocases(p->rgt);
8727dd7cddfSDavid du Colombier break;
8737dd7cddfSDavid du Colombier #ifdef NXT
8747dd7cddfSDavid du Colombier case NEXT:
8757dd7cddfSDavid du Colombier #endif
8767dd7cddfSDavid du Colombier case NOT:
8777dd7cddfSDavid du Colombier p->lft = twocases(p->lft);
8787dd7cddfSDavid du Colombier break;
8797dd7cddfSDavid du Colombier
8807dd7cddfSDavid du Colombier default:
8817dd7cddfSDavid du Colombier break;
8827dd7cddfSDavid du Colombier }
8837dd7cddfSDavid du Colombier if (p->ntyp == AND /* 1 */
8847dd7cddfSDavid du Colombier && p->lft->ntyp == V_OPER
8857dd7cddfSDavid du Colombier && p->lft->lft->ntyp == FALSE
8867dd7cddfSDavid du Colombier && p->rgt->ntyp == V_OPER
8877dd7cddfSDavid du Colombier && p->rgt->lft->ntyp == FALSE)
8887dd7cddfSDavid du Colombier { q = tl_nn(V_OPER, False,
8897dd7cddfSDavid du Colombier tl_nn(AND, p->lft->rgt, p->rgt->rgt));
8907dd7cddfSDavid du Colombier } else
8917dd7cddfSDavid du Colombier if (p->ntyp == OR /* 2 */
8927dd7cddfSDavid du Colombier && p->lft->ntyp == U_OPER
8937dd7cddfSDavid du Colombier && p->lft->lft->ntyp == TRUE
8947dd7cddfSDavid du Colombier && p->rgt->ntyp == U_OPER
8957dd7cddfSDavid du Colombier && p->rgt->lft->ntyp == TRUE)
8967dd7cddfSDavid du Colombier { q = tl_nn(U_OPER, True,
8977dd7cddfSDavid du Colombier tl_nn(OR, p->lft->rgt, p->rgt->rgt));
8987dd7cddfSDavid du Colombier } else
8997dd7cddfSDavid du Colombier q = p;
9007dd7cddfSDavid du Colombier return q;
9017dd7cddfSDavid du Colombier }
9027dd7cddfSDavid du Colombier
9037dd7cddfSDavid du Colombier void
trans(Node * p)9047dd7cddfSDavid du Colombier trans(Node *p)
9057dd7cddfSDavid du Colombier { Node *op;
9067dd7cddfSDavid du Colombier Graph *g;
9077dd7cddfSDavid du Colombier
9087dd7cddfSDavid du Colombier if (!p || tl_errs) return;
9097dd7cddfSDavid du Colombier
9107dd7cddfSDavid du Colombier p = twocases(p);
9117dd7cddfSDavid du Colombier
9127dd7cddfSDavid du Colombier if (tl_verbose || tl_terse)
9137dd7cddfSDavid du Colombier { fprintf(tl_out, "\t/* Normlzd: ");
9147dd7cddfSDavid du Colombier dump(p);
9157dd7cddfSDavid du Colombier fprintf(tl_out, " */\n");
9167dd7cddfSDavid du Colombier }
9177dd7cddfSDavid du Colombier if (tl_terse)
9187dd7cddfSDavid du Colombier return;
9197dd7cddfSDavid du Colombier
9207dd7cddfSDavid du Colombier op = dupnode(p);
9217dd7cddfSDavid du Colombier
9227dd7cddfSDavid du Colombier ng(ZS, getsym(tl_lookup("init")), p, ZN, ZN);
923312a1df1SDavid du Colombier while ((g = Nodes_Stack) != (Graph *) 0)
9247dd7cddfSDavid du Colombier { Nodes_Stack = g->nxt;
925312a1df1SDavid du Colombier expand_g(g);
9267dd7cddfSDavid du Colombier }
9277dd7cddfSDavid du Colombier if (newstates)
9287dd7cddfSDavid du Colombier return;
9297dd7cddfSDavid du Colombier
9307dd7cddfSDavid du Colombier fixinit(p);
9317dd7cddfSDavid du Colombier liveness(flatten(op)); /* was: liveness(op); */
9327dd7cddfSDavid du Colombier
9337dd7cddfSDavid du Colombier mkbuchi();
9347dd7cddfSDavid du Colombier if (tl_verbose)
9357dd7cddfSDavid du Colombier { printf("/*\n");
9367dd7cddfSDavid du Colombier printf(" * %d states in Streett automaton\n", Base);
9377dd7cddfSDavid du Colombier printf(" * %d Streett acceptance conditions\n", Max_Red);
9387dd7cddfSDavid du Colombier printf(" * %d Buchi states\n", Total);
9397dd7cddfSDavid du Colombier printf(" */\n");
9407dd7cddfSDavid du Colombier }
9417dd7cddfSDavid du Colombier }
942