tl_parse.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /***** tl_spin: tl_parse.c *****/
  10. /* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */
  11. /* All Rights Reserved. This software is for educational purposes only. */
  12. /* No guarantee whatsoever is expressed or implied by the distribution of */
  13. /* this code. Permission is given to distribute this code provided that */
  14. /* this introductory message is not removed and no monies are exchanged. */
  15. /* Software written by Gerard J. Holzmann. For tool documentation see: */
  16. /* http://spinroot.com/ */
  17. /* Send all bug-reports and/or questions to: bugs@spinroot.com */
  18. /* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */
  19. /* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */
  20. #include "tl.h"
  21. extern int tl_yylex(void);
  22. extern int tl_verbose, tl_errs;
  23. int tl_yychar = 0;
  24. YYSTYPE tl_yylval;
  25. static Node *tl_formula(void);
  26. static Node *tl_factor(void);
  27. static Node *tl_level(int);
  28. static int prec[2][4] = {
  29. { U_OPER, V_OPER, 0, 0 }, /* left associative */
  30. { OR, AND, IMPLIES, EQUIV, }, /* left associative */
  31. };
  32. static Node *
  33. tl_factor(void)
  34. { Node *ptr = ZN;
  35. switch (tl_yychar) {
  36. case '(':
  37. ptr = tl_formula();
  38. if (tl_yychar != ')')
  39. tl_yyerror("expected ')'");
  40. tl_yychar = tl_yylex();
  41. break;
  42. case NOT:
  43. ptr = tl_yylval;
  44. tl_yychar = tl_yylex();
  45. ptr->lft = tl_factor();
  46. ptr = push_negation(ptr);
  47. break;
  48. case ALWAYS:
  49. tl_yychar = tl_yylex();
  50. ptr = tl_factor();
  51. #ifndef NO_OPT
  52. if (ptr->ntyp == FALSE
  53. || ptr->ntyp == TRUE)
  54. break; /* [] false == false */
  55. if (ptr->ntyp == V_OPER)
  56. { if (ptr->lft->ntyp == FALSE)
  57. break; /* [][]p = []p */
  58. ptr = ptr->rgt; /* [] (p V q) = [] q */
  59. }
  60. #endif
  61. ptr = tl_nn(V_OPER, False, ptr);
  62. break;
  63. #ifdef NXT
  64. case NEXT:
  65. tl_yychar = tl_yylex();
  66. ptr = tl_factor();
  67. if (ptr->ntyp == TRUE)
  68. break; /* X true = true */
  69. ptr = tl_nn(NEXT, ptr, ZN);
  70. break;
  71. #endif
  72. case EVENTUALLY:
  73. tl_yychar = tl_yylex();
  74. ptr = tl_factor();
  75. #ifndef NO_OPT
  76. if (ptr->ntyp == TRUE
  77. || ptr->ntyp == FALSE)
  78. break; /* <> true == true */
  79. if (ptr->ntyp == U_OPER
  80. && ptr->lft->ntyp == TRUE)
  81. break; /* <><>p = <>p */
  82. if (ptr->ntyp == U_OPER)
  83. { /* <> (p U q) = <> q */
  84. ptr = ptr->rgt;
  85. /* fall thru */
  86. }
  87. #endif
  88. ptr = tl_nn(U_OPER, True, ptr);
  89. break;
  90. case PREDICATE:
  91. ptr = tl_yylval;
  92. tl_yychar = tl_yylex();
  93. break;
  94. case TRUE:
  95. case FALSE:
  96. ptr = tl_yylval;
  97. tl_yychar = tl_yylex();
  98. break;
  99. }
  100. if (!ptr) tl_yyerror("expected predicate");
  101. #if 0
  102. printf("factor: ");
  103. tl_explain(ptr->ntyp);
  104. printf("\n");
  105. #endif
  106. return ptr;
  107. }
  108. static Node *
  109. bin_simpler(Node *ptr)
  110. { Node *a, *b;
  111. if (ptr)
  112. switch (ptr->ntyp) {
  113. case U_OPER:
  114. #ifndef NO_OPT
  115. if (ptr->rgt->ntyp == TRUE
  116. || ptr->rgt->ntyp == FALSE
  117. || ptr->lft->ntyp == FALSE)
  118. { ptr = ptr->rgt;
  119. break;
  120. }
  121. if (isequal(ptr->lft, ptr->rgt))
  122. { /* p U p = p */
  123. ptr = ptr->rgt;
  124. break;
  125. }
  126. if (ptr->lft->ntyp == U_OPER
  127. && isequal(ptr->lft->lft, ptr->rgt))
  128. { /* (p U q) U p = (q U p) */
  129. ptr->lft = ptr->lft->rgt;
  130. break;
  131. }
  132. if (ptr->rgt->ntyp == U_OPER
  133. && ptr->rgt->lft->ntyp == TRUE)
  134. { /* p U (T U q) = (T U q) */
  135. ptr = ptr->rgt;
  136. break;
  137. }
  138. #ifdef NXT
  139. /* X p U X q == X (p U q) */
  140. if (ptr->rgt->ntyp == NEXT
  141. && ptr->lft->ntyp == NEXT)
  142. { ptr = tl_nn(NEXT,
  143. tl_nn(U_OPER,
  144. ptr->lft->lft,
  145. ptr->rgt->lft), ZN);
  146. }
  147. #endif
  148. #endif
  149. break;
  150. case V_OPER:
  151. #ifndef NO_OPT
  152. if (ptr->rgt->ntyp == FALSE
  153. || ptr->rgt->ntyp == TRUE
  154. || ptr->lft->ntyp == TRUE)
  155. { ptr = ptr->rgt;
  156. break;
  157. }
  158. if (isequal(ptr->lft, ptr->rgt))
  159. { /* p V p = p */
  160. ptr = ptr->rgt;
  161. break;
  162. }
  163. /* F V (p V q) == F V q */
  164. if (ptr->lft->ntyp == FALSE
  165. && ptr->rgt->ntyp == V_OPER)
  166. { ptr->rgt = ptr->rgt->rgt;
  167. break;
  168. }
  169. /* p V (F V q) == F V q */
  170. if (ptr->rgt->ntyp == V_OPER
  171. && ptr->rgt->lft->ntyp == FALSE)
  172. { ptr->lft = False;
  173. ptr->rgt = ptr->rgt->rgt;
  174. break;
  175. }
  176. #endif
  177. break;
  178. case IMPLIES:
  179. #ifndef NO_OPT
  180. if (isequal(ptr->lft, ptr->rgt))
  181. { ptr = True;
  182. break;
  183. }
  184. #endif
  185. ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt);
  186. ptr = rewrite(ptr);
  187. break;
  188. case EQUIV:
  189. #ifndef NO_OPT
  190. if (isequal(ptr->lft, ptr->rgt))
  191. { ptr = True;
  192. break;
  193. }
  194. #endif
  195. a = rewrite(tl_nn(AND,
  196. dupnode(ptr->lft),
  197. dupnode(ptr->rgt)));
  198. b = rewrite(tl_nn(AND,
  199. Not(ptr->lft),
  200. Not(ptr->rgt)));
  201. ptr = tl_nn(OR, a, b);
  202. ptr = rewrite(ptr);
  203. break;
  204. case AND:
  205. #ifndef NO_OPT
  206. /* p && (q U p) = p */
  207. if (ptr->rgt->ntyp == U_OPER
  208. && isequal(ptr->rgt->rgt, ptr->lft))
  209. { ptr = ptr->lft;
  210. break;
  211. }
  212. if (ptr->lft->ntyp == U_OPER
  213. && isequal(ptr->lft->rgt, ptr->rgt))
  214. { ptr = ptr->rgt;
  215. break;
  216. }
  217. /* p && (q V p) == q V p */
  218. if (ptr->rgt->ntyp == V_OPER
  219. && isequal(ptr->rgt->rgt, ptr->lft))
  220. { ptr = ptr->rgt;
  221. break;
  222. }
  223. if (ptr->lft->ntyp == V_OPER
  224. && isequal(ptr->lft->rgt, ptr->rgt))
  225. { ptr = ptr->lft;
  226. break;
  227. }
  228. /* (p U q) && (r U q) = (p && r) U q*/
  229. if (ptr->rgt->ntyp == U_OPER
  230. && ptr->lft->ntyp == U_OPER
  231. && isequal(ptr->rgt->rgt, ptr->lft->rgt))
  232. { ptr = tl_nn(U_OPER,
  233. tl_nn(AND, ptr->lft->lft, ptr->rgt->lft),
  234. ptr->lft->rgt);
  235. break;
  236. }
  237. /* (p V q) && (p V r) = p V (q && r) */
  238. if (ptr->rgt->ntyp == V_OPER
  239. && ptr->lft->ntyp == V_OPER
  240. && isequal(ptr->rgt->lft, ptr->lft->lft))
  241. { ptr = tl_nn(V_OPER,
  242. ptr->rgt->lft,
  243. tl_nn(AND, ptr->lft->rgt, ptr->rgt->rgt));
  244. break;
  245. }
  246. #ifdef NXT
  247. /* X p && X q == X (p && q) */
  248. if (ptr->rgt->ntyp == NEXT
  249. && ptr->lft->ntyp == NEXT)
  250. { ptr = tl_nn(NEXT,
  251. tl_nn(AND,
  252. ptr->rgt->lft,
  253. ptr->lft->lft), ZN);
  254. break;
  255. }
  256. #endif
  257. if (isequal(ptr->lft, ptr->rgt) /* (p && p) == p */
  258. || ptr->rgt->ntyp == FALSE /* (p && F) == F */
  259. || ptr->lft->ntyp == TRUE) /* (T && p) == p */
  260. { ptr = ptr->rgt;
  261. break;
  262. }
  263. if (ptr->rgt->ntyp == TRUE /* (p && T) == p */
  264. || ptr->lft->ntyp == FALSE) /* (F && p) == F */
  265. { ptr = ptr->lft;
  266. break;
  267. }
  268. /* (p V q) && (r U q) == p V q */
  269. if (ptr->rgt->ntyp == U_OPER
  270. && ptr->lft->ntyp == V_OPER
  271. && isequal(ptr->lft->rgt, ptr->rgt->rgt))
  272. { ptr = ptr->lft;
  273. break;
  274. }
  275. #endif
  276. break;
  277. case OR:
  278. #ifndef NO_OPT
  279. /* p || (q U p) == q U p */
  280. if (ptr->rgt->ntyp == U_OPER
  281. && isequal(ptr->rgt->rgt, ptr->lft))
  282. { ptr = ptr->rgt;
  283. break;
  284. }
  285. /* p || (q V p) == p */
  286. if (ptr->rgt->ntyp == V_OPER
  287. && isequal(ptr->rgt->rgt, ptr->lft))
  288. { ptr = ptr->lft;
  289. break;
  290. }
  291. /* (p U q) || (p U r) = p U (q || r) */
  292. if (ptr->rgt->ntyp == U_OPER
  293. && ptr->lft->ntyp == U_OPER
  294. && isequal(ptr->rgt->lft, ptr->lft->lft))
  295. { ptr = tl_nn(U_OPER,
  296. ptr->rgt->lft,
  297. tl_nn(OR, ptr->lft->rgt, ptr->rgt->rgt));
  298. break;
  299. }
  300. if (isequal(ptr->lft, ptr->rgt) /* (p || p) == p */
  301. || ptr->rgt->ntyp == FALSE /* (p || F) == p */
  302. || ptr->lft->ntyp == TRUE) /* (T || p) == T */
  303. { ptr = ptr->lft;
  304. break;
  305. }
  306. if (ptr->rgt->ntyp == TRUE /* (p || T) == T */
  307. || ptr->lft->ntyp == FALSE) /* (F || p) == p */
  308. { ptr = ptr->rgt;
  309. break;
  310. }
  311. /* (p V q) || (r V q) = (p || r) V q */
  312. if (ptr->rgt->ntyp == V_OPER
  313. && ptr->lft->ntyp == V_OPER
  314. && isequal(ptr->lft->rgt, ptr->rgt->rgt))
  315. { ptr = tl_nn(V_OPER,
  316. tl_nn(OR, ptr->lft->lft, ptr->rgt->lft),
  317. ptr->rgt->rgt);
  318. break;
  319. }
  320. /* (p V q) || (r U q) == r U q */
  321. if (ptr->rgt->ntyp == U_OPER
  322. && ptr->lft->ntyp == V_OPER
  323. && isequal(ptr->lft->rgt, ptr->rgt->rgt))
  324. { ptr = ptr->rgt;
  325. break;
  326. }
  327. #endif
  328. break;
  329. }
  330. return ptr;
  331. }
  332. static Node *
  333. tl_level(int nr)
  334. { int i; Node *ptr = ZN;
  335. if (nr < 0)
  336. return tl_factor();
  337. ptr = tl_level(nr-1);
  338. again:
  339. for (i = 0; i < 4; i++)
  340. if (tl_yychar == prec[nr][i])
  341. { tl_yychar = tl_yylex();
  342. ptr = tl_nn(prec[nr][i],
  343. ptr, tl_level(nr-1));
  344. ptr = bin_simpler(ptr);
  345. goto again;
  346. }
  347. if (!ptr) tl_yyerror("syntax error");
  348. #if 0
  349. printf("level %d: ", nr);
  350. tl_explain(ptr->ntyp);
  351. printf("\n");
  352. #endif
  353. return ptr;
  354. }
  355. static Node *
  356. tl_formula(void)
  357. { tl_yychar = tl_yylex();
  358. return tl_level(1); /* 2 precedence levels, 1 and 0 */
  359. }
  360. void
  361. tl_parse(void)
  362. { Node *n;
  363. /* tl_verbose = 1; */
  364. n = tl_formula();
  365. if (tl_verbose)
  366. { printf("formula: ");
  367. dump(n);
  368. printf("\n");
  369. }
  370. if (tl_Getchar() != -1)
  371. { tl_yyerror("syntax error");
  372. tl_errs++;
  373. return;
  374. }
  375. trans(n);
  376. }