tl_cache.c 5.7 KB

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