VIS
|
00001 00019 #include "synthInt.h" 00020 00021 static char rcsid[] UNUSED = "$Id: synthSimple.c,v 1.36 2005/04/23 14:37:51 jinh Exp $"; 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Constant declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 00027 00028 /*---------------------------------------------------------------------------*/ 00029 /* Type declarations */ 00030 /*---------------------------------------------------------------------------*/ 00031 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Structure declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 00038 /*---------------------------------------------------------------------------*/ 00039 /* Variable declarations */ 00040 /*---------------------------------------------------------------------------*/ 00041 00042 extern int CompMode; 00043 extern int UseMtree; 00044 extern int UseCommonDivisor; 00045 extern int TryNodeSharing; 00046 extern int Resubstitution; 00047 extern int RemainderComplement; 00048 extern int noMemoryFlag; 00049 extern int VerifyTreeMode; 00050 00053 /*---------------------------------------------------------------------------*/ 00054 /* Static function prototypes */ 00055 /*---------------------------------------------------------------------------*/ 00056 00057 static int CountZddLeafLiterals(bdd_manager *dd, bdd_node *node); 00058 00062 /*---------------------------------------------------------------------------*/ 00063 /* Definition of exported functions */ 00064 /*---------------------------------------------------------------------------*/ 00065 00066 00067 /*---------------------------------------------------------------------------*/ 00068 /* Definition of internal functions */ 00069 /*---------------------------------------------------------------------------*/ 00070 00094 MlTree * 00095 SynthSimpleFactorTree(bdd_manager *dd, 00096 st_table *table, 00097 bdd_node *f, 00098 int level, 00099 int *ref, 00100 MlTree *comp_d_tree, 00101 int comp_d_flag, 00102 MlTree *bring, 00103 int verbosity) 00104 { 00105 bdd_node *one = bdd_read_one(dd); 00106 bdd_node *zero = bdd_read_zero(dd); 00107 bdd_node *d, *q, *r, *m; 00108 MlTree *tree, *q_tree, *d_tree, *r_tree; 00109 char message[120]; 00110 char space[100]; 00111 MlTree *comp_q_tree = (MlTree *)NULL; 00112 MlTree *comp_r_tree = (MlTree *)NULL; 00113 int found; 00114 MlTree *tmp_tree; 00115 int comp_flag; 00116 00117 if (verbosity > 1) { 00118 SynthGetSpaceString(space, level * 2, 80); 00119 sprintf(message, "%s[%d] in : ", space, level); 00120 SynthPrintZddTreeMessage(dd, f, message); 00121 sprintf(message, "%s[%d]out : ", space, level); 00122 } 00123 00124 if (bring) 00125 tree = (MlTree *)NULL; 00126 else { 00127 tree = SynthLookupMlTable(table, dd, f, 1, verbosity); 00128 /* tree could be NULL because of reordering, or a failure to 00129 * allocate memory or just that f was not in the cache. 00130 * So, we would like return NULL ONLY in the case of 00131 * reordering or failure to allocate memory. 00132 */ 00133 if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) 00134 return(NULL); 00135 } 00136 if (tree) { 00137 if (verbosity > 1) 00138 SynthPrintMlTreeMessage(dd, tree, message); 00139 *ref = 1; 00140 return(tree); 00141 } 00142 00143 if (f == one || f == zero) { 00144 tree = SynthFindOrCreateMlTree(table, dd, f, 1, 0, ref, verbosity); 00145 if (!tree) 00146 return(NULL); 00147 tmp_tree = tree; 00148 tree = SynthCheckAndMakeComplement(dd, table, tree, &comp_flag, verbosity); 00149 if (!tree) { 00150 if (*ref == 0) 00151 SynthFreeMlTree(MlTree_Regular(tmp_tree), 1); 00152 return(NULL); 00153 } else if (tree != tmp_tree) { 00154 *ref = 1; 00155 if (comp_flag) 00156 tree = MlTree_Not(tree); 00157 } 00158 if (verbosity > 1) 00159 SynthPrintMlTreeMessage(dd, tree, message); 00160 return(tree); 00161 } 00162 00163 d_tree = (MlTree *)NULL; 00164 if (comp_d_tree) { 00165 if (comp_d_flag) 00166 d = comp_d_tree->complement; 00167 else 00168 d = comp_d_tree->node; 00169 if (!d) 00170 return((MlTree *)NULL); 00171 bdd_ref(d); 00172 } else { 00173 found = 0; 00174 d = (* SynthGetZddDivisorFunc())(dd, f); 00175 if (!d) 00176 return(NULL); 00177 bdd_ref(d); 00178 if (TryNodeSharing) { 00179 /* Here, we don't need to call bdd_ref. */ 00180 d = SynthFindBiggerDivisorInList(dd, table, f, d, &found, 00181 &comp_d_flag, &comp_d_tree, verbosity); 00182 if (!d) 00183 return(NULL); 00184 } 00185 if (UseCommonDivisor && found == 0) { 00186 tree = SynthGetFactorTreeWithCommonDivisor(dd, table, 00187 SynthSimpleFactorTree, f, d, level, ref, verbosity); 00188 if (tree) 00189 return(tree); 00190 if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) 00191 return(NULL); 00192 } 00193 } 00194 if (d == f) { 00195 tree = SynthFindOrCreateMlTree(table, dd, f, 1, 0, ref, verbosity); 00196 if (!tree) { 00197 bdd_recursive_deref_zdd(dd, d); 00198 return(NULL); 00199 } 00200 if (verbosity > 1) 00201 SynthPrintMlTreeMessage(dd, tree, message); 00202 tmp_tree = tree; 00203 tree = SynthCheckAndMakeComplement(dd, table, tree, &comp_flag, verbosity); 00204 if (!tree) { 00205 bdd_recursive_deref_zdd(dd, d); 00206 return(NULL); 00207 } else if (tree == tmp_tree) { 00208 if (*ref == 0) 00209 SynthPutMlTreeInList(dd, tree, 0); 00210 } else { 00211 *ref = 1; 00212 if (comp_flag) 00213 tree = MlTree_Not(tree); 00214 } 00215 bdd_recursive_deref_zdd(dd, d); 00216 return(tree); 00217 } 00218 if (!comp_d_tree) { 00219 if (st_lookup(table, (char *)d, &d_tree)) { 00220 SynthSetSharedFlag(dd, d_tree); 00221 if (MlTree_Regular(d_tree)->candidate) { 00222 if (!SynthUseCandidate(table, dd, d_tree, verbosity)) { 00223 bdd_recursive_deref_zdd(dd, d); 00224 return(NULL); 00225 } 00226 } 00227 if (MlTree_IsComplement(d_tree)) { 00228 d_tree = MlTree_Regular(d_tree); 00229 comp_d_tree = d_tree; 00230 d_tree = (MlTree *)NULL; 00231 } 00232 } 00233 } else { 00234 if (!comp_d_flag) 00235 d_tree = comp_d_tree; 00236 } 00237 00238 q = (* SynthGetZddDivideFunc())(dd, f, d); 00239 if (!q) { 00240 bdd_recursive_deref_zdd(dd, d); 00241 return(NULL); 00242 } 00243 bdd_ref(q); 00244 if (comp_d_tree && q == zero) { 00245 bdd_recursive_deref_zdd(dd, d); 00246 bdd_recursive_deref_zdd(dd, q); 00247 return((MlTree *)NULL); 00248 } 00249 if (q == one) { 00250 bdd_recursive_deref_zdd(dd, q); 00251 tree = SynthPostFactorTree(dd, table, f, q, d, bring, 00252 comp_d_tree, comp_d_flag, message, ref, verbosity); 00253 bdd_recursive_deref_zdd(dd, d); 00254 return(tree); 00255 } 00256 00257 if (comp_d_tree && d_tree == comp_d_tree) 00258 comp_d_tree = (MlTree *)NULL; 00259 00260 q_tree = (MlTree *)NULL; 00261 if (st_lookup(table, (char *)q, &q_tree)) { 00262 SynthSetSharedFlag(dd, q_tree); 00263 if (MlTree_Regular(q_tree)->candidate) { 00264 if (!SynthUseCandidate(table, dd, q_tree, verbosity)) { 00265 bdd_recursive_deref_zdd(dd, d); 00266 bdd_recursive_deref_zdd(dd, q); 00267 return(NULL); 00268 } 00269 } 00270 if (MlTree_IsComplement(q_tree)) { 00271 q_tree = MlTree_Regular(q_tree); 00272 comp_q_tree = q_tree; 00273 q_tree = (MlTree *)NULL; 00274 } 00275 } 00276 00277 m = (* SynthGetZddProductFunc())(dd, d, q); 00278 if (!m) { 00279 bdd_recursive_deref_zdd(dd, d); 00280 bdd_recursive_deref_zdd(dd, q); 00281 return(NULL); 00282 } 00283 bdd_ref(m); 00284 r = bdd_zdd_diff(dd, f, m); 00285 if (!r) { 00286 bdd_recursive_deref_zdd(dd, d); 00287 bdd_recursive_deref_zdd(dd, q); 00288 bdd_recursive_deref_zdd(dd, m); 00289 return(NULL); 00290 } 00291 bdd_ref(r); 00292 00293 r_tree = (MlTree *)NULL; 00294 if (st_lookup(table, (char *)r, &r_tree)) { 00295 SynthSetSharedFlag(dd, r_tree); 00296 if (MlTree_Regular(r_tree)->candidate) { 00297 if (!SynthUseCandidate(table, dd, r_tree, verbosity)) { 00298 bdd_recursive_deref_zdd(dd, d); 00299 bdd_recursive_deref_zdd(dd, q); 00300 bdd_recursive_deref_zdd(dd, m); 00301 bdd_recursive_deref_zdd(dd, r); 00302 return(NULL); 00303 } 00304 } 00305 if (MlTree_IsComplement(r_tree)) { 00306 r_tree = MlTree_Regular(r_tree); 00307 comp_r_tree = r_tree; 00308 r_tree = (MlTree *)NULL; 00309 } 00310 } 00311 00312 tree = SynthFactorTreeRecur(dd, table, SynthSimpleFactorTree, 00313 f, q, d, r, m, q_tree, d_tree, r_tree, 00314 comp_q_tree, comp_d_tree, comp_r_tree, 00315 bring, level, space, message, ref, verbosity); 00316 bdd_recursive_deref_zdd(dd, d); 00317 bdd_recursive_deref_zdd(dd, q); 00318 bdd_recursive_deref_zdd(dd, m); 00319 bdd_recursive_deref_zdd(dd, r); 00320 00321 if (VerifyTreeMode) { 00322 SynthVerifyTree(dd, tree, 0); 00323 SynthVerifyMlTable(dd, table); 00324 } 00325 00326 return(tree); 00327 } 00328 00329 00341 bdd_node * 00342 SynthFindBiggerDivisorInList(bdd_manager *dd, 00343 st_table *table, 00344 bdd_node *f, 00345 bdd_node *d, 00346 int *found, 00347 int *comp_d_flag, 00348 MlTree **comp_d_tree, 00349 int verbosity) 00350 { 00351 bdd_node *zero = bdd_read_zero(dd); 00352 int size, nSupports; 00353 unsigned int *support; 00354 int flag; 00355 int nL, nLiterals; 00356 bdd_node *candy; 00357 MlTree *cur; 00358 bdd_node *q; 00359 00360 nSupports = SynthGetSupportCount(dd, d); 00361 size = bdd_num_zdd_vars(dd) / (sizeof(unsigned int) * 8) + 1; 00362 support = ALLOC(unsigned int, size); 00363 SynthGetSupportMask(dd, f, support); 00364 flag = 0; 00365 cur = SynthGetHeadTreeOfSize(SynthGetLiteralCount(dd, f) - 1); 00366 nLiterals = CountZddLeafLiterals(dd, d); 00367 if (nLiterals == -1) { 00368 noMemoryFlag = 1; 00369 FREE(support); 00370 bdd_recursive_deref_zdd(dd, d); 00371 return(NULL); 00372 } 00373 00374 while (cur) { 00375 if (cur->nLiterals < nSupports) 00376 break; 00377 nL = CountZddLeafLiterals(dd, cur->node); 00378 00379 if ((!SynthIsSubsetOfSupport(size, cur->support, support)) || 00380 nL < nLiterals) { 00381 flag = 0; 00382 cur = cur->next; 00383 continue; 00384 } 00385 00386 if (flag) 00387 candy = cur->complement; 00388 else 00389 candy = cur->node; 00390 q = (* SynthGetZddDivideFunc())(dd, f, candy); 00391 if (!q) { 00392 FREE(support); 00393 bdd_recursive_deref_zdd(dd, d); 00394 return(NULL); 00395 } 00396 bdd_ref(q); 00397 bdd_recursive_deref_zdd(dd, q); 00398 if (q != zero) { 00399 if (MlTree_Regular(cur)->candidate) { 00400 if (!SynthUseCandidate(table, dd, cur, verbosity)) { 00401 FREE(support); 00402 bdd_recursive_deref_zdd(dd, d); 00403 return(NULL); 00404 } 00405 } 00406 *found = 1; 00407 *comp_d_flag = flag; 00408 *comp_d_tree = cur; 00409 bdd_recursive_deref_zdd(dd, d); 00410 d = candy; 00411 bdd_ref(d); 00412 break; 00413 } 00414 if (flag == 0 && cur->complement) 00415 flag = 1; 00416 else { 00417 cur = cur->next; 00418 flag = 0; 00419 } 00420 } 00421 00422 FREE(support); 00423 return(d); 00424 } 00425 00426 00438 MlTree * 00439 SynthGetFactorTreeWithCommonDivisor(bdd_manager *dd, 00440 st_table *table, 00441 MlTree *(* factoring_func)(bdd_manager *, 00442 st_table *, 00443 bdd_node *, int, 00444 int *, MlTree *, 00445 int, MlTree *, 00446 int), 00447 bdd_node *f, 00448 bdd_node *d, 00449 int level, 00450 int *ref, 00451 int verbosity) 00452 { 00453 bdd_node *zero = bdd_read_zero(dd); 00454 bdd_node *cd; 00455 bdd_node *q; 00456 MlTree *tree, *q_tree, *d_tree, *r_tree; 00457 int q_ref, d_ref, r_ref; 00458 MlTree *comp_q_tree = (MlTree *)NULL; 00459 MlTree *comp_d_tree = (MlTree *)NULL; 00460 MlTree *comp_r_tree = (MlTree *)NULL; 00461 int q_tree_exist; 00462 MlTree *tmp_tree; 00463 char message[120]; 00464 char space[100]; 00465 char comp_mess[120]; 00466 int comp_flag; 00467 00468 q_ref = d_ref = r_ref = 0; 00469 00470 if (verbosity > 1) { 00471 SynthGetSpaceString(space, level * 2, 80); 00472 sprintf(message, "%s[%d]out : ", space, level); 00473 } 00474 00475 cd = SynthZddCommonDivisor(dd, f); 00476 if (cd) { 00477 bdd_recursive_deref_zdd(dd, d); 00478 d = cd; 00479 bdd_ref(d); 00480 q = (* SynthGetZddDivideFunc())(dd, f, d); 00481 if (!q) { 00482 bdd_recursive_deref_zdd(dd, d); 00483 return(NULL); 00484 } 00485 bdd_ref(q); 00486 00487 d_tree = (MlTree *)NULL; 00488 if (st_lookup(table, (char *)d, &d_tree)) { 00489 SynthSetSharedFlag(dd, d_tree); 00490 if (MlTree_Regular(d_tree)->candidate) { 00491 if (!SynthUseCandidate(table, dd, d_tree, verbosity)) { 00492 bdd_recursive_deref_zdd(dd, d); 00493 bdd_recursive_deref_zdd(dd, q); 00494 return(NULL); 00495 } 00496 } 00497 if (MlTree_IsComplement(d_tree)) { 00498 d_tree = MlTree_Regular(d_tree); 00499 comp_d_tree = d_tree; 00500 } 00501 d_ref = 1; 00502 } else { 00503 d_tree = SynthFindOrCreateMlTree(table, dd, d, 1, 0, &d_ref, verbosity); 00504 if (!d_tree) { 00505 bdd_recursive_deref_zdd(dd, d); 00506 bdd_recursive_deref_zdd(dd, q); 00507 return(NULL); 00508 } 00509 if (MlTree_IsComplement(d_tree)) { 00510 d_tree = MlTree_Regular(d_tree); 00511 comp_d_tree = d_tree; 00512 } 00513 tmp_tree = d_tree; 00514 d_tree = SynthCheckAndMakeComplement(dd, table, d_tree, &comp_flag, 00515 verbosity); 00516 if (!d_tree) { 00517 bdd_recursive_deref_zdd(dd, d); 00518 bdd_recursive_deref_zdd(dd, q); 00519 return(NULL); 00520 } else if (d_tree == tmp_tree) { 00521 if (d_ref == 0) 00522 SynthPutMlTreeInList(dd, d_tree, 0); 00523 } else { 00524 if (comp_flag) 00525 comp_d_tree = d_tree; 00526 d_ref = 1; 00527 } 00528 } 00529 00530 q_tree = (MlTree *)NULL; 00531 if (st_lookup(table, (char *)q, &q_tree)) { 00532 SynthSetSharedFlag(dd, q_tree); 00533 if (MlTree_Regular(q_tree)->candidate) { 00534 if (!SynthUseCandidate(table, dd, q_tree, verbosity)) { 00535 bdd_recursive_deref_zdd(dd, d); 00536 bdd_recursive_deref_zdd(dd, q); 00537 return(NULL); 00538 } 00539 } 00540 if (MlTree_IsComplement(q_tree)) { 00541 q_tree = MlTree_Regular(q_tree); 00542 comp_q_tree = q_tree; 00543 q_tree = (MlTree *)NULL; 00544 } 00545 } 00546 00547 if (verbosity > 1) 00548 (void) fprintf(vis_stdout,"%s[%d] quotient\n", space, level); 00549 q_tree_exist = 0; 00550 if (q_tree) { 00551 q_ref = 1; 00552 q_tree_exist = 1; 00553 } else if (comp_q_tree) { 00554 q_tree = comp_q_tree; 00555 q_ref = 1; 00556 if (verbosity > 1) { 00557 sprintf(comp_mess, "%s\t(C) : ", space); 00558 SynthPrintZddTreeMessage(dd, q, comp_mess); 00559 } 00560 } else { 00561 q_tree = (* factoring_func)(dd, table, q, level + 1,&q_ref, 00562 NULL, 0, NULL, verbosity); 00563 if (!q_tree) { 00564 bdd_recursive_deref_zdd(dd, d); 00565 bdd_recursive_deref_zdd(dd, q); 00566 return(NULL); 00567 } 00568 if (MlTree_IsComplement(q_tree)) { 00569 q_tree = MlTree_Regular(q_tree); 00570 comp_q_tree = q_tree; 00571 } else 00572 bdd_ref(q_tree->node); 00573 } 00574 tmp_tree = q_tree; 00575 q_tree = SynthCheckAndMakeComplement(dd, table, q_tree, &comp_flag, 00576 verbosity); 00577 if (!q_tree) { 00578 bdd_recursive_deref_zdd(dd, d); 00579 bdd_recursive_deref_zdd(dd, q); 00580 if (comp_q_tree != q_tree) 00581 bdd_recursive_deref_zdd(dd, q_tree->node); 00582 return(NULL); 00583 } else if (q_tree != tmp_tree) { 00584 if (comp_flag) 00585 comp_q_tree = q_tree; 00586 q_ref = 1; 00587 } 00588 00589 r_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &r_ref, verbosity); 00590 if (!r_tree) { 00591 bdd_recursive_deref_zdd(dd, d); 00592 bdd_recursive_deref_zdd(dd, q); 00593 if (comp_q_tree != q_tree) 00594 bdd_recursive_deref_zdd(dd, q_tree->node); 00595 return(NULL); 00596 } 00597 if (MlTree_IsComplement(r_tree)) { 00598 r_tree = MlTree_Regular(r_tree); 00599 comp_r_tree = r_tree; 00600 } 00601 tmp_tree = r_tree; 00602 r_tree = SynthCheckAndMakeComplement(dd, table, r_tree, &comp_flag, 00603 verbosity); 00604 if (!r_tree) { 00605 bdd_recursive_deref_zdd(dd, d); 00606 bdd_recursive_deref_zdd(dd, q); 00607 if (comp_q_tree != q_tree) 00608 bdd_recursive_deref_zdd(dd, q_tree->node); 00609 return(NULL); 00610 } else if (r_tree != tmp_tree) { 00611 if (comp_flag) 00612 comp_r_tree = r_tree; 00613 r_ref = 1; 00614 } 00615 00616 bdd_recursive_deref_zdd(dd, q); 00617 bdd_recursive_deref_zdd(dd, d); 00618 if ((!q_tree_exist) && (!comp_q_tree)) 00619 bdd_recursive_deref_zdd(dd, q_tree->node); 00620 00621 tree = SynthFindOrCreateMlTree(table, dd, f, 0, 0, ref, verbosity); 00622 if (!tree) 00623 return(NULL); 00624 if (*ref == 1) 00625 (void) fprintf(vis_stdout, "** synth warning: May be duplicate.\n"); 00626 tree->q = q_tree; 00627 tree->d = d_tree; 00628 tree->r = r_tree; 00629 if (comp_q_tree) 00630 tree->q_comp = 1; 00631 if (comp_d_tree) 00632 tree->d_comp = 1; 00633 if (comp_r_tree) 00634 tree->r_comp = 1; 00635 tree->q_ref = q_ref; 00636 tree->d_ref = d_ref; 00637 tree->r_ref = r_ref; 00638 if (verbosity > 1) 00639 SynthPrintMlTreeMessage(dd, tree, message); 00640 SynthPutMlTreeInList(dd, tree, 0); 00641 if (VerifyTreeMode) { 00642 SynthVerifyTree(dd, tree, 0); 00643 SynthVerifyMlTable(dd, table); 00644 } 00645 return(tree); 00646 } else if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) 00647 bdd_recursive_deref_zdd(dd, d); 00648 return(NULL); 00649 } 00650 00651 00663 MlTree * 00664 SynthPostFactorTree(bdd_manager *dd, 00665 st_table *table, 00666 bdd_node *f, 00667 bdd_node *q, 00668 bdd_node *d, 00669 MlTree *bring, 00670 MlTree *comp_d_tree, 00671 int comp_d_flag, 00672 char *message, 00673 int *ref, 00674 int verbosity) 00675 { 00676 bdd_node *one = bdd_read_one(dd); 00677 bdd_node *r; 00678 MlTree *tree, *r_tree, *tmp_tree; 00679 int q_ref, r_ref; 00680 MlTree *comp_r_tree = (MlTree *)NULL; 00681 int comp_flag; 00682 00683 q_ref = r_ref = 0; 00684 00685 r = bdd_zdd_diff(dd, f, d); 00686 if (!r) 00687 return(NULL); 00688 bdd_ref(r); 00689 r_tree = (MlTree *)NULL; 00690 if (st_lookup(table, (char *)r, &r_tree)) { 00691 SynthSetSharedFlag(dd, r_tree); 00692 if (MlTree_Regular(r_tree)->candidate) { 00693 if (!SynthUseCandidate(table, dd, r_tree, verbosity)) { 00694 bdd_recursive_deref_zdd(dd, r); 00695 return(NULL); 00696 } 00697 } 00698 if (MlTree_IsComplement(r_tree)) { 00699 r_tree = MlTree_Regular(r_tree); 00700 comp_r_tree = r_tree; 00701 } 00702 r_ref = 1; 00703 } else { 00704 r_tree = SynthFindOrCreateMlTree(table, dd, r, 1, 0, &r_ref, verbosity); 00705 if (!r_tree) { 00706 bdd_recursive_deref_zdd(dd, r); 00707 return(NULL); 00708 } 00709 if (MlTree_IsComplement(r_tree)) { 00710 comp_r_tree = MlTree_Regular(r_tree); 00711 r_tree = comp_r_tree; 00712 } 00713 tmp_tree = r_tree; 00714 r_tree = SynthCheckAndMakeComplement(dd, table, r_tree, &comp_flag, 00715 verbosity); 00716 if (!r_tree) { 00717 bdd_recursive_deref_zdd(dd, r); 00718 return(NULL); 00719 } else if (r_tree == tmp_tree) { 00720 if (r_ref == 0) 00721 SynthPutMlTreeInList(dd, r_tree, 0); 00722 } else { 00723 if (comp_flag) 00724 comp_r_tree = r_tree; 00725 r_ref = 1; 00726 } 00727 } 00728 bdd_recursive_deref_zdd(dd, r); 00729 00730 if (bring) 00731 tree = bring; 00732 else { 00733 tree = SynthFindOrCreateMlTree(table, dd, f, 0, 0, ref, verbosity); 00734 if (!tree) 00735 return(NULL); 00736 if (*ref) 00737 (void)fprintf(vis_stdout, "** synth warning: May be duplicate.\n"); 00738 } 00739 tree->q = SynthFindOrCreateMlTree(table, dd, one, 1, 0, &q_ref, verbosity); 00740 if (!tree->q) 00741 return(NULL); 00742 if (MlTree_IsComplement(tree->q)) { 00743 tree->q = MlTree_Regular(tree->q); 00744 tree->q_comp = 1; 00745 } 00746 tree->d = comp_d_tree; 00747 tree->r = r_tree; 00748 tree->d_comp = comp_d_flag; 00749 if (comp_r_tree) 00750 tree->r_comp = 1; 00751 tree->q_ref = q_ref; 00752 tree->d_ref = 1; 00753 tree->r_ref = r_ref; 00754 if (verbosity > 1) 00755 SynthPrintMlTreeMessage(dd, tree, message); 00756 if (bring) 00757 bring->leaf = 0; 00758 else 00759 SynthPutMlTreeInList(dd, tree, 0); 00760 if (VerifyTreeMode) { 00761 SynthVerifyTree(dd, tree, 0); 00762 SynthVerifyMlTable(dd, table); 00763 } 00764 return(tree); 00765 } 00766 00767 00781 MlTree * 00782 SynthFactorTreeRecur(bdd_manager *dd, 00783 st_table *table, 00784 MlTree *(* factoring_func)(bdd_manager *, st_table *, 00785 bdd_node *, int, int *, 00786 MlTree *, int, MlTree *, int), 00787 bdd_node *f, 00788 bdd_node *q, 00789 bdd_node *d, 00790 bdd_node *r, 00791 bdd_node *m, 00792 MlTree *q_tree, 00793 MlTree *d_tree, 00794 MlTree *r_tree, 00795 MlTree *comp_q_tree, 00796 MlTree *comp_d_tree, 00797 MlTree *comp_r_tree, 00798 MlTree *bring, 00799 int level, 00800 char *space, 00801 char *message, 00802 int *ref, 00803 int verbosity) 00804 { 00805 bdd_node *one = bdd_read_one(dd); 00806 bdd_node *zero = bdd_read_zero(dd); 00807 int q_tree_exist, d_tree_exist, r_tree_exist; 00808 MlTree *m_tree; 00809 MlTree *tree, *tmp_tree; 00810 int q_ref, d_ref, r_ref, m_ref; 00811 char comp_mess[120]; 00812 int comp_flag; 00813 00814 q_ref = d_ref = r_ref = 0; 00815 00816 if (verbosity > 1) 00817 (void) fprintf(vis_stdout,"%s[%d] quotient\n", space, level); 00818 q_tree_exist = 0; 00819 if (q_tree) { 00820 q_ref = 1; 00821 q_tree_exist = 1; 00822 } else if (comp_q_tree) { 00823 q_tree = comp_q_tree; 00824 q_ref = 1; 00825 if (verbosity > 1) { 00826 sprintf(comp_mess, "%s\t(C) : ", space); 00827 SynthPrintZddTreeMessage(dd, q, comp_mess); 00828 } 00829 } else { 00830 q_tree = (* factoring_func)(dd, table, q, level + 1, 00831 &q_ref, NULL, 0, NULL, verbosity); 00832 if (!q_tree) 00833 return(NULL); 00834 if (MlTree_IsComplement(q_tree)) { 00835 q_tree = MlTree_Regular(q_tree); 00836 comp_q_tree = q_tree; 00837 } else 00838 bdd_ref(q_tree->node); 00839 } 00840 tmp_tree = q_tree; 00841 q_tree = SynthCheckAndMakeComplement(dd, table, q_tree, &comp_flag, 00842 verbosity); 00843 if (!q_tree) { 00844 if (comp_q_tree != tmp_tree) 00845 bdd_recursive_deref_zdd(dd, tmp_tree->node); 00846 if (q_ref == 0) 00847 SynthFreeMlTree(MlTree_Regular(tmp_tree), 1); 00848 return(NULL); 00849 } else if (q_tree != tmp_tree) { 00850 if (comp_flag) 00851 comp_q_tree = q_tree; 00852 q_ref = 1; 00853 } 00854 00855 if (verbosity > 1) 00856 (void)fprintf(vis_stdout,"%s[%d] divisor\n", space, level); 00857 d_tree_exist = 0; 00858 if (d_tree) { 00859 d_ref = 1; 00860 d_tree_exist = 1; 00861 } else if (comp_d_tree) { 00862 d_tree = comp_d_tree; 00863 d_ref = 1; 00864 if (verbosity > 1) { 00865 sprintf(comp_mess, "%s\t(C) : ", space); 00866 SynthPrintZddTreeMessage(dd, d, comp_mess); 00867 } 00868 } else { 00869 d_tree = (* factoring_func)(dd, table, d, level + 1, &d_ref, 00870 NULL, 0, NULL, verbosity); 00871 if (!d_tree) { 00872 if (comp_q_tree != q_tree) 00873 bdd_recursive_deref_zdd(dd, q_tree->node); 00874 if (q_ref == 0) 00875 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00876 return(NULL); 00877 } 00878 if (MlTree_IsComplement(d_tree)) { 00879 d_tree = MlTree_Regular(d_tree); 00880 comp_d_tree = d_tree; 00881 } else 00882 bdd_ref(d_tree->node); 00883 } 00884 tmp_tree = d_tree; 00885 d_tree = SynthCheckAndMakeComplement(dd, table, d_tree, &comp_flag, 00886 verbosity); 00887 if (!d_tree) { 00888 if (comp_q_tree != q_tree) 00889 bdd_recursive_deref_zdd(dd, q_tree->node); 00890 if (comp_d_tree != tmp_tree) 00891 bdd_recursive_deref_zdd(dd, tmp_tree->node); 00892 if (q_ref == 0) 00893 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00894 if (d_ref == 0) 00895 SynthFreeMlTree(MlTree_Regular(tmp_tree), 1); 00896 return(NULL); 00897 } else if (d_tree != tmp_tree) { 00898 if (comp_flag) 00899 comp_d_tree = d_tree; 00900 d_ref = 1; 00901 } 00902 00903 m_tree = (MlTree *)NULL; 00904 m_ref = 0; 00905 if (UseMtree && m != f) { 00906 m_tree = SynthFindOrCreateMlTree(table, dd, m, 0, 1, &m_ref, verbosity); 00907 if (!m_tree) { 00908 if (comp_q_tree != q_tree) 00909 bdd_recursive_deref_zdd(dd, q_tree->node); 00910 if (comp_d_tree != d_tree) 00911 bdd_recursive_deref_zdd(dd, d_tree->node); 00912 if (q_ref == 0) 00913 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00914 if (d_ref == 0) 00915 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00916 return(NULL); 00917 } 00918 if (m_ref == 0) { 00919 m_tree->q = q_tree; 00920 m_tree->d = d_tree; 00921 m_tree->r = (MlTree *)NULL; 00922 if (comp_q_tree) 00923 m_tree->q_comp = 1; 00924 if (comp_d_tree) 00925 m_tree->d_comp = 1; 00926 m_tree->q_ref = q_ref; 00927 m_tree->d_ref = d_ref; 00928 m_tree->r_ref = 0; 00929 00930 tmp_tree = m_tree; 00931 m_tree = SynthCheckAndMakeComplement(dd, table, m_tree, &comp_flag, 00932 verbosity); 00933 if (!m_tree) { 00934 if (comp_q_tree != q_tree) 00935 bdd_recursive_deref_zdd(dd, q_tree->node); 00936 if (comp_d_tree != d_tree) 00937 bdd_recursive_deref_zdd(dd, d_tree->node); 00938 if (q_ref == 0) 00939 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00940 if (d_ref == 0) 00941 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00942 return(NULL); 00943 } else if (m_tree == tmp_tree) 00944 SynthPutMlTreeInList(dd, m_tree, 1); 00945 else { 00946 if (m_tree->candidate) 00947 SynthPutMlTreeInList(dd, m_tree, 1); 00948 else 00949 m_tree = NIL(MlTree); 00950 } 00951 if (m_tree && VerifyTreeMode) { 00952 SynthVerifyTree(dd, m_tree, 0); 00953 SynthVerifyMlTable(dd, table); 00954 } 00955 } 00956 } 00957 00958 if (verbosity > 1) 00959 (void)fprintf(vis_stdout,"%s[%d] remainder\n", space, level); 00960 r_tree_exist = 0; 00961 if (r_tree) { 00962 r_ref = 1; 00963 r_tree_exist = 1; 00964 } else if (comp_r_tree) { 00965 r_tree = comp_r_tree; 00966 r_ref = 1; 00967 if (verbosity > 1) { 00968 sprintf(comp_mess, "%s\t(C) : ", space); 00969 SynthPrintZddTreeMessage(dd, r, comp_mess); 00970 } 00971 } else if (comp_d_tree) { 00972 r_tree = (* factoring_func)(dd, table, r, level + 1, 00973 &r_ref, NULL, 0, NULL, verbosity); 00974 if (!r_tree) { 00975 if (comp_q_tree != q_tree) 00976 bdd_recursive_deref_zdd(dd, q_tree->node); 00977 if (comp_d_tree != d_tree) 00978 bdd_recursive_deref_zdd(dd, d_tree->node); 00979 if (q_ref == 0) 00980 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00981 if (d_ref == 0) 00982 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00983 if (m_tree && m_ref == 0) 00984 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 00985 return(NULL); 00986 } 00987 if (MlTree_IsComplement(r_tree)) { 00988 r_tree = MlTree_Regular(r_tree); 00989 comp_r_tree = r_tree; 00990 } else 00991 bdd_ref(r_tree->node); 00992 } else { 00993 if (Resubstitution) { 00994 r_tree = (* factoring_func)(dd, table, r, level + 1, 00995 &r_ref, d_tree, 1, NULL, verbosity); 00996 if (!r_tree && (bdd_read_reordered_field(dd) || noMemoryFlag == 1)) { 00997 if (comp_q_tree != q_tree) 00998 bdd_recursive_deref_zdd(dd, q_tree->node); 00999 if (comp_d_tree != d_tree) 01000 bdd_recursive_deref_zdd(dd, d_tree->node); 01001 if (q_ref == 0) 01002 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01003 if (d_ref == 0) 01004 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01005 if (m_tree && m_ref == 0) 01006 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01007 return(NULL); 01008 } 01009 } 01010 if (!r_tree) { 01011 r_tree = (* factoring_func)(dd, table, r, level + 1, 01012 &r_ref, NULL, 0, NULL, verbosity); 01013 if (!r_tree) { 01014 if (comp_q_tree != q_tree) 01015 bdd_recursive_deref_zdd(dd, q_tree->node); 01016 if (comp_d_tree != d_tree) 01017 bdd_recursive_deref_zdd(dd, d_tree->node); 01018 if (q_ref == 0) 01019 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01020 if (d_ref == 0) 01021 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01022 if (m_tree && m_ref == 0) 01023 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01024 return(NULL); 01025 } 01026 } else { 01027 if (r != one && r != zero) 01028 SynthSetSharedFlag(dd, d_tree); 01029 } 01030 if (MlTree_IsComplement(r_tree)) { 01031 r_tree = MlTree_Regular(r_tree); 01032 comp_r_tree = r_tree; 01033 } else 01034 bdd_ref(r_tree->node); 01035 } 01036 if (RemainderComplement) { 01037 tmp_tree = r_tree; 01038 r_tree = SynthCheckAndMakeComplement(dd, table, r_tree, &comp_flag, 01039 verbosity); 01040 if (!r_tree) { 01041 if (comp_q_tree != q_tree) 01042 bdd_recursive_deref_zdd(dd, q_tree->node); 01043 if (comp_d_tree != d_tree) 01044 bdd_recursive_deref_zdd(dd, d_tree->node); 01045 if (comp_r_tree != tmp_tree) 01046 bdd_recursive_deref_zdd(dd, tmp_tree->node); 01047 if (q_ref == 0) 01048 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01049 if (d_ref == 0) 01050 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01051 if (r_ref == 0) 01052 SynthFreeMlTree(MlTree_Regular(tmp_tree), 1); 01053 if (m_tree && m_ref == 0) 01054 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01055 return(NULL); 01056 } else if (r_tree != tmp_tree) { 01057 if (comp_flag) 01058 comp_r_tree = r_tree; 01059 r_ref = 1; 01060 } 01061 } 01062 01063 if ((!q_tree_exist) && (!comp_q_tree)) 01064 bdd_recursive_deref_zdd(dd, q_tree->node); 01065 if ((!d_tree_exist) && (!comp_d_tree)) 01066 bdd_recursive_deref_zdd(dd, d_tree->node); 01067 if ((!r_tree_exist) && (!comp_r_tree)) 01068 bdd_recursive_deref_zdd(dd, r_tree->node); 01069 01070 if (bring) { 01071 tree = bring; 01072 tree->leaf = 0; 01073 tree->q = q_tree; 01074 tree->d = d_tree; 01075 tree->r = r_tree; 01076 if (comp_q_tree) 01077 tree->q_comp = 1; 01078 if (comp_d_tree) 01079 tree->d_comp = 1; 01080 if (comp_r_tree) 01081 tree->r_comp = 1; 01082 tree->q_ref = q_ref; 01083 tree->d_ref = d_ref; 01084 tree->r_ref = r_ref; 01085 if (UseMtree && m_tree && m_ref == 0) { 01086 MlTree_Regular(m_tree)->r = tree; 01087 if (m_tree->r->id == 0) { 01088 assert(0); 01089 /* 01090 if (!SynthUseCandidate(table, dd, m_tree, verbosity)) { 01091 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01092 return(NULL); 01093 } 01094 */ 01095 } 01096 } 01097 if (verbosity > 1) 01098 SynthPrintMlTreeMessage(dd, tree, message); 01099 if (VerifyTreeMode) { 01100 SynthVerifyTree(dd, tree, 0); 01101 SynthVerifyMlTable(dd, table); 01102 } 01103 return(tree); 01104 } 01105 01106 tree = SynthFindOrCreateMlTree(table, dd, f, 0, 0, ref, verbosity); 01107 if (!tree) { 01108 if (q_ref == 0) 01109 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01110 if (d_ref == 0) 01111 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01112 if (r_ref == 0) 01113 SynthFreeMlTree(MlTree_Regular(r_tree), 1); 01114 if (m_tree && m_ref == 0) 01115 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01116 return(NULL); 01117 } 01118 if (*ref == 1) 01119 (void)fprintf(vis_stdout, "** synth warning: May be duplicate.\n"); 01120 tree->q = q_tree; 01121 tree->d = d_tree; 01122 tree->r = r_tree; 01123 if (comp_q_tree) 01124 tree->q_comp = 1; 01125 if (comp_d_tree) 01126 tree->d_comp = 1; 01127 if (comp_r_tree) 01128 tree->r_comp = 1; 01129 tree->q_ref = q_ref; 01130 tree->d_ref = d_ref; 01131 tree->r_ref = r_ref; 01132 if (UseMtree && m_tree && m_ref == 0) { 01133 MlTree_Regular(m_tree)->r = tree; 01134 if (m_tree->r->id == 0) { 01135 assert(0); 01136 /* 01137 if (!SynthUseCandidate(table, dd, m_tree, verbosity)) { 01138 SynthFreeMlTree(MlTree_Regular(tree), 1); 01139 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01140 return(NULL); 01141 } 01142 */ 01143 } 01144 } 01145 if (verbosity > 1) 01146 SynthPrintMlTreeMessage(dd, tree, message); 01147 SynthPutMlTreeInList(dd, tree, 0); 01148 if (VerifyTreeMode) { 01149 SynthVerifyTree(dd, tree, 0); 01150 SynthVerifyMlTable(dd, table); 01151 } 01152 return(tree); 01153 } 01154 01155 01156 /*---------------------------------------------------------------------------*/ 01157 /* Definition of static functions */ 01158 /*---------------------------------------------------------------------------*/ 01159 01171 static int 01172 CountZddLeafLiterals(bdd_manager *dd, 01173 bdd_node *node) 01174 { 01175 int i, *support; 01176 int count = 0; 01177 int sizeZ = bdd_num_zdd_vars(dd); 01178 01179 support = ALLOC(int, sizeZ); 01180 if (!support) 01181 return(-1); 01182 (void)memset((void *)support, 0, sizeof(int) * sizeZ); 01183 SynthZddSupportStep(bdd_regular(node), support); 01184 SynthZddClearFlag(bdd_regular(node)); 01185 for (i = 0; i < sizeZ; i++) { 01186 if (support[i]) 01187 count++; 01188 } 01189 FREE(support); 01190 return(count); 01191 }