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.

209 lines
6.0 KiB

  1. /***** ltl2ba : set.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. #include "ltl2ba.h"
  29. extern FILE *tl_out;
  30. extern int node_size, sym_size, scc_size;
  31. extern char **sym_table;
  32. int mod = 8 * sizeof(int);
  33. /* type = 2 for scc set, 1 for symbol sets, 0 for nodes sets */
  34. #define set_size(t) (t==1?sym_size:(t==2?scc_size:node_size))
  35. int *new_set(int type) /* creates a new set */
  36. {
  37. return (int *)tl_emalloc(set_size(type) * sizeof(int));
  38. }
  39. int *clear_set(int *l, int type) /* clears the set */
  40. {
  41. int i;
  42. for(i = 0; i < set_size(type); i++) {
  43. l[i] = 0;
  44. }
  45. return l;
  46. }
  47. int *make_set(int n, int type) /* creates the set {n}, or the empty set if n = -1 */
  48. {
  49. int *l = clear_set(new_set(type), type);
  50. if(n == -1) return l;
  51. l[n/mod] = 1 << (n%mod);
  52. return l;
  53. }
  54. void copy_set(int *from, int *to, int type) /* copies a set */
  55. {
  56. int i;
  57. for(i = 0; i < set_size(type); i++)
  58. to[i] = from[i];
  59. }
  60. int *dup_set(int *l, int type) /* duplicates a set */
  61. {
  62. int i, *m = new_set(type);
  63. for(i = 0; i < set_size(type); i++)
  64. m[i] = l[i];
  65. return m;
  66. }
  67. void merge_sets(int *l1, int *l2, int type) /* puts the union of the two sets in l1 */
  68. {
  69. int i;
  70. for(i = 0; i < set_size(type); i++)
  71. l1[i] = l1[i] | l2[i];
  72. }
  73. void do_merge_sets(int *l, int *l1, int *l2, int type) /* makes the union of two sets */
  74. {
  75. int i;
  76. for(i = 0; i < set_size(type); i++)
  77. l[i] = l1[i] | l2[i];
  78. }
  79. int *intersect_sets(int *l1, int *l2, int type) /* makes the intersection of two sets */
  80. {
  81. int i, *l = new_set(type);
  82. for(i = 0; i < set_size(type); i++)
  83. l[i] = l1[i] & l2[i];
  84. return l;
  85. }
  86. int empty_intersect_sets(int *l1, int *l2, int type) /* tests intersection of two sets */
  87. {
  88. int i, test = 0;
  89. for(i = 0; i < set_size(type); i++)
  90. test |= l1[i] & l2[i];
  91. return !test;
  92. }
  93. void add_set(int *l, int n) /* adds an element to a set */
  94. {
  95. l[n/mod] |= 1 << (n%mod);
  96. }
  97. void rem_set(int *l, int n) /* removes an element from a set */
  98. {
  99. l[n/mod] &= (-1 - (1 << (n%mod)));
  100. }
  101. void spin_print_set(int *pos, int *neg) /* prints the content of a set for spin */
  102. {
  103. int i, j, start = 1;
  104. for(i = 0; i < sym_size; i++)
  105. for(j = 0; j < mod; j++) {
  106. if(pos[i] & (1 << j)) {
  107. if(!start)
  108. fprintf(tl_out, " && ");
  109. fprintf(tl_out, "%s", sym_table[mod * i + j]);
  110. start = 0;
  111. }
  112. if(neg[i] & (1 << j)) {
  113. if(!start)
  114. fprintf(tl_out, " && ");
  115. fprintf(tl_out, "!%s", sym_table[mod * i + j]);
  116. start = 0;
  117. }
  118. }
  119. if(start)
  120. fprintf(tl_out, "1");
  121. }
  122. void print_set(int *l, int type) /* prints the content of a set */
  123. {
  124. int i, j, start = 1;;
  125. if(type != 1) fprintf(tl_out, "{");
  126. for(i = 0; i < set_size(type); i++)
  127. for(j = 0; j < mod; j++)
  128. if(l[i] & (1 << j)) {
  129. switch(type) {
  130. case 0: case 2:
  131. if(!start) fprintf(tl_out, ",");
  132. fprintf(tl_out, "%i", mod * i + j);
  133. break;
  134. case 1:
  135. if(!start) fprintf(tl_out, " & ");
  136. fprintf(tl_out, "%s", sym_table[mod * i + j]);
  137. break;
  138. }
  139. start = 0;
  140. }
  141. if(type != 1) fprintf(tl_out, "}");
  142. }
  143. int empty_set(int *l, int type) /* tests if a set is the empty set */
  144. {
  145. int i, test = 0;
  146. for(i = 0; i < set_size(type); i++)
  147. test |= l[i];
  148. return !test;
  149. }
  150. int same_sets(int *l1, int *l2, int type) /* tests if two sets are identical */
  151. {
  152. int i, test = 1;
  153. for(i = 0; i < set_size(type); i++)
  154. test &= (l1[i] == l2[i]);
  155. return test;
  156. }
  157. int included_set(int *l1, int *l2, int type)
  158. { /* tests if the first set is included in the second one */
  159. int i, test = 0;
  160. for(i = 0; i < set_size(type); i++)
  161. test |= (l1[i] & ~l2[i]);
  162. return !test;
  163. }
  164. int in_set(int *l, int n) /* tests if an element is in a set */
  165. {
  166. return(l[n/mod] & (1 << (n%mod)));
  167. }
  168. int *list_set(int *l, int type) /* transforms a set into a list */
  169. {
  170. int i, j, size = 1, *list;
  171. for(i = 0; i < set_size(type); i++)
  172. for(j = 0; j < mod; j++)
  173. if(l[i] & (1 << j))
  174. size++;
  175. list = (int *)tl_emalloc(size * sizeof(int));
  176. list[0] = size;
  177. size = 1;
  178. for(i = 0; i < set_size(type); i++)
  179. for(j = 0; j < mod; j++)
  180. if(l[i] & (1 << j))
  181. list[size++] = mod * i + j;
  182. return list;
  183. }