17dd7cddfSDavid du Colombier /***** tl_spin: tl_main.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;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier int newstates = 0; /* debugging only */
207dd7cddfSDavid du Colombier int tl_errs = 0;
217dd7cddfSDavid du Colombier int tl_verbose = 0;
227dd7cddfSDavid du Colombier int tl_terse = 0;
237dd7cddfSDavid du Colombier int tl_clutter = 0;
24*00d97012SDavid du Colombier int state_cnt = 0;
25*00d97012SDavid du Colombier
267dd7cddfSDavid du Colombier unsigned long All_Mem = 0;
27*00d97012SDavid du Colombier char *claim_name;
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier static char uform[4096];
307dd7cddfSDavid du Colombier static int hasuform=0, cnt=0;
317dd7cddfSDavid du Colombier
32312a1df1SDavid du Colombier extern void cache_stats(void);
33312a1df1SDavid du Colombier extern void a_stats(void);
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier int
tl_Getchar(void)367dd7cddfSDavid du Colombier tl_Getchar(void)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier if (cnt < hasuform)
397dd7cddfSDavid du Colombier return uform[cnt++];
407dd7cddfSDavid du Colombier cnt++;
417dd7cddfSDavid du Colombier return -1;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier
44*00d97012SDavid du Colombier int
tl_peek(int n)45*00d97012SDavid du Colombier tl_peek(int n)
46*00d97012SDavid du Colombier {
47*00d97012SDavid du Colombier if (cnt+n < hasuform)
48*00d97012SDavid du Colombier { return uform[cnt+n];
49*00d97012SDavid du Colombier }
50*00d97012SDavid du Colombier return -1;
51*00d97012SDavid du Colombier }
52*00d97012SDavid du Colombier
537dd7cddfSDavid du Colombier void
tl_balanced(void)54f3793cddSDavid du Colombier tl_balanced(void)
55f3793cddSDavid du Colombier { int i;
56f3793cddSDavid du Colombier int k = 0;
57f3793cddSDavid du Colombier
58f3793cddSDavid du Colombier for (i = 0; i < hasuform; i++)
59f3793cddSDavid du Colombier { if (uform[i] == '(')
60f3793cddSDavid du Colombier { k++;
61f3793cddSDavid du Colombier } else if (uform[i] == ')')
62f3793cddSDavid du Colombier { k--;
63f3793cddSDavid du Colombier } }
64f3793cddSDavid du Colombier if (k != 0)
65f3793cddSDavid du Colombier { tl_errs++;
66f3793cddSDavid du Colombier tl_yyerror("parentheses not balanced");
67f3793cddSDavid du Colombier }
68f3793cddSDavid du Colombier }
69f3793cddSDavid du Colombier
70f3793cddSDavid du Colombier void
put_uform(void)717dd7cddfSDavid du Colombier put_uform(void)
727dd7cddfSDavid du Colombier {
737dd7cddfSDavid du Colombier fprintf(tl_out, "%s", uform);
747dd7cddfSDavid du Colombier }
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier void
tl_UnGetchar(void)777dd7cddfSDavid du Colombier tl_UnGetchar(void)
787dd7cddfSDavid du Colombier {
797dd7cddfSDavid du Colombier if (cnt > 0) cnt--;
807dd7cddfSDavid du Colombier }
817dd7cddfSDavid du Colombier
82312a1df1SDavid du Colombier static void
tl_stats(void)83312a1df1SDavid du Colombier tl_stats(void)
84312a1df1SDavid du Colombier { extern int Stack_mx;
85312a1df1SDavid du Colombier printf("total memory used: %9ld\n", All_Mem);
86312a1df1SDavid du Colombier printf("largest stack sze: %9d\n", Stack_mx);
87312a1df1SDavid du Colombier cache_stats();
88312a1df1SDavid du Colombier a_stats();
89312a1df1SDavid du Colombier }
90312a1df1SDavid du Colombier
917dd7cddfSDavid du Colombier int
tl_main(int argc,char * argv[])927dd7cddfSDavid du Colombier tl_main(int argc, char *argv[])
937dd7cddfSDavid du Colombier { int i;
94*00d97012SDavid du Colombier extern int /* verbose, */ xspin;
95*00d97012SDavid du Colombier
96*00d97012SDavid du Colombier tl_verbose = 0; /* was: tl_verbose = verbose; */
977dd7cddfSDavid du Colombier tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */
987dd7cddfSDavid du Colombier
99*00d97012SDavid du Colombier newstates = 0;
100*00d97012SDavid du Colombier state_cnt = 0;
101*00d97012SDavid du Colombier tl_errs = 0;
102*00d97012SDavid du Colombier tl_terse = 0;
103*00d97012SDavid du Colombier All_Mem = 0;
104*00d97012SDavid du Colombier memset(uform, 0, sizeof(uform));
105*00d97012SDavid du Colombier hasuform=0;
106*00d97012SDavid du Colombier cnt=0;
107*00d97012SDavid du Colombier claim_name = (char *) 0;
108*00d97012SDavid du Colombier
109*00d97012SDavid du Colombier ini_buchi();
110*00d97012SDavid du Colombier ini_cache();
111*00d97012SDavid du Colombier ini_rewrt();
112*00d97012SDavid du Colombier ini_trans();
113*00d97012SDavid du Colombier
1147dd7cddfSDavid du Colombier while (argc > 1 && argv[1][0] == '-')
115*00d97012SDavid du Colombier {
116*00d97012SDavid du Colombier switch (argv[1][1]) {
1177dd7cddfSDavid du Colombier case 'd': newstates = 1; /* debugging mode */
1187dd7cddfSDavid du Colombier break;
1197dd7cddfSDavid du Colombier case 'f': argc--; argv++;
120*00d97012SDavid du Colombier for (i = 0; argv[1][i]; i++)
1217dd7cddfSDavid du Colombier { if (argv[1][i] == '\t'
1227dd7cddfSDavid du Colombier || argv[1][i] == '\"'
1237dd7cddfSDavid du Colombier || argv[1][i] == '\n')
1247dd7cddfSDavid du Colombier argv[1][i] = ' ';
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier strcpy(uform, argv[1]);
127312a1df1SDavid du Colombier hasuform = (int) strlen(uform);
1287dd7cddfSDavid du Colombier break;
1297dd7cddfSDavid du Colombier case 'v': tl_verbose++;
1307dd7cddfSDavid du Colombier break;
1317dd7cddfSDavid du Colombier case 'n': tl_terse = 1;
1327dd7cddfSDavid du Colombier break;
133*00d97012SDavid du Colombier case 'c': argc--; argv++;
134*00d97012SDavid du Colombier claim_name = (char *) emalloc(strlen(argv[1])+1);
135*00d97012SDavid du Colombier strcpy(claim_name, argv[1]);
136*00d97012SDavid du Colombier break;
1377dd7cddfSDavid du Colombier default : printf("spin -f: saw '-%c'\n", argv[1][1]);
1387dd7cddfSDavid du Colombier goto nogood;
1397dd7cddfSDavid du Colombier }
1407dd7cddfSDavid du Colombier argc--; argv++;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier if (hasuform == 0)
1437dd7cddfSDavid du Colombier {
1447dd7cddfSDavid du Colombier nogood: printf("usage:\tspin [-v] [-n] -f formula\n");
1457dd7cddfSDavid du Colombier printf(" -v verbose translation\n");
1467dd7cddfSDavid du Colombier printf(" -n normalize tl formula and exit\n");
1477dd7cddfSDavid du Colombier exit(1);
1487dd7cddfSDavid du Colombier }
149f3793cddSDavid du Colombier tl_balanced();
150f3793cddSDavid du Colombier
151f3793cddSDavid du Colombier if (tl_errs == 0)
1527dd7cddfSDavid du Colombier tl_parse();
153f3793cddSDavid du Colombier
1547dd7cddfSDavid du Colombier if (tl_verbose) tl_stats();
1557dd7cddfSDavid du Colombier return tl_errs;
1567dd7cddfSDavid du Colombier }
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier #define Binop(a) \
1597dd7cddfSDavid du Colombier fprintf(tl_out, "("); \
1607dd7cddfSDavid du Colombier dump(n->lft); \
1617dd7cddfSDavid du Colombier fprintf(tl_out, a); \
1627dd7cddfSDavid du Colombier dump(n->rgt); \
1637dd7cddfSDavid du Colombier fprintf(tl_out, ")")
1647dd7cddfSDavid du Colombier
1657dd7cddfSDavid du Colombier void
dump(Node * n)1667dd7cddfSDavid du Colombier dump(Node *n)
1677dd7cddfSDavid du Colombier {
1687dd7cddfSDavid du Colombier if (!n) return;
1697dd7cddfSDavid du Colombier
1707dd7cddfSDavid du Colombier switch(n->ntyp) {
1717dd7cddfSDavid du Colombier case OR: Binop(" || "); break;
1727dd7cddfSDavid du Colombier case AND: Binop(" && "); break;
1737dd7cddfSDavid du Colombier case U_OPER: Binop(" U "); break;
1747dd7cddfSDavid du Colombier case V_OPER: Binop(" V "); break;
1757dd7cddfSDavid du Colombier #ifdef NXT
1767dd7cddfSDavid du Colombier case NEXT:
1777dd7cddfSDavid du Colombier fprintf(tl_out, "X");
1787dd7cddfSDavid du Colombier fprintf(tl_out, " (");
1797dd7cddfSDavid du Colombier dump(n->lft);
1807dd7cddfSDavid du Colombier fprintf(tl_out, ")");
1817dd7cddfSDavid du Colombier break;
1827dd7cddfSDavid du Colombier #endif
1837dd7cddfSDavid du Colombier case NOT:
1847dd7cddfSDavid du Colombier fprintf(tl_out, "!");
1857dd7cddfSDavid du Colombier fprintf(tl_out, " (");
1867dd7cddfSDavid du Colombier dump(n->lft);
1877dd7cddfSDavid du Colombier fprintf(tl_out, ")");
1887dd7cddfSDavid du Colombier break;
1897dd7cddfSDavid du Colombier case FALSE:
1907dd7cddfSDavid du Colombier fprintf(tl_out, "false");
1917dd7cddfSDavid du Colombier break;
1927dd7cddfSDavid du Colombier case TRUE:
1937dd7cddfSDavid du Colombier fprintf(tl_out, "true");
1947dd7cddfSDavid du Colombier break;
1957dd7cddfSDavid du Colombier case PREDICATE:
1967dd7cddfSDavid du Colombier fprintf(tl_out, "(%s)", n->sym->name);
1977dd7cddfSDavid du Colombier break;
1987dd7cddfSDavid du Colombier case -1:
1997dd7cddfSDavid du Colombier fprintf(tl_out, " D ");
2007dd7cddfSDavid du Colombier break;
2017dd7cddfSDavid du Colombier default:
2027dd7cddfSDavid du Colombier printf("Unknown token: ");
2037dd7cddfSDavid du Colombier tl_explain(n->ntyp);
2047dd7cddfSDavid du Colombier break;
2057dd7cddfSDavid du Colombier }
2067dd7cddfSDavid du Colombier }
2077dd7cddfSDavid du Colombier
2087dd7cddfSDavid du Colombier void
tl_explain(int n)2097dd7cddfSDavid du Colombier tl_explain(int n)
2107dd7cddfSDavid du Colombier {
2117dd7cddfSDavid du Colombier switch (n) {
2127dd7cddfSDavid du Colombier case ALWAYS: printf("[]"); break;
2137dd7cddfSDavid du Colombier case EVENTUALLY: printf("<>"); break;
2147dd7cddfSDavid du Colombier case IMPLIES: printf("->"); break;
2157dd7cddfSDavid du Colombier case EQUIV: printf("<->"); break;
2167dd7cddfSDavid du Colombier case PREDICATE: printf("predicate"); break;
2177dd7cddfSDavid du Colombier case OR: printf("||"); break;
2187dd7cddfSDavid du Colombier case AND: printf("&&"); break;
2197dd7cddfSDavid du Colombier case NOT: printf("!"); break;
2207dd7cddfSDavid du Colombier case U_OPER: printf("U"); break;
2217dd7cddfSDavid du Colombier case V_OPER: printf("V"); break;
2227dd7cddfSDavid du Colombier #ifdef NXT
2237dd7cddfSDavid du Colombier case NEXT: printf("X"); break;
2247dd7cddfSDavid du Colombier #endif
2257dd7cddfSDavid du Colombier case TRUE: printf("true"); break;
2267dd7cddfSDavid du Colombier case FALSE: printf("false"); break;
2277dd7cddfSDavid du Colombier case ';': printf("end of formula"); break;
2287dd7cddfSDavid du Colombier default: printf("%c", n); break;
2297dd7cddfSDavid du Colombier }
2307dd7cddfSDavid du Colombier }
2317dd7cddfSDavid du Colombier
2327dd7cddfSDavid du Colombier static void
tl_non_fatal(char * s1,char * s2)233312a1df1SDavid du Colombier tl_non_fatal(char *s1, char *s2)
2347dd7cddfSDavid du Colombier { extern int tl_yychar;
2357dd7cddfSDavid du Colombier int i;
2367dd7cddfSDavid du Colombier
2377dd7cddfSDavid du Colombier printf("tl_spin: ");
2387dd7cddfSDavid du Colombier if (s2)
2397dd7cddfSDavid du Colombier printf(s1, s2);
2407dd7cddfSDavid du Colombier else
2417dd7cddfSDavid du Colombier printf(s1);
2427dd7cddfSDavid du Colombier if (tl_yychar != -1 && tl_yychar != 0)
2437dd7cddfSDavid du Colombier { printf(", saw '");
2447dd7cddfSDavid du Colombier tl_explain(tl_yychar);
2457dd7cddfSDavid du Colombier printf("'");
2467dd7cddfSDavid du Colombier }
2477dd7cddfSDavid du Colombier printf("\ntl_spin: %s\n---------", uform);
2487dd7cddfSDavid du Colombier for (i = 0; i < cnt; i++)
2497dd7cddfSDavid du Colombier printf("-");
2507dd7cddfSDavid du Colombier printf("^\n");
2517dd7cddfSDavid du Colombier fflush(stdout);
2527dd7cddfSDavid du Colombier tl_errs++;
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier
2557dd7cddfSDavid du Colombier void
tl_yyerror(char * s1)2567dd7cddfSDavid du Colombier tl_yyerror(char *s1)
2577dd7cddfSDavid du Colombier {
2587dd7cddfSDavid du Colombier Fatal(s1, (char *) 0);
2597dd7cddfSDavid du Colombier }
2607dd7cddfSDavid du Colombier
2617dd7cddfSDavid du Colombier void
Fatal(char * s1,char * s2)2627dd7cddfSDavid du Colombier Fatal(char *s1, char *s2)
2637dd7cddfSDavid du Colombier {
264312a1df1SDavid du Colombier tl_non_fatal(s1, s2);
2657dd7cddfSDavid du Colombier /* tl_stats(); */
2667dd7cddfSDavid du Colombier exit(1);
2677dd7cddfSDavid du Colombier }
268