You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

356 lines
9.4 KiB

  1. /***** ltl2ba : main.c *****/
  2. /* Written by Denis Oddoux, LIAFA, France */
  3. /* Copyright (c) 2001 Denis Oddoux */
  4. /* Modified by Paul Gastin, LSV, France */
  5. /* Copyright (c) 2007 Paul Gastin */
  6. /* */
  7. /* This program is free software; you can redistribute it and/or modify */
  8. /* it under the terms of the GNU General Public License as published by */
  9. /* the Free Software Foundation; either version 2 of the License, or */
  10. /* (at your option) any later version. */
  11. /* */
  12. /* This program is distributed in the hope that it will be useful, */
  13. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  14. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  15. /* GNU General Public License for more details. */
  16. /* */
  17. /* You should have received a copy of the GNU General Public License */
  18. /* along with this program; if not, write to the Free Software */
  19. /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
  20. /* */
  21. /* Based on the translation algorithm by Gastin and Oddoux, */
  22. /* presented at the 13th International Conference on Computer Aided */
  23. /* Verification, CAV 2001, Paris, France. */
  24. /* Proceedings - LNCS 2102, pp. 53-65 */
  25. /* */
  26. /* Send bug-reports and/or questions to Paul Gastin */
  27. /* http://www.lsv.ens-cachan.fr/~gastin */
  28. /* */
  29. /* Some of the code in this file was taken from the Spin software */
  30. /* Written by Gerard J. Holzmann, Bell Laboratories, U.S.A. */
  31. #include "ltl2ba.h"
  32. FILE *tl_out;
  33. int tl_stats = 0; /* time and size stats */
  34. int tl_simp_log = 1; /* logical simplification */
  35. int tl_simp_diff = 1; /* automata simplification */
  36. int tl_simp_fly = 1; /* on the fly simplification */
  37. int tl_simp_scc = 1; /* use scc simplification */
  38. int tl_fjtofj = 1; /* 2eme fj */
  39. int tl_errs = 0;
  40. int tl_verbose = 0;
  41. int tl_terse = 0;
  42. unsigned long All_Mem = 0;
  43. static char uform[4096];
  44. static int hasuform=0, cnt=0;
  45. static char **ltl_file = (char **)0;
  46. static char **add_ltl = (char **)0;
  47. static char out1[64];
  48. static void tl_endstats(void);
  49. static void non_fatal(char *, char *);
  50. void
  51. alldone(int estatus)
  52. {
  53. if (strlen(out1) > 0)
  54. (void) unlink((const char *)out1);
  55. exit(estatus);
  56. }
  57. FILE *
  58. cpyfile(char *src, char *tgt)
  59. { FILE *inp, *out;
  60. char buf[1024];
  61. inp = fopen(src, "r");
  62. out = fopen(tgt, "w");
  63. if (!inp || !out)
  64. { printf("ltl2ba: cannot cp %s to %s\n", src, tgt);
  65. alldone(1);
  66. }
  67. while (fgets(buf, 1024, inp))
  68. fprintf(out, "%s", buf);
  69. fclose(inp);
  70. return out;
  71. }
  72. char *
  73. emalloc(int n)
  74. { char *tmp;
  75. if (!(tmp = (char *) malloc(n)))
  76. fatal("not enough memory", (char *)0);
  77. memset(tmp, 0, n);
  78. return tmp;
  79. }
  80. int
  81. tl_Getchar(void)
  82. {
  83. if (cnt < hasuform)
  84. return uform[cnt++];
  85. cnt++;
  86. return -1;
  87. }
  88. void
  89. put_uform(void)
  90. {
  91. fprintf(tl_out, "%s", uform);
  92. }
  93. void
  94. tl_UnGetchar(void)
  95. {
  96. if (cnt > 0) cnt--;
  97. }
  98. void
  99. usage(void)
  100. {
  101. printf("usage: ltl2ba [-flag] -f formula\n");
  102. printf(" or -F file\n");
  103. printf(" -f \"formula\"\ttranslate LTL ");
  104. printf("into never claim\n");
  105. printf(" -F file\tlike -f, but with the LTL ");
  106. printf("formula stored in a 1-line file\n");
  107. printf(" -d\t\tdisplay automata (D)escription at each step\n");
  108. printf(" -s\t\tcomputing time and automata sizes (S)tatistics\n");
  109. printf(" -l\t\tdisable (L)ogic formula simplification\n");
  110. printf(" -p\t\tdisable a-(P)osteriori simplification\n");
  111. printf(" -o\t\tdisable (O)n-the-fly simplification\n");
  112. printf(" -c\t\tdisable strongly (C)onnected components simplification\n");
  113. printf(" -a\t\tdisable trick in (A)ccepting conditions\n");
  114. alldone(1);
  115. }
  116. int
  117. tl_main(int argc, char *argv[])
  118. { int i;
  119. while (argc > 1 && argv[1][0] == '-')
  120. { switch (argv[1][1]) {
  121. case 'f': argc--; argv++;
  122. for (i = 0; i < argv[1][i]; i++)
  123. { if (argv[1][i] == '\t'
  124. || argv[1][i] == '\"'
  125. || argv[1][i] == '\n')
  126. argv[1][i] = ' ';
  127. }
  128. strcpy(uform, argv[1]);
  129. hasuform = strlen(uform);
  130. break;
  131. default : usage();
  132. }
  133. argc--; argv++;
  134. }
  135. if (hasuform == 0) usage();
  136. tl_parse();
  137. if (tl_stats) tl_endstats();
  138. return tl_errs;
  139. }
  140. int
  141. main(int argc, char *argv[])
  142. { int i;
  143. tl_out = stdout;
  144. while (argc > 1 && argv[1][0] == '-')
  145. { switch (argv[1][1]) {
  146. case 'F': ltl_file = (char **) (argv+2);
  147. argc--; argv++; break;
  148. case 'f': add_ltl = (char **) argv;
  149. argc--; argv++; break;
  150. case 'a': tl_fjtofj = 0; break;
  151. case 'c': tl_simp_scc = 0; break;
  152. case 'o': tl_simp_fly = 0; break;
  153. case 'p': tl_simp_diff = 0; break;
  154. case 'l': tl_simp_log = 0; break;
  155. case 'd': tl_verbose = 1; break;
  156. case 's': tl_stats = 1; break;
  157. default : usage(); break;
  158. }
  159. argc--, argv++;
  160. }
  161. if(!ltl_file && !add_ltl) usage();
  162. if (ltl_file)
  163. { char formula[4096];
  164. add_ltl = ltl_file-2; add_ltl[1][1] = 'f';
  165. if (!(tl_out = fopen(*ltl_file, "r")))
  166. { printf("ltl2ba: cannot open %s\n", *ltl_file);
  167. alldone(1);
  168. }
  169. fgets(formula, 4096, tl_out);
  170. fclose(tl_out);
  171. tl_out = stdout;
  172. *ltl_file = (char *) formula;
  173. }
  174. if (argc > 1)
  175. { char cmd[128], out2[64];
  176. strcpy(out1, "_tmp1_");
  177. strcpy(out2, "_tmp2_");
  178. tl_out = cpyfile(argv[1], out2);
  179. tl_main(2, add_ltl);
  180. fclose(tl_out);
  181. } else
  182. {
  183. if (argc > 0)
  184. exit(tl_main(2, add_ltl));
  185. usage();
  186. }
  187. }
  188. /* Subtract the `struct timeval' values X and Y, storing the result X-Y in RESULT.
  189. Return 1 if the difference is negative, otherwise 0. */
  190. int
  191. timeval_subtract (result, x, y)
  192. struct timeval *result, *x, *y;
  193. {
  194. if (x->tv_usec < y->tv_usec) {
  195. x->tv_usec += 1000000;
  196. x->tv_sec--;
  197. }
  198. /* Compute the time remaining to wait. tv_usec is certainly positive. */
  199. result->tv_sec = x->tv_sec - y->tv_sec;
  200. result->tv_usec = x->tv_usec - y->tv_usec;
  201. /* Return 1 if result is negative. */
  202. return x->tv_sec < y->tv_sec;
  203. }
  204. static void
  205. tl_endstats(void)
  206. { extern int Stack_mx;
  207. printf("\ntotal memory used: %9ld\n", All_Mem);
  208. /*printf("largest stack sze: %9d\n", Stack_mx);*/
  209. /*cache_stats();*/
  210. a_stats();
  211. }
  212. #define Binop(a) \
  213. fprintf(tl_out, "("); \
  214. dump(n->lft); \
  215. fprintf(tl_out, a); \
  216. dump(n->rgt); \
  217. fprintf(tl_out, ")")
  218. void
  219. dump(Node *n)
  220. {
  221. if (!n) return;
  222. switch(n->ntyp) {
  223. case OR: Binop(" || "); break;
  224. case AND: Binop(" && "); break;
  225. case U_OPER: Binop(" U "); break;
  226. case V_OPER: Binop(" V "); break;
  227. #ifdef NXT
  228. case NEXT:
  229. fprintf(tl_out, "X");
  230. fprintf(tl_out, " (");
  231. dump(n->lft);
  232. fprintf(tl_out, ")");
  233. break;
  234. #endif
  235. case NOT:
  236. fprintf(tl_out, "!");
  237. fprintf(tl_out, " (");
  238. dump(n->lft);
  239. fprintf(tl_out, ")");
  240. break;
  241. case FALSE:
  242. fprintf(tl_out, "false");
  243. break;
  244. case TRUE:
  245. fprintf(tl_out, "true");
  246. break;
  247. case PREDICATE:
  248. fprintf(tl_out, "(%s)", n->sym->name);
  249. break;
  250. case -1:
  251. fprintf(tl_out, " D ");
  252. break;
  253. default:
  254. printf("Unknown token: ");
  255. tl_explain(n->ntyp);
  256. break;
  257. }
  258. }
  259. void
  260. tl_explain(int n)
  261. {
  262. switch (n) {
  263. case ALWAYS: printf("[]"); break;
  264. case EVENTUALLY: printf("<>"); break;
  265. case IMPLIES: printf("->"); break;
  266. case EQUIV: printf("<->"); break;
  267. case PREDICATE: printf("predicate"); break;
  268. case OR: printf("||"); break;
  269. case AND: printf("&&"); break;
  270. case NOT: printf("!"); break;
  271. case U_OPER: printf("U"); break;
  272. case V_OPER: printf("V"); break;
  273. #ifdef NXT
  274. case NEXT: printf("X"); break;
  275. #endif
  276. case TRUE: printf("true"); break;
  277. case FALSE: printf("false"); break;
  278. case ';': printf("end of formula"); break;
  279. default: printf("%c", n); break;
  280. }
  281. }
  282. static void
  283. non_fatal(char *s1, char *s2)
  284. { extern int tl_yychar;
  285. int i;
  286. printf("ltl2ba: ");
  287. if (s2)
  288. printf(s1, s2);
  289. else
  290. printf(s1);
  291. if (tl_yychar != -1 && tl_yychar != 0)
  292. { printf(", saw '");
  293. tl_explain(tl_yychar);
  294. printf("'");
  295. }
  296. printf("\nltl2ba: %s\n---------", uform);
  297. for (i = 0; i < cnt; i++)
  298. printf("-");
  299. printf("^\n");
  300. fflush(stdout);
  301. tl_errs++;
  302. }
  303. void
  304. tl_yyerror(char *s1)
  305. {
  306. Fatal(s1, (char *) 0);
  307. }
  308. void
  309. Fatal(char *s1, char *s2)
  310. {
  311. non_fatal(s1, s2);
  312. alldone(1);
  313. }
  314. void
  315. fatal(char *s1, char *s2)
  316. {
  317. non_fatal(s1, s2);
  318. alldone(1);
  319. }