tl_cache.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /***** tl_spin: tl_cache.c *****/
  2. /* Copyright (c) 1995-2000 by Lucent Technologies - Bell Laboratories */
  3. /* All Rights Reserved. This software is for educational purposes only. */
  4. /* Permission is given to distribute this code provided that this intro- */
  5. /* ductory message is not removed and no monies are exchanged. */
  6. /* No guarantee is expressed or implied by the distribution of this code. */
  7. /* Written by Gerard J. Holzmann, Bell Laboratories, U.S.A. */
  8. /* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */
  9. /* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */
  10. /* Send bug-reports and/or questions to: gerard@research.bell-labs.com */
  11. #include "tl.h"
  12. typedef struct Cache {
  13. Node *before;
  14. Node *after;
  15. int same;
  16. struct Cache *nxt;
  17. } Cache;
  18. static Cache *stored = (Cache *) 0;
  19. static unsigned long Caches, CacheHits;
  20. static int ismatch(Node *, Node *);
  21. extern void fatal(char *, char *);
  22. int sameform(Node *, Node *);
  23. void
  24. cache_dump(void)
  25. { Cache *d; int nr=0;
  26. printf("\nCACHE DUMP:\n");
  27. for (d = stored; d; d = d->nxt, nr++)
  28. { if (d->same) continue;
  29. printf("B%3d: ", nr); dump(d->before); printf("\n");
  30. printf("A%3d: ", nr); dump(d->after); printf("\n");
  31. }
  32. printf("============\n");
  33. }
  34. Node *
  35. in_cache(Node *n)
  36. { Cache *d; int nr=0;
  37. for (d = stored; d; d = d->nxt, nr++)
  38. if (isequal(d->before, n))
  39. { CacheHits++;
  40. if (d->same && ismatch(n, d->before)) return n;
  41. return dupnode(d->after);
  42. }
  43. return ZN;
  44. }
  45. Node *
  46. cached(Node *n)
  47. { Cache *d;
  48. Node *m;
  49. if (!n) return n;
  50. if (m = in_cache(n))
  51. return m;
  52. Caches++;
  53. d = (Cache *) tl_emalloc(sizeof(Cache));
  54. d->before = dupnode(n);
  55. d->after = Canonical(n); /* n is released */
  56. if (ismatch(d->before, d->after))
  57. { d->same = 1;
  58. releasenode(1, d->after);
  59. d->after = d->before;
  60. }
  61. d->nxt = stored;
  62. stored = d;
  63. return dupnode(d->after);
  64. }
  65. void
  66. cache_stats(void)
  67. {
  68. printf("cache stores : %9ld\n", Caches);
  69. printf("cache hits : %9ld\n", CacheHits);
  70. }
  71. void
  72. releasenode(int all_levels, Node *n)
  73. {
  74. if (!n) return;
  75. if (all_levels)
  76. { releasenode(1, n->lft);
  77. n->lft = ZN;
  78. releasenode(1, n->rgt);
  79. n->rgt = ZN;
  80. }
  81. tfree((void *) n);
  82. }
  83. Node *
  84. tl_nn(int t, Node *ll, Node *rl)
  85. { Node *n = (Node *) tl_emalloc(sizeof(Node));
  86. n->ntyp = (short) t;
  87. n->lft = ll;
  88. n->rgt = rl;
  89. return n;
  90. }
  91. Node *
  92. getnode(Node *p)
  93. { Node *n;
  94. if (!p) return p;
  95. n = (Node *) tl_emalloc(sizeof(Node));
  96. n->ntyp = p->ntyp;
  97. n->sym = p->sym; /* same name */
  98. n->lft = p->lft;
  99. n->rgt = p->rgt;
  100. return n;
  101. }
  102. Node *
  103. dupnode(Node *n)
  104. { Node *d;
  105. if (!n) return n;
  106. d = getnode(n);
  107. d->lft = dupnode(n->lft);
  108. d->rgt = dupnode(n->rgt);
  109. return d;
  110. }
  111. int
  112. one_lft(int ntyp, Node *x, Node *in)
  113. {
  114. if (!x) return 1;
  115. if (!in) return 0;
  116. if (sameform(x, in))
  117. return 1;
  118. if (in->ntyp != ntyp)
  119. return 0;
  120. if (one_lft(ntyp, x, in->lft))
  121. return 1;
  122. return one_lft(ntyp, x, in->rgt);
  123. }
  124. int
  125. all_lfts(int ntyp, Node *from, Node *in)
  126. {
  127. if (!from) return 1;
  128. if (from->ntyp != ntyp)
  129. return one_lft(ntyp, from, in);
  130. if (!one_lft(ntyp, from->lft, in))
  131. return 0;
  132. return all_lfts(ntyp, from->rgt, in);
  133. }
  134. int
  135. sametrees(int ntyp, Node *a, Node *b)
  136. { /* toplevel is an AND or OR */
  137. /* both trees are right-linked, but the leafs */
  138. /* can be in different places in the two trees */
  139. if (!all_lfts(ntyp, a, b))
  140. return 0;
  141. return all_lfts(ntyp, b, a);
  142. }
  143. int /* a better isequal() */
  144. sameform(Node *a, Node *b)
  145. {
  146. if (!a && !b) return 1;
  147. if (!a || !b) return 0;
  148. if (a->ntyp != b->ntyp) return 0;
  149. if (a->sym
  150. && b->sym
  151. && strcmp(a->sym->name, b->sym->name) != 0)
  152. return 0;
  153. switch (a->ntyp) {
  154. case TRUE:
  155. case FALSE:
  156. return 1;
  157. case PREDICATE:
  158. if (!a->sym || !b->sym) fatal("sameform...", (char *) 0);
  159. return !strcmp(a->sym->name, b->sym->name);
  160. case NOT:
  161. #ifdef NXT
  162. case NEXT:
  163. #endif
  164. return sameform(a->lft, b->lft);
  165. case U_OPER:
  166. case V_OPER:
  167. if (!sameform(a->lft, b->lft))
  168. return 0;
  169. if (!sameform(a->rgt, b->rgt))
  170. return 0;
  171. return 1;
  172. case AND:
  173. case OR: /* the hard case */
  174. return sametrees(a->ntyp, a, b);
  175. default:
  176. printf("type: %d\n", a->ntyp);
  177. fatal("cannot happen, sameform", (char *) 0);
  178. }
  179. return 0;
  180. }
  181. int
  182. isequal(Node *a, Node *b)
  183. {
  184. if (!a && !b)
  185. return 1;
  186. if (!a || !b)
  187. { if (!a)
  188. { if (b->ntyp == TRUE)
  189. return 1;
  190. } else
  191. { if (a->ntyp == TRUE)
  192. return 1;
  193. }
  194. return 0;
  195. }
  196. if (a->ntyp != b->ntyp)
  197. return 0;
  198. if (a->sym
  199. && b->sym
  200. && strcmp(a->sym->name, b->sym->name) != 0)
  201. return 0;
  202. if (isequal(a->lft, b->lft)
  203. && isequal(a->rgt, b->rgt))
  204. return 1;
  205. return sameform(a, b);
  206. }
  207. static int
  208. ismatch(Node *a, Node *b)
  209. {
  210. if (!a && !b) return 1;
  211. if (!a || !b) return 0;
  212. if (a->ntyp != b->ntyp) return 0;
  213. if (a->sym
  214. && b->sym
  215. && strcmp(a->sym->name, b->sym->name) != 0)
  216. return 0;
  217. if (ismatch(a->lft, b->lft)
  218. && ismatch(a->rgt, b->rgt))
  219. return 1;
  220. return 0;
  221. }
  222. int
  223. any_term(Node *srch, Node *in)
  224. {
  225. if (!in) return 0;
  226. if (in->ntyp == AND)
  227. return any_term(srch, in->lft) ||
  228. any_term(srch, in->rgt);
  229. return isequal(in, srch);
  230. }
  231. int
  232. any_and(Node *srch, Node *in)
  233. {
  234. if (!in) return 0;
  235. if (srch->ntyp == AND)
  236. return any_and(srch->lft, in) &&
  237. any_and(srch->rgt, in);
  238. return any_term(srch, in);
  239. }
  240. int
  241. any_lor(Node *srch, Node *in)
  242. {
  243. if (!in) return 0;
  244. if (in->ntyp == OR)
  245. return any_lor(srch, in->lft) ||
  246. any_lor(srch, in->rgt);
  247. return isequal(in, srch);
  248. }
  249. int
  250. anywhere(int tok, Node *srch, Node *in)
  251. {
  252. if (!in) return 0;
  253. switch (tok) {
  254. case AND: return any_and(srch, in);
  255. case OR: return any_lor(srch, in);
  256. case 0: return any_term(srch, in);
  257. }
  258. fatal("cannot happen, anywhere", (char *) 0);
  259. return 0;
  260. }