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.

178 lines
5.0 KiB

  1. /* */
  2. /**
  3. * Calculates \exists variables . a
  4. */
  5. TASK_IMPL_3(BDD, sylvan_existsRepresentative, BDD, a, BDD, variables, BDDVAR, prev_level)
  6. {
  7. int aIsNegated = (a & sylvan_complement) == ((uint64_t)0) ? 0 : 1;
  8. BDD aRegular = (aIsNegated) ? sylvan_not(a) : a;
  9. if (aRegular == sylvan_false) {
  10. if (aIsNegated) {
  11. if (sylvan_set_isempty(variables)) {
  12. return sylvan_true;
  13. } else {
  14. //printf("return in preprocessing...3\n");
  15. BDD _v = sylvan_set_next(variables);
  16. BDD res = CALL(sylvan_existsRepresentative, a, _v, prev_level);
  17. if (res == sylvan_invalid) {
  18. return sylvan_invalid;
  19. }
  20. sylvan_ref(res);
  21. BDD res1 = sylvan_ite(sylvan_ithvar(bddnode_getvariable(MTBDD_GETNODE(variables))), sylvan_false, res);
  22. if (res1 == sylvan_invalid) {
  23. sylvan_deref(res);
  24. return sylvan_invalid;
  25. }
  26. sylvan_deref(res);
  27. return res1;
  28. }
  29. } else {
  30. return a;
  31. }
  32. } else if (sylvan_set_isempty(variables)) {
  33. return a;
  34. }
  35. BDD result;
  36. if (cache_get3(CACHE_MTBDD_ABSTRACT_REPRESENTATIVE, a, variables, (size_t)2, &result)) {
  37. sylvan_stats_count(MTBDD_ABSTRACT_CACHED);
  38. return result;
  39. }
  40. /* From now on, f and cube are non-constant. */
  41. bddnode_t na = MTBDD_GETNODE(a);
  42. BDDVAR level = bddnode_getvariable(na);
  43. bddnode_t nv = MTBDD_GETNODE(variables);
  44. BDDVAR vv = bddnode_getvariable(nv);
  45. /* Abstract a variable that does not appear in f. */
  46. if (level > vv) {
  47. BDD _v = sylvan_set_next(variables);
  48. BDD res = CALL(sylvan_existsRepresentative, a, _v, level);
  49. if (res == sylvan_invalid) {
  50. return sylvan_invalid;
  51. }
  52. sylvan_ref(res);
  53. BDD res1 = sylvan_ite(sylvan_ithvar(vv), sylvan_false, res);
  54. if (res1 == sylvan_invalid) {
  55. sylvan_deref(res);
  56. return sylvan_invalid;
  57. }
  58. sylvan_deref(res);
  59. return res1;
  60. }
  61. /* Compute the cofactors of a. */
  62. BDD aLow = node_low(a, na); // ELSE
  63. BDD aHigh = node_high(a, na); // THEN
  64. /* If the two indices are the same, so are their levels. */
  65. if (level == vv) {
  66. BDD _v = sylvan_set_next(variables);
  67. BDD res1 = CALL(sylvan_existsRepresentative, aLow, _v, level);
  68. if (res1 == sylvan_invalid) {
  69. return sylvan_invalid;
  70. }
  71. if (res1 == sylvan_true) {
  72. return sylvan_not(variables);
  73. }
  74. sylvan_ref(res1);
  75. BDD res2 = CALL(sylvan_existsRepresentative, aHigh, _v, level);
  76. if (res2 == sylvan_invalid) {
  77. sylvan_deref(res1);
  78. return sylvan_invalid;
  79. }
  80. sylvan_ref(res2);
  81. BDD left = CALL(sylvan_exists, aLow, _v, 0);
  82. if (left == sylvan_invalid) {
  83. sylvan_deref(res1);
  84. sylvan_deref(res2);
  85. return sylvan_invalid;
  86. }
  87. sylvan_ref(left);
  88. BDD res1Inf = sylvan_ite(left, res1, sylvan_false);
  89. if (res1Inf == sylvan_invalid) {
  90. sylvan_deref(res1);
  91. sylvan_deref(res2);
  92. sylvan_deref(left);
  93. return sylvan_invalid;
  94. }
  95. sylvan_ref(res1Inf);
  96. sylvan_deref(res1);
  97. BDD res2Inf = sylvan_ite(left, sylvan_false, res2);
  98. if (res2Inf == sylvan_invalid) {
  99. sylvan_deref(res2);
  100. sylvan_deref(left);
  101. sylvan_deref(res1Inf);
  102. return sylvan_invalid;
  103. }
  104. sylvan_ref(res2Inf);
  105. sylvan_deref(res2);
  106. sylvan_deref(left);
  107. assert(res1Inf != res2Inf);
  108. BDD res = sylvan_ite(sylvan_ithvar(level), res2Inf, res1Inf);
  109. if (res == sylvan_invalid) {
  110. sylvan_deref(res1Inf);
  111. sylvan_deref(res2Inf);
  112. return sylvan_invalid;
  113. }
  114. /* Store in cache */
  115. if (cache_put3(CACHE_MTBDD_ABSTRACT_REPRESENTATIVE, a, variables, (size_t)2, res)) {
  116. sylvan_stats_count(MTBDD_ABSTRACT_CACHEDPUT);
  117. }
  118. sylvan_deref(res1Inf);
  119. sylvan_deref(res2Inf);
  120. return res;
  121. } else { /* if (level == vv) */
  122. BDD res1 = CALL(sylvan_existsRepresentative, aLow, variables, level);
  123. if (res1 == sylvan_invalid){
  124. return sylvan_invalid;
  125. }
  126. sylvan_ref(res1);
  127. BDD res2 = CALL(sylvan_existsRepresentative, aHigh, variables, level);
  128. if (res2 == sylvan_invalid) {
  129. sylvan_deref(res1);
  130. return sylvan_invalid;
  131. }
  132. sylvan_ref(res2);
  133. /* ITE takes care of possible complementation of res1 and of the
  134. ** case in which res1 == res2. */
  135. BDD res = sylvan_ite(sylvan_ithvar(level), res2, res1);
  136. if (res == sylvan_invalid) {
  137. sylvan_deref(res1);
  138. sylvan_deref(res2);
  139. return sylvan_invalid;
  140. }
  141. sylvan_deref(res1);
  142. sylvan_deref(res2);
  143. /* Store in cache */
  144. if (cache_put3(CACHE_MTBDD_ABSTRACT_REPRESENTATIVE, a, variables, (size_t)2, res)) {
  145. sylvan_stats_count(MTBDD_ABSTRACT_CACHEDPUT);
  146. }
  147. return res;
  148. }
  149. // Prevent unused variable warning
  150. (void)prev_level;
  151. }