VIS
|
00001 00017 #include "synthInt.h" 00018 00019 static char rcsid[] UNUSED = "$Id: synthDiv.c,v 1.25 2002/09/10 05:50:52 fabio Exp $"; 00020 00021 /*---------------------------------------------------------------------------*/ 00022 /* Constant declarations */ 00023 /*---------------------------------------------------------------------------*/ 00024 00025 #define MAX_COUNT 100000000 /* just chosen for a very large number */ 00026 00027 /*---------------------------------------------------------------------------*/ 00028 /* Type declarations */ 00029 /*---------------------------------------------------------------------------*/ 00030 00031 00032 /*---------------------------------------------------------------------------*/ 00033 /* Structure declarations */ 00034 /*---------------------------------------------------------------------------*/ 00035 00045 typedef struct bfs_item { 00046 int reach; /* number of path from top node */ 00047 int count; /* number of path to constant 1 */ 00048 bdd_node *node; /* ZDD node */ 00049 struct bfs_item *next; 00050 } BfsItem; 00051 00061 typedef struct bfs_list { 00062 struct bfs_item *item; 00063 int child; /* 1 : T, 0 : E */ 00064 struct bfs_list *next; 00065 } BfsList; 00066 00067 00068 /*---------------------------------------------------------------------------*/ 00069 /* Variable declarations */ 00070 /*---------------------------------------------------------------------------*/ 00071 00072 00075 /*---------------------------------------------------------------------------*/ 00076 /* Static function prototypes */ 00077 /*---------------------------------------------------------------------------*/ 00078 00079 static int FindQuickDivisor(bdd_node *f, bdd_node *one, int *v); 00080 00084 /*---------------------------------------------------------------------------*/ 00085 /* Definition of exported functions */ 00086 /*---------------------------------------------------------------------------*/ 00087 00088 00103 bdd_node * 00104 Synth_ZddQuickDivisor(bdd_manager *dd, 00105 bdd_node *f) 00106 { 00107 bdd_node *res; 00108 00109 if (bdd_get_package_name() != CUDD) { 00110 (void)fprintf(vis_stderr, 00111 "** synth error: Synthesis package can be used only with CUDD package\n"); 00112 (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); 00113 return NIL(bdd_node); 00114 } 00115 00116 do { 00117 bdd_set_reordered_field(dd, 0); 00118 res = SynthZddQuickDivisor(dd, f); 00119 } while (bdd_read_reordered_field(dd) == 1); 00120 return(res); 00121 } 00122 00123 00138 bdd_node * 00139 Synth_ZddLeastDivisor(bdd_manager *dd, 00140 bdd_node *f) 00141 { 00142 bdd_node *res; 00143 00144 if (bdd_get_package_name() != CUDD) { 00145 (void)fprintf(vis_stderr, 00146 "** synth error: Synthesis package can be used only with CUDD package\n"); 00147 (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); 00148 return NIL(bdd_node); 00149 } 00150 00151 do { 00152 bdd_set_reordered_field(dd, 0); 00153 res = SynthZddLeastDivisor(dd, f); 00154 } while (bdd_read_reordered_field(dd) == 1); 00155 return(res); 00156 } 00157 00158 00173 bdd_node * 00174 Synth_ZddMostDivisor(bdd_manager *dd, 00175 bdd_node *f) 00176 { 00177 bdd_node *res; 00178 00179 if (bdd_get_package_name() != CUDD) { 00180 (void)fprintf(vis_stderr, 00181 "** synth error: Synthesis package can be used only with CUDD package\n"); 00182 (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); 00183 return NIL(bdd_node); 00184 } 00185 00186 do { 00187 bdd_set_reordered_field(dd, 0); 00188 res = SynthZddMostDivisor(dd, f); 00189 } while (bdd_read_reordered_field(dd) == 1); 00190 return(res); 00191 } 00192 00193 00207 bdd_node * 00208 Synth_ZddLevelZeroDivisor(bdd_manager *dd, 00209 bdd_node *f) 00210 { 00211 bdd_node *res; 00212 00213 if (bdd_get_package_name() != CUDD) { 00214 (void)fprintf(vis_stderr, 00215 "** synth error: Synthesis package can be used only with CUDD package\n"); 00216 (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); 00217 return NIL(bdd_node); 00218 } 00219 00220 do { 00221 bdd_set_reordered_field(dd, 0); 00222 res = SynthZddLevelZeroDivisor(dd, f); 00223 } while (bdd_read_reordered_field(dd) == 1); 00224 return(res); 00225 } 00226 00227 00241 bdd_node * 00242 Synth_ZddCommonDivisor(bdd_manager *dd, 00243 bdd_node *f) 00244 { 00245 bdd_node *res; 00246 00247 if (bdd_get_package_name() != CUDD) { 00248 (void)fprintf(vis_stderr, 00249 "** synth error: Synthesis package can be used only with CUDD package\n"); 00250 (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); 00251 return NIL(bdd_node); 00252 } 00253 00254 do { 00255 bdd_set_reordered_field(dd, 0); 00256 res = SynthZddCommonDivisor(dd, f); 00257 } while (bdd_read_reordered_field(dd) == 1); 00258 return(res); 00259 } 00260 00261 00274 bdd_node * 00275 Synth_ZddLpDivisor(bdd_manager *dd, 00276 bdd_node *f) 00277 { 00278 bdd_node *res; 00279 00280 if (bdd_get_package_name() != CUDD) { 00281 (void)fprintf(vis_stderr, 00282 "** synth error: Synthesis package can be used only with CUDD package\n"); 00283 (void)fprintf(vis_stderr,"** synth error: Please link with CUDD package\n"); 00284 return NIL(bdd_node); 00285 } 00286 00287 do { 00288 bdd_set_reordered_field(dd, 0); 00289 res = SynthZddLpDivisor(dd, f); 00290 } while (bdd_read_reordered_field(dd) == 1); 00291 return(res); 00292 } 00293 00294 00295 /*---------------------------------------------------------------------------*/ 00296 /* Definition of internal functions */ 00297 /*---------------------------------------------------------------------------*/ 00298 00299 00317 bdd_node * 00318 SynthZddQuickDivisor(bdd_manager *dd, 00319 bdd_node *f) 00320 { 00321 int i, v; 00322 int nvars; 00323 int *count; 00324 bdd_node *one = bdd_read_one(dd); 00325 bdd_node *zero = bdd_read_zero(dd); 00326 bdd_node *divisor, *node; 00327 bdd_node *tmp; 00328 int min_count; 00329 00330 if (f == one || f == zero) 00331 return(f); 00332 00333 /* Search for a literal appearing in at least two cubes. */ 00334 v = -1; 00335 FindQuickDivisor(f, one, &v); 00336 SynthZddClearFlag(f); 00337 00338 if (v == -1) { 00339 /* Quick divisor not found by looking at the ZDD graph. 00340 * Find the literal that occurs the least among those occuring 00341 * at least twice. 00342 */ 00343 min_count = MAX_COUNT; 00344 nvars = bdd_num_zdd_vars(dd); 00345 count = ALLOC(int, nvars); 00346 (void)memset((void *)count, 0, sizeof(int) * nvars); 00347 SynthCountLiteralOccurrence(dd, f, count); 00348 for (i = 0; i < nvars; i++) { 00349 if (count[i] > 1 && count[i] < min_count) { 00350 v = i; 00351 min_count = count[i]; 00352 } 00353 } 00354 FREE(count); 00355 if (v == -1) { 00356 /* All literal appear exactly once. We are done. */ 00357 return(f); 00358 } 00359 } 00360 00361 /* Obtain the literal divisor from its index and divide f. */ 00362 node = bdd_zdd_get_node(dd, v, one, zero); 00363 if (!node) 00364 return(NULL); 00365 bdd_ref(node); 00366 00367 tmp = (* SynthGetZddDivideRecurFunc())(dd, f, node); 00368 if (!tmp) { 00369 bdd_recursive_deref_zdd(dd,node); 00370 return(NULL); 00371 } 00372 bdd_ref(tmp); 00373 bdd_recursive_deref_zdd(dd, node); 00374 00375 /* Recur on the quotient to make sure that all literals appear once. */ 00376 divisor = SynthZddQuickDivisor(dd, tmp); 00377 if (!divisor) { 00378 bdd_recursive_deref_zdd(dd,tmp); 00379 return(NULL); 00380 } 00381 bdd_ref(divisor); 00382 bdd_recursive_deref_zdd(dd, tmp); 00383 00384 bdd_deref(divisor); 00385 return(divisor); 00386 } 00387 00388 00401 bdd_node * 00402 SynthZddLeastDivisor(bdd_manager *dd, 00403 bdd_node *f) 00404 { 00405 int i, v; 00406 int nvars, min_count; 00407 int *count; 00408 bdd_node *one = bdd_read_one(dd); 00409 bdd_node *zero = bdd_read_zero(dd); 00410 bdd_node *divisor, *node; 00411 bdd_node *tmp1; 00412 00413 if (f == one || f == zero) 00414 return(f); 00415 00416 /* Find the literal that occurs the least among those occuring at 00417 * least twice. 00418 */ 00419 v = -1; 00420 min_count = MAX_COUNT; 00421 nvars = bdd_num_zdd_vars(dd); 00422 count = ALLOC(int, nvars); 00423 (void)memset((void *)count, 0, sizeof(int) * nvars); 00424 SynthCountLiteralOccurrence(dd, f, count); 00425 for (i = 0; i < nvars; i++) { 00426 if (count[i] > 1 && count[i] < min_count) { 00427 v = i; 00428 min_count = count[i]; 00429 } 00430 } 00431 FREE(count); 00432 00433 if (v == -1) { 00434 /* All literal appear exactly once. We are done. */ 00435 return(f); 00436 } 00437 00438 /* Obtain the literal divisor from its index and divide f. */ 00439 node = bdd_zdd_get_node(dd, v, one, zero); 00440 if (!node) { 00441 return(NULL); 00442 } 00443 bdd_ref(node); 00444 00445 tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); 00446 if (!tmp1) { 00447 bdd_recursive_deref_zdd(dd, node); 00448 return(NULL); 00449 } 00450 bdd_ref(tmp1); 00451 bdd_recursive_deref_zdd(dd, node); 00452 00453 /* Recur on the quotient to make sure that all literals appear once. */ 00454 divisor = SynthZddLeastDivisor(dd, tmp1); 00455 if (!divisor) { 00456 bdd_recursive_deref_zdd(dd, tmp1); 00457 return(NULL); 00458 } 00459 bdd_ref(divisor); 00460 bdd_recursive_deref_zdd(dd, tmp1); 00461 00462 bdd_deref(divisor); 00463 return(divisor); 00464 } 00465 00466 00479 bdd_node * 00480 SynthZddMostDivisor(bdd_manager *dd, 00481 bdd_node *f) 00482 { 00483 int i, v; 00484 int nvars, max_count; 00485 int *count; 00486 bdd_node *one = bdd_read_one(dd); 00487 bdd_node *zero = bdd_read_zero(dd); 00488 bdd_node *divisor, *node; 00489 bdd_node *tmp1; 00490 00491 if (f == one || f == zero) 00492 return(f); 00493 00494 /* Find the literal that occurs the most. */ 00495 v = -1; 00496 max_count = 1; 00497 nvars = bdd_num_zdd_vars(dd); 00498 count = ALLOC(int, nvars); 00499 (void)memset((void *)count, 0, sizeof(int) * nvars); 00500 SynthCountLiteralOccurrence(dd, f, count); 00501 for (i = 0; i < nvars; i++) { 00502 if (count[i] > max_count) { 00503 v = i; 00504 max_count = count[i]; 00505 } 00506 } 00507 00508 FREE(count); 00509 00510 if (v == -1) { 00511 /* All literal appear exactly once. We are done. */ 00512 return(f); 00513 } 00514 00515 /* Obtain the literal divisor from its index and divide f. */ 00516 node = bdd_zdd_get_node(dd, v, one, zero); 00517 if (!node) 00518 return(NULL); 00519 bdd_ref(node); 00520 00521 tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); 00522 if (!tmp1) { 00523 bdd_recursive_deref_zdd(dd, node); 00524 return(NULL); 00525 } 00526 bdd_ref(tmp1); 00527 bdd_recursive_deref_zdd(dd, node); 00528 00529 /* Recur on the quotient to make sure that all literals appear once. */ 00530 divisor = SynthZddMostDivisor(dd, tmp1); 00531 if (!divisor) { 00532 bdd_recursive_deref_zdd(dd, tmp1); 00533 return(NULL); 00534 } 00535 bdd_ref(divisor); 00536 bdd_recursive_deref_zdd(dd, tmp1); 00537 00538 bdd_deref(divisor); 00539 return(divisor); 00540 } 00541 00542 00555 bdd_node * 00556 SynthZddLevelZeroDivisor(bdd_manager *dd, 00557 bdd_node *f) 00558 { 00559 int i, v; 00560 int nvars, max_count; 00561 int *count; 00562 bdd_node *one = bdd_read_one(dd); 00563 bdd_node *zero = bdd_read_zero(dd); 00564 bdd_node *divisor, *node; 00565 bdd_node *tmp1, *tmp2; 00566 00567 if (f == one || f == zero) 00568 return(f); 00569 00570 /* Find the literal that occurs the most. */ 00571 v = -1; 00572 max_count = 1; 00573 nvars = bdd_num_zdd_vars(dd); 00574 count = ALLOC(int, nvars); 00575 (void)memset((void *)count, 0, sizeof(int) * nvars); 00576 SynthCountLiteralOccurrence(dd, f, count); 00577 for (i = 0; i < nvars; i++) { 00578 if (count[i] > max_count) { 00579 v = i; 00580 max_count = count[i]; 00581 } 00582 } 00583 00584 FREE(count); 00585 00586 if (v == -1) { 00587 /* All literal appear exactly once. We are done. */ 00588 return(f); 00589 } 00590 00591 /* Obtain the literal divisor from its index and divide f. */ 00592 node = bdd_zdd_get_node(dd, v, one, zero); 00593 if (!node) 00594 return(NULL); 00595 bdd_ref(node); 00596 00597 tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); 00598 if (!tmp1) { 00599 bdd_recursive_deref_zdd(dd, node); 00600 return(NULL); 00601 } 00602 bdd_ref(tmp1); 00603 bdd_recursive_deref_zdd(dd, node); 00604 00605 /* Factor out all literals appearing in all cubes. */ 00606 tmp2 = SynthMakeCubeFree(dd, tmp1); 00607 if (!tmp2) { 00608 bdd_recursive_deref_zdd(dd, tmp1); 00609 return(NULL); 00610 } 00611 bdd_ref(tmp2); 00612 bdd_recursive_deref_zdd(dd, tmp1); 00613 00614 /* Recur on the quotient to make sure that all literals appear once. */ 00615 divisor = SynthZddLevelZeroDivisor(dd, tmp2); 00616 if (!divisor) { 00617 bdd_recursive_deref_zdd(dd, tmp2); 00618 return(NULL); 00619 } 00620 bdd_ref(divisor); 00621 bdd_recursive_deref_zdd(dd, tmp2); 00622 00623 bdd_deref(divisor); 00624 return(divisor); 00625 } 00626 00639 bdd_node * 00640 SynthZddCommonDivisor(bdd_manager *dd, 00641 bdd_node *f) 00642 { 00643 int i; 00644 int nvars; 00645 int *count; 00646 bdd_node *one = bdd_read_one(dd); 00647 bdd_node *zero = bdd_read_zero(dd); 00648 bdd_node *divisor, *node, *tmp; 00649 int nCubes; 00650 00651 divisor = (bdd_node *)NULL; /* NULL means no such divisor exists */ 00652 if (f == one || f == zero) 00653 return(divisor); 00654 00655 nCubes = bdd_zdd_count(dd, f); 00656 if (nCubes == 1) 00657 return(divisor); 00658 00659 /* Find the literals that appear exactly as many times as there 00660 * are cubes. These literals appear in all cubes, hence in the 00661 * common divisor. Their product is accumulated in divisor. */ 00662 nvars = bdd_num_zdd_vars(dd); 00663 count = ALLOC(int, nvars); 00664 (void)memset((void *)count, 0, sizeof(int) * nvars); 00665 SynthCountLiteralOccurrence(dd, f, count); 00666 for (i = 0; i < nvars; i++) { 00667 if (count[i] == nCubes) { 00668 node = bdd_zdd_get_node(dd, i, one, zero); 00669 if (!node) { 00670 FREE(count); 00671 return(NULL); 00672 } 00673 bdd_ref(node); 00674 if (!divisor) { 00675 divisor = node; 00676 continue; 00677 } 00678 tmp = divisor; 00679 divisor = (* SynthGetZddProductRecurFunc())(dd, divisor, node); 00680 if (!divisor) { 00681 bdd_recursive_deref_zdd(dd, tmp); 00682 bdd_recursive_deref_zdd(dd, node); 00683 FREE(count); 00684 return(NULL); 00685 } 00686 bdd_ref(divisor); 00687 bdd_recursive_deref_zdd(dd, tmp); 00688 bdd_recursive_deref_zdd(dd, node); 00689 } 00690 } 00691 FREE(count); 00692 00693 if (divisor) 00694 bdd_deref(divisor); 00695 return(divisor); 00696 } 00697 00698 00711 bdd_node * 00712 SynthZddLpDivisor(bdd_manager *dd, 00713 bdd_node *f) 00714 { 00715 int i, v; 00716 int nvars, min_count, min_pos = 0; 00717 int *count; 00718 bdd_node *one = bdd_read_one(dd); 00719 bdd_node *zero = bdd_read_zero(dd); 00720 bdd_node *divisor, *node; 00721 bdd_node *tmp1; 00722 00723 if (f == one || f == zero) 00724 return(f); 00725 00726 /* Find the literal that occurs the least among those occuring at 00727 * least twice. 00728 */ 00729 v = -1; 00730 min_count = MAX_COUNT; 00731 nvars = bdd_num_zdd_vars(dd); 00732 count = ALLOC(int, nvars); 00733 (void)memset((void *)count, 0, sizeof(int) * nvars); 00734 00735 SynthCountLiteralOccurrence(dd, f, count); 00736 for (i = 0; i < nvars; i++) { 00737 if (count[i] > 1 && count[i] < min_count) { 00738 v = i; 00739 min_count = count[i]; 00740 min_pos = i; 00741 } 00742 } 00743 if (v == -1) { 00744 /* All literal appear exactly once. We are done. */ 00745 FREE(count); 00746 return(f); 00747 } 00748 00749 /* Among the literals with minimum count, find a good one. */ 00750 v = SynthFindDivisorForLowPower(count, nvars, min_count, min_pos); 00751 00752 FREE(count); 00753 00754 if (v == -1) { 00755 return(f); 00756 } 00757 00758 /* Obtain the literal divisor from its index and divide f. */ 00759 node = bdd_zdd_get_node(dd, v, one, zero); 00760 if (!node) 00761 return(NULL); 00762 bdd_ref(node); 00763 00764 tmp1 = (* SynthGetZddDivideRecurFunc())(dd, f, node); 00765 if (!tmp1) { 00766 bdd_recursive_deref_zdd(dd, node); 00767 return(NULL); 00768 } 00769 bdd_ref(tmp1); 00770 bdd_recursive_deref_zdd(dd, node); 00771 00772 /* Recur on the quotient to make sure that all literals appear once. */ 00773 divisor = SynthZddLpDivisor(dd, tmp1); 00774 if (!divisor) { 00775 bdd_recursive_deref_zdd(dd, tmp1); 00776 return(NULL); 00777 } 00778 bdd_ref(divisor); 00779 bdd_recursive_deref_zdd(dd, tmp1); 00780 00781 bdd_deref(divisor); 00782 return(divisor); 00783 } 00784 00785 00811 void 00812 SynthCountLiteralOccurrence(bdd_manager *dd, 00813 bdd_node *f, 00814 int *count) 00815 { 00816 BfsItem **level, *item, *cur_item, *next_item, *last_item; 00817 BfsList *list, *pre_list, *cur_list, *next_list, *last_list; 00818 BfsList *new_list, *save_last_list; 00819 int cur_level, next_level, start_level, last_level; 00820 int exist; 00821 bdd_node *zero = bdd_read_zero(dd); 00822 bdd_node *one = bdd_read_one(dd); 00823 int i, ct, ce; 00824 bdd_node *node; 00825 int lv, *index, id; 00826 int sizeZ = bdd_num_zdd_vars(dd); 00827 00828 if (bdd_is_constant(f)) 00829 return; 00830 00831 level = ALLOC(BfsItem *, sizeZ); 00832 (void)memset((void *)level, 0, sizeof(BfsItem *) * sizeZ); 00833 index = ALLOC(int, sizeZ); 00834 (void)memset((void *)index, 0, sizeof(int) * sizeZ); 00835 00836 /* Initialize BFS by entering f in the queue. */ 00837 item = ALLOC(BfsItem, 1); 00838 (void)memset((void *)item, 0, sizeof(BfsItem)); 00839 item->node = f; 00840 item->reach = 1; 00841 lv = bdd_read_zdd_level(dd,bdd_node_read_index(f)); 00842 level[lv] = item; 00843 index[lv] = bdd_node_read_index(f); 00844 start_level = last_level = lv; 00845 00846 if (!bdd_is_constant(bdd_bdd_T(f))) { 00847 list = ALLOC(BfsList, 1); 00848 (void)memset((void *)list, 0, sizeof(BfsList)); 00849 list->item = item; 00850 list->child = 1; 00851 last_list = list; 00852 } else 00853 list = last_list = (BfsList *)NULL; 00854 if (!bdd_is_constant(bdd_bdd_E(f))) { 00855 last_list = ALLOC(BfsList, 1); 00856 (void)memset((void *)last_list, 0, sizeof(BfsList)); 00857 last_list->item = item; 00858 last_list->child = 0; 00859 if (list) 00860 list->next = last_list; 00861 else 00862 list = last_list; 00863 } 00864 00865 /* Perform the BFS. */ 00866 while (list) { 00867 cur_level = sizeZ; 00868 cur_list = list; 00869 while (cur_list) { 00870 if (cur_list->child) 00871 id = bdd_node_read_index(bdd_bdd_T(cur_list->item->node)); 00872 else 00873 id = bdd_node_read_index(bdd_bdd_E(cur_list->item->node)); 00874 next_level = bdd_read_zdd_level(dd,id); 00875 cur_level = (cur_level < next_level) ? cur_level : next_level; 00876 cur_list = cur_list->next; 00877 } 00878 last_level = cur_level; 00879 save_last_list = last_list; 00880 00881 pre_list = (BfsList *)NULL; 00882 cur_list = list; 00883 while (cur_list) { 00884 if (cur_list->child) 00885 id = bdd_node_read_index(bdd_bdd_T(cur_list->item->node)); 00886 else 00887 id = bdd_node_read_index(bdd_bdd_E(cur_list->item->node)); 00888 next_level = bdd_read_zdd_level(dd,id); 00889 00890 if (next_level != cur_level) { 00891 pre_list = cur_list; 00892 cur_list = cur_list->next; 00893 continue; 00894 } 00895 00896 if (cur_list->child) 00897 node = bdd_bdd_T(cur_list->item->node); 00898 else 00899 node = bdd_bdd_E(cur_list->item->node); 00900 00901 exist = 0; 00902 last_item = level[cur_level]; 00903 while (last_item) { 00904 if (node == last_item->node) { 00905 last_item->reach += cur_list->item->reach; 00906 exist = 1; 00907 break; 00908 } 00909 if (last_item->next) 00910 last_item = last_item->next; 00911 else 00912 break; 00913 } 00914 00915 if (exist == 0) { 00916 item = ALLOC(BfsItem, 1); 00917 (void)memset((void *)item, 0, sizeof(BfsItem)); 00918 item->node = node; 00919 item->reach = cur_list->item->reach; 00920 if (last_item) 00921 last_item->next = item; 00922 else { 00923 level[cur_level] = item; 00924 index[cur_level] = id; 00925 } 00926 00927 if (!bdd_is_constant(bdd_bdd_T(node))) { 00928 new_list = ALLOC(BfsList, 1); 00929 (void)memset((void *)new_list, 0, sizeof(BfsList)); 00930 new_list->item = item; 00931 new_list->child = 1; 00932 last_list->next = new_list; 00933 last_list = new_list; 00934 } 00935 if (!bdd_is_constant(bdd_bdd_E(node))) { 00936 new_list = ALLOC(BfsList, 1); 00937 (void)memset((void *)new_list, 0, sizeof(BfsList)); 00938 new_list->item = item; 00939 new_list->child = 0; 00940 last_list->next = new_list; 00941 last_list = new_list; 00942 } 00943 } 00944 00945 next_list = cur_list->next; 00946 if (cur_list == list && cur_list == last_list) { 00947 FREE(cur_list); 00948 list = next_list; 00949 } else if (cur_list == list) { 00950 FREE(cur_list); 00951 pre_list = (BfsList *)NULL; 00952 if (list == save_last_list) { 00953 list = next_list; 00954 next_list = (BfsList *)NULL; 00955 } else 00956 list = next_list; 00957 } else if (cur_list == last_list) { 00958 if (pre_list) 00959 pre_list->next = cur_list->next; 00960 FREE(cur_list); 00961 last_list = pre_list; 00962 } else { 00963 if (pre_list) 00964 pre_list->next = cur_list->next; 00965 if (cur_list == save_last_list) { 00966 FREE(cur_list); 00967 next_list = (BfsList *)NULL; 00968 } else 00969 FREE(cur_list); 00970 } 00971 00972 cur_list = next_list; 00973 } 00974 } 00975 00976 /* Compute the number of paths to the constant 1 for each node in 00977 * bottom up fashion. Update the occurrence count of the variables. 00978 */ 00979 for (i = last_level; i >= start_level; i--) { 00980 item = level[i]; 00981 while (item) { 00982 ct = ce = 0; 00983 if (bdd_bdd_T(item->node) == one) 00984 ct = 1; 00985 else { 00986 node = bdd_bdd_T(item->node); 00987 next_level = bdd_read_zdd_level(dd, bdd_node_read_index(node)); 00988 cur_item = level[next_level]; 00989 while (cur_item) { 00990 if (cur_item->node == node) { 00991 ct = cur_item->count; 00992 break; 00993 } 00994 cur_item = cur_item->next; 00995 } 00996 } 00997 if (bdd_bdd_E(item->node) != zero) { 00998 node = bdd_bdd_E(item->node); 00999 next_level = bdd_read_zdd_level(dd, 01000 bdd_node_read_index(node)); 01001 cur_item = level[next_level]; 01002 while (cur_item) { 01003 if (cur_item->node == node) { 01004 ce = cur_item->count; 01005 break; 01006 } 01007 cur_item = cur_item->next; 01008 } 01009 } 01010 item->count = ct + ce; 01011 count[index[i]] += ct * item->reach; 01012 item = item->next; 01013 } 01014 } 01015 01016 /* Clean up. */ 01017 for (i = last_level; i >= start_level; i--) { 01018 item = level[i]; 01019 while (item) { 01020 next_item = item->next; 01021 FREE(item); 01022 item = next_item; 01023 } 01024 } 01025 01026 FREE(level); 01027 FREE(index); 01028 } 01029 01030 01031 /*---------------------------------------------------------------------------*/ 01032 /* Definition of static functions */ 01033 /*---------------------------------------------------------------------------*/ 01034 01035 01054 static int 01055 FindQuickDivisor(bdd_node *f, 01056 bdd_node *one, 01057 int *v) 01058 { 01059 int c, ct, ce; 01060 bdd_node *temp = bdd_read_next(f); 01061 01062 if (bdd_is_constant(f)) { 01063 if (f == one) 01064 return(1); 01065 else 01066 return(0); 01067 } 01068 01069 if (bdd_is_complement(temp)) { /* already visited */ 01070 *v = bdd_node_read_index(f); 01071 return(-1); 01072 } 01073 /* mark as visited */ 01074 bdd_set_next(f, bdd_not_bdd_node(temp)); 01075 01076 ct = FindQuickDivisor(bdd_bdd_T(f), one, v); 01077 if (ct == -1) /* already found */ 01078 return(-1); 01079 else if (ct > 1) { 01080 *v = bdd_node_read_index(f); 01081 return(-1); 01082 } 01083 01084 ce = FindQuickDivisor(bdd_bdd_E(f), one, v); 01085 if (ce == -1) /* already found */ 01086 return(-1); 01087 01088 /* Add the number of path to constant 1 from two children nodes. */ 01089 c = ct + ce; 01090 return(c); 01091 }