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.

344 lines
7.1 KiB

  1. /***** ltl2ba : cache.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. typedef struct Cache {
  33. Node *before;
  34. Node *after;
  35. int same;
  36. struct Cache *nxt;
  37. } Cache;
  38. static Cache *stored = (Cache *) 0;
  39. static unsigned long Caches, CacheHits;
  40. static int ismatch(Node *, Node *);
  41. extern void fatal(char *, char *);
  42. int sameform(Node *, Node *);
  43. void
  44. cache_dump(void)
  45. { Cache *d; int nr=0;
  46. printf("\nCACHE DUMP:\n");
  47. for (d = stored; d; d = d->nxt, nr++)
  48. { if (d->same) continue;
  49. printf("B%3d: ", nr); dump(d->before); printf("\n");
  50. printf("A%3d: ", nr); dump(d->after); printf("\n");
  51. }
  52. printf("============\n");
  53. }
  54. Node *
  55. in_cache(Node *n)
  56. { Cache *d; int nr=0;
  57. for (d = stored; d; d = d->nxt, nr++)
  58. if (isequal(d->before, n))
  59. { CacheHits++;
  60. if (d->same && ismatch(n, d->before)) return n;
  61. return dupnode(d->after);
  62. }
  63. return ZN;
  64. }
  65. Node *
  66. cached(Node *n)
  67. { Cache *d;
  68. Node *m;
  69. if (!n) return n;
  70. if (m = in_cache(n))
  71. return m;
  72. Caches++;
  73. d = (Cache *) tl_emalloc(sizeof(Cache));
  74. d->before = dupnode(n);
  75. d->after = Canonical(n); /* n is released */
  76. if (ismatch(d->before, d->after))
  77. { d->same = 1;
  78. releasenode(1, d->after);
  79. d->after = d->before;
  80. }
  81. d->nxt = stored;
  82. stored = d;
  83. return dupnode(d->after);
  84. }
  85. void
  86. cache_stats(void)
  87. {
  88. printf("cache stores : %9ld\n", Caches);
  89. printf("cache hits : %9ld\n", CacheHits);
  90. }
  91. void
  92. releasenode(int all_levels, Node *n)
  93. {
  94. if (!n) return;
  95. if (all_levels)
  96. { releasenode(1, n->lft);
  97. n->lft = ZN;
  98. releasenode(1, n->rgt);
  99. n->rgt = ZN;
  100. }
  101. tfree((void *) n);
  102. }
  103. Node *
  104. tl_nn(int t, Node *ll, Node *rl)
  105. { Node *n = (Node *) tl_emalloc(sizeof(Node));
  106. n->ntyp = (short) t;
  107. n->lft = ll;
  108. n->rgt = rl;
  109. return n;
  110. }
  111. Node *
  112. getnode(Node *p)
  113. { Node *n;
  114. if (!p) return p;
  115. n = (Node *) tl_emalloc(sizeof(Node));
  116. n->ntyp = p->ntyp;
  117. n->sym = p->sym; /* same name */
  118. n->lft = p->lft;
  119. n->rgt = p->rgt;
  120. return n;
  121. }
  122. Node *
  123. dupnode(Node *n)
  124. { Node *d;
  125. if (!n) return n;
  126. d = getnode(n);
  127. d->lft = dupnode(n->lft);
  128. d->rgt = dupnode(n->rgt);
  129. return d;
  130. }
  131. int
  132. one_lft(int ntyp, Node *x, Node *in)
  133. {
  134. if (!x) return 1;
  135. if (!in) return 0;
  136. if (sameform(x, in))
  137. return 1;
  138. if (in->ntyp != ntyp)
  139. return 0;
  140. if (one_lft(ntyp, x, in->lft))
  141. return 1;
  142. return one_lft(ntyp, x, in->rgt);
  143. }
  144. int
  145. all_lfts(int ntyp, Node *from, Node *in)
  146. {
  147. if (!from) return 1;
  148. if (from->ntyp != ntyp)
  149. return one_lft(ntyp, from, in);
  150. if (!one_lft(ntyp, from->lft, in))
  151. return 0;
  152. return all_lfts(ntyp, from->rgt, in);
  153. }
  154. int
  155. sametrees(int ntyp, Node *a, Node *b)
  156. { /* toplevel is an AND or OR */
  157. /* both trees are right-linked, but the leafs */
  158. /* can be in different places in the two trees */
  159. if (!all_lfts(ntyp, a, b))
  160. return 0;
  161. return all_lfts(ntyp, b, a);
  162. }
  163. int /* a better isequal() */
  164. sameform(Node *a, Node *b)
  165. {
  166. if (!a && !b) return 1;
  167. if (!a || !b) return 0;
  168. if (a->ntyp != b->ntyp) return 0;
  169. if (a->sym
  170. && b->sym
  171. && strcmp(a->sym->name, b->sym->name) != 0)
  172. return 0;
  173. switch (a->ntyp) {
  174. case TRUE:
  175. case FALSE:
  176. return 1;
  177. case PREDICATE:
  178. if (!a->sym || !b->sym) fatal("sameform...", (char *) 0);
  179. return !strcmp(a->sym->name, b->sym->name);
  180. case NOT:
  181. #ifdef NXT
  182. case NEXT:
  183. #endif
  184. return sameform(a->lft, b->lft);
  185. case U_OPER:
  186. case V_OPER:
  187. if (!sameform(a->lft, b->lft))
  188. return 0;
  189. if (!sameform(a->rgt, b->rgt))
  190. return 0;
  191. return 1;
  192. case AND:
  193. case OR: /* the hard case */
  194. return sametrees(a->ntyp, a, b);
  195. default:
  196. printf("type: %d\n", a->ntyp);
  197. fatal("cannot happen, sameform", (char *) 0);
  198. }
  199. return 0;
  200. }
  201. int
  202. isequal(Node *a, Node *b)
  203. {
  204. if (!a && !b)
  205. return 1;
  206. if (!a || !b)
  207. { if (!a)
  208. { if (b->ntyp == TRUE)
  209. return 1;
  210. } else
  211. { if (a->ntyp == TRUE)
  212. return 1;
  213. }
  214. return 0;
  215. }
  216. if (a->ntyp != b->ntyp)
  217. return 0;
  218. if (a->sym
  219. && b->sym
  220. && strcmp(a->sym->name, b->sym->name) != 0)
  221. return 0;
  222. if (isequal(a->lft, b->lft)
  223. && isequal(a->rgt, b->rgt))
  224. return 1;
  225. return sameform(a, b);
  226. }
  227. static int
  228. ismatch(Node *a, Node *b)
  229. {
  230. if (!a && !b) return 1;
  231. if (!a || !b) return 0;
  232. if (a->ntyp != b->ntyp) return 0;
  233. if (a->sym
  234. && b->sym
  235. && strcmp(a->sym->name, b->sym->name) != 0)
  236. return 0;
  237. if (ismatch(a->lft, b->lft)
  238. && ismatch(a->rgt, b->rgt))
  239. return 1;
  240. return 0;
  241. }
  242. int
  243. any_term(Node *srch, Node *in)
  244. {
  245. if (!in) return 0;
  246. if (in->ntyp == AND)
  247. return any_term(srch, in->lft) ||
  248. any_term(srch, in->rgt);
  249. return isequal(in, srch);
  250. }
  251. int
  252. any_and(Node *srch, Node *in)
  253. {
  254. if (!in) return 0;
  255. if (srch->ntyp == AND)
  256. return any_and(srch->lft, in) &&
  257. any_and(srch->rgt, in);
  258. return any_term(srch, in);
  259. }
  260. int
  261. any_lor(Node *srch, Node *in)
  262. {
  263. if (!in) return 0;
  264. if (in->ntyp == OR)
  265. return any_lor(srch, in->lft) ||
  266. any_lor(srch, in->rgt);
  267. return isequal(in, srch);
  268. }
  269. int
  270. anywhere(int tok, Node *srch, Node *in)
  271. {
  272. if (!in) return 0;
  273. switch (tok) {
  274. case AND: return any_and(srch, in);
  275. case OR: return any_lor(srch, in);
  276. case 0: return any_term(srch, in);
  277. }
  278. fatal("cannot happen, anywhere", (char *) 0);
  279. return 0;
  280. }