VIS
|
00001 00019 #include "synthInt.h" 00020 00021 static char rcsid[] UNUSED = "$Id: synthGen.c,v 1.36 2005/05/11 20:17:21 hhhan 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 UseMtree; 00043 extern int UseCommonDivisor; 00044 extern int TryNodeSharing; 00045 extern int Resubstitution; 00046 extern int RemainderComplement; 00047 extern int noMemoryFlag; 00048 extern int VerifyTreeMode; 00049 00052 /*---------------------------------------------------------------------------*/ 00053 /* Static function prototypes */ 00054 /*---------------------------------------------------------------------------*/ 00055 00056 static MlTree * LiteralFactoringTree(bdd_manager *dd, st_table *table, bdd_node *f, bdd_node *c, int level, int *ref, MlTree *bring, int verbosity); 00057 static bdd_node * BestLiteral(bdd_manager *dd, bdd_node *f, bdd_node *c); 00058 static int IsCubeFree(bdd_manager *dd, bdd_node *f); 00059 static bdd_node * CommonCube(bdd_manager *dd, bdd_node *f); 00060 00064 /*---------------------------------------------------------------------------*/ 00065 /* Definition of exported functions */ 00066 /*---------------------------------------------------------------------------*/ 00067 00068 00069 00070 /*---------------------------------------------------------------------------*/ 00071 /* Definition of internal functions */ 00072 /*---------------------------------------------------------------------------*/ 00073 00097 MlTree * 00098 SynthGenericFactorTree(bdd_manager *dd, 00099 st_table *table, 00100 bdd_node *f, 00101 int level, 00102 int *ref, 00103 MlTree *comp_d_tree, 00104 int comp_d_flag, 00105 MlTree *bring, 00106 int verbosity) 00107 { 00108 bdd_node *one = bdd_read_one(dd); 00109 bdd_node *zero = bdd_read_zero(dd); 00110 bdd_node *d, *q, *r, *m, *c; 00111 MlTree *tree, *q_tree, *d_tree, *r_tree; 00112 int q_ref, d_ref, r_ref; 00113 int ncubes; 00114 bdd_node *tmp; 00115 char message[80]; 00116 char space[80]; 00117 MlTree *comp_q_tree = (MlTree *)NULL; 00118 MlTree *comp_r_tree = (MlTree *)NULL; 00119 int found; 00120 MlTree *tmp_tree; 00121 int comp_flag; 00122 00123 if (verbosity > 1) { 00124 SynthGetSpaceString(space, level * 2, 80); 00125 sprintf(message, "%s[%d] in : ", space, level); 00126 SynthPrintZddTreeMessage(dd, f, message); 00127 sprintf(message, "%s[%d]out : ", space, level); 00128 } 00129 00130 if (bring) 00131 tree = (MlTree *)NULL; 00132 else { 00133 tree = SynthLookupMlTable(table, dd, f, 1, verbosity); 00134 /* tree could be NULL because of reordering, or a failure to 00135 * allocate memory or just that f was not in the cache. 00136 * So, we would like return NULL ONLY in the case of 00137 * reordering or failure to allocate memory. 00138 */ 00139 if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) 00140 return(NULL); 00141 } 00142 if (tree) { 00143 if (verbosity > 1) 00144 SynthPrintMlTreeMessage(dd, tree, message); 00145 *ref = 1; 00146 return(tree); 00147 } 00148 00149 if (f == one || f == zero) { 00150 tree = SynthFindOrCreateMlTree(table, dd, f, 1, 0, ref, verbosity); 00151 if (!tree) 00152 return(NULL); 00153 tmp_tree = tree; 00154 tree = SynthCheckAndMakeComplement(dd, table, tree, &comp_flag, verbosity); 00155 if (!tree) { 00156 if (*ref == 0) 00157 SynthFreeMlTree(MlTree_Regular(tmp_tree), 1); 00158 return(NULL); 00159 } else if (tree != tmp_tree) { 00160 *ref = 1; 00161 if (comp_flag) 00162 tree = MlTree_Not(tree); 00163 } 00164 if (verbosity > 1) 00165 SynthPrintMlTreeMessage(dd, tree, message); 00166 return(tree); 00167 } 00168 00169 d_tree = (MlTree *)NULL; 00170 if (comp_d_tree) { 00171 if (comp_d_flag) 00172 d = comp_d_tree->complement; 00173 else 00174 d = comp_d_tree->node; 00175 if (!d) 00176 return((MlTree *)NULL); 00177 bdd_ref(d); 00178 } else { 00179 found = 0; 00180 d = (* SynthGetZddDivisorFunc())(dd, f); 00181 if (!d) 00182 return(NULL); 00183 bdd_ref(d); 00184 if (TryNodeSharing) { 00185 /* Here, we don't need to call bdd_ref. */ 00186 d = SynthFindBiggerDivisorInList(dd, table, f, d, &found, 00187 &comp_d_flag, &comp_d_tree, verbosity); 00188 if (!d) 00189 return(NULL); 00190 } 00191 if (UseCommonDivisor && found == 0) { 00192 tree = SynthGetFactorTreeWithCommonDivisor(dd, table, 00193 SynthGenericFactorTree, f, d, level, ref, verbosity); 00194 if (tree) 00195 return(tree); 00196 if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) { 00197 bdd_recursive_deref_zdd(dd, d); 00198 return(NULL); 00199 } 00200 } 00201 } 00202 if (d == f) { 00203 tree = SynthFindOrCreateMlTree(table, dd, f, 1, 0, ref, verbosity); 00204 if (!tree) { 00205 bdd_recursive_deref_zdd(dd, d); 00206 return(NULL); 00207 } 00208 if (verbosity > 1) 00209 SynthPrintMlTreeMessage(dd, tree, message); 00210 tmp_tree = tree; 00211 tree = SynthCheckAndMakeComplement(dd, table, tree, &comp_flag, verbosity); 00212 if (!tree) { 00213 bdd_recursive_deref_zdd(dd, d); 00214 return(NULL); 00215 } else if (tree == tmp_tree) { 00216 if (*ref == 0) 00217 SynthPutMlTreeInList(dd, tree, 0); 00218 } else { 00219 *ref = 1; 00220 if (comp_flag) 00221 tree = MlTree_Not(tree); 00222 } 00223 bdd_recursive_deref_zdd(dd, d); 00224 return(tree); 00225 } 00226 if (!comp_d_tree) { 00227 if (st_lookup(table, (char *)d, &d_tree)) { 00228 SynthSetSharedFlag(dd, d_tree); 00229 if (MlTree_Regular(d_tree)->candidate) { 00230 if (!SynthUseCandidate(table, dd, d_tree, verbosity)) { 00231 bdd_recursive_deref_zdd(dd, d); 00232 return(NULL); 00233 } 00234 } 00235 if (MlTree_IsComplement(d_tree)) { 00236 d_tree = MlTree_Regular(d_tree); 00237 comp_d_tree = d_tree; 00238 comp_d_flag = 1; 00239 d_tree = (MlTree *)NULL; 00240 } 00241 else 00242 comp_d_flag = 0; 00243 } 00244 } else { 00245 if (!comp_d_flag) 00246 d_tree = comp_d_tree; 00247 } 00248 00249 q = (* SynthGetZddDivideFunc())(dd, f, d); 00250 if (!q) { 00251 bdd_recursive_deref_zdd(dd, d); 00252 return(NULL); 00253 } 00254 bdd_ref(q); 00255 if (comp_d_tree && q == zero) { 00256 bdd_recursive_deref_zdd(dd, d); 00257 bdd_recursive_deref_zdd(dd, q); 00258 return((MlTree *)NULL); 00259 } 00260 if (q == one) { 00261 bdd_recursive_deref_zdd(dd, q); 00262 tree = SynthPostFactorTree(dd, table, f, q, d, bring, 00263 comp_d_tree, comp_d_flag, message, ref, verbosity); 00264 bdd_recursive_deref_zdd(dd, d); 00265 return(tree); 00266 } 00267 00268 ncubes = bdd_zdd_count(dd, q); 00269 if (ncubes == 1) { 00270 if (d_tree || comp_d_tree) { 00271 m = (* SynthGetZddProductFunc())(dd, q, d); 00272 if (!m) { 00273 bdd_recursive_deref_zdd(dd, d); 00274 bdd_recursive_deref_zdd(dd, q); 00275 return(NULL); 00276 } 00277 bdd_ref(m); 00278 bdd_recursive_deref_zdd(dd, d); 00279 r = bdd_zdd_diff(dd, f, m); 00280 bdd_recursive_deref_zdd(dd, m); 00281 if (!r) { 00282 bdd_recursive_deref_zdd(dd, q); 00283 return(NULL); 00284 } 00285 bdd_ref(r); 00286 bdd_recursive_deref_zdd(dd,r); 00287 if (r == zero) { 00288 if (!d_tree) 00289 d_tree = comp_d_tree; 00290 d_ref = 1; 00291 q_tree = (MlTree *)NULL; 00292 if (st_lookup(table, (char *)q, &q_tree)) { 00293 SynthSetSharedFlag(dd, q_tree); 00294 if (MlTree_Regular(q_tree)->candidate) { 00295 if (!SynthUseCandidate(table, dd, q_tree, verbosity)) { 00296 bdd_recursive_deref_zdd(dd, q); 00297 return(NULL); 00298 } 00299 } 00300 if (MlTree_IsComplement(q_tree)) { 00301 q_tree = MlTree_Regular(q_tree); 00302 comp_q_tree = q_tree; 00303 } 00304 q_ref = 1; 00305 } else { 00306 q_tree = SynthFindOrCreateMlTree(table, dd, q, 1, 00307 0, &q_ref, verbosity); 00308 if (!q_tree) { 00309 bdd_recursive_deref_zdd(dd, q); 00310 return(NULL); 00311 } 00312 if (MlTree_IsComplement(q_tree)) { 00313 comp_q_tree = MlTree_Regular(q_tree); 00314 q_tree = comp_q_tree; 00315 } 00316 tmp_tree = q_tree; 00317 q_tree = SynthCheckAndMakeComplement(dd, table, q_tree, &comp_flag, 00318 verbosity); 00319 if (!q_tree) { 00320 bdd_recursive_deref_zdd(dd, q); 00321 return(NULL); 00322 } else if (q_tree == tmp_tree) { 00323 if (q_ref == 0) 00324 SynthPutMlTreeInList(dd, q_tree, 0); 00325 } else { 00326 if (comp_flag) 00327 comp_q_tree = q_tree; 00328 q_ref = 1; 00329 } 00330 } 00331 bdd_recursive_deref_zdd(dd, q); 00332 00333 if (bring) { 00334 tree = bring; 00335 tree->leaf = 0; 00336 tree->q = q_tree; 00337 tree->d = d_tree; 00338 tree->r = SynthFindOrCreateMlTree(table, dd, zero, 00339 1, 0, &r_ref, verbosity); 00340 if (!tree->r) 00341 return(NULL); 00342 if (MlTree_IsComplement(tree->r)) { 00343 tree->r = MlTree_Regular(tree->r); 00344 tree->r_comp = 1; 00345 } 00346 if (comp_q_tree) 00347 tree->q_comp = 1; 00348 if (comp_d_flag) 00349 tree->d_comp = 1; 00350 tree->q_ref = q_ref; 00351 tree->d_ref = d_ref; 00352 tree->r_ref = r_ref; 00353 if (verbosity > 1) 00354 SynthPrintMlTreeMessage(dd, tree, message); 00355 if (VerifyTreeMode) { 00356 SynthVerifyTree(dd, tree, 0); 00357 SynthVerifyMlTable(dd, table); 00358 } 00359 return(tree); 00360 } 00361 00362 tree = SynthFindOrCreateMlTree(table, dd, f, 0, 0, ref, verbosity); 00363 if (!tree) 00364 return(NULL); 00365 if (*ref) 00366 (void) fprintf(vis_stdout, 00367 "** synth warning: May be duplicate.\n"); 00368 tree->q = q_tree; 00369 tree->d = d_tree; 00370 tree->r = SynthFindOrCreateMlTree(table, dd, zero, 1, 00371 0, &r_ref, verbosity); 00372 if (!tree->r) 00373 return(NULL); 00374 if (MlTree_IsComplement(tree->r)) { 00375 tree->r = MlTree_Regular(tree->r); 00376 tree->r_comp = 1; 00377 } 00378 if (comp_q_tree) 00379 tree->q_comp = 1; 00380 if (comp_d_flag) 00381 tree->d_comp = 1; 00382 tree->q_ref = q_ref; 00383 tree->d_ref = d_ref; 00384 tree->r_ref = r_ref; 00385 if (verbosity > 1) 00386 SynthPrintMlTreeMessage(dd, tree, message); 00387 SynthPutMlTreeInList(dd, tree, 0); 00388 if (VerifyTreeMode) { 00389 SynthVerifyTree(dd, tree, 0); 00390 SynthVerifyMlTable(dd, table); 00391 } 00392 return(tree); 00393 } 00394 } else 00395 bdd_recursive_deref_zdd(dd, d); 00396 00397 tree = LiteralFactoringTree(dd, table, f, q, level + 1, ref, 00398 bring, verbosity); 00399 if (!tree) { 00400 bdd_recursive_deref_zdd(dd, q); 00401 return(NULL); 00402 } 00403 tmp_tree = tree; 00404 tree = SynthCheckAndMakeComplement(dd, table, tree, &comp_flag, verbosity); 00405 if (!tree) { 00406 bdd_recursive_deref_zdd(dd, q); 00407 return(NULL); 00408 } else if (tree != tmp_tree) { 00409 *ref = 1; 00410 if (comp_flag) 00411 tree = MlTree_Not(tree); 00412 } 00413 bdd_recursive_deref_zdd(dd, q); 00414 00415 if (verbosity > 1) 00416 SynthPrintMlTreeMessage(dd, tree, message); 00417 return(tree); 00418 } 00419 bdd_recursive_deref_zdd(dd, d); 00420 00421 d_tree = comp_d_tree = (MlTree *)NULL; 00422 00423 tmp = q; 00424 q = SynthMakeCubeFree(dd, q); 00425 if (!q) { 00426 bdd_recursive_deref_zdd(dd,tmp); 00427 return(NULL); 00428 } 00429 bdd_ref(q); 00430 bdd_recursive_deref_zdd(dd,tmp); 00431 00432 q_tree = (MlTree *)NULL; 00433 if (st_lookup(table, (char *)q, &q_tree)) { 00434 SynthSetSharedFlag(dd, q_tree); 00435 if (MlTree_Regular(q_tree)->candidate) { 00436 if (!SynthUseCandidate(table, dd, q_tree, verbosity)) { 00437 bdd_recursive_deref_zdd(dd, q); 00438 return(NULL); 00439 } 00440 } 00441 if (MlTree_IsComplement(q_tree)) { 00442 q_tree = MlTree_Regular(q_tree); 00443 comp_q_tree = q_tree; 00444 q_tree = (MlTree *)NULL; 00445 } 00446 } 00447 00448 d = (* SynthGetZddDivideFunc())(dd, f, q); 00449 if (!d) { 00450 bdd_recursive_deref_zdd(dd, q); 00451 return(NULL); 00452 } 00453 bdd_ref(d); 00454 d_tree = (MlTree *)NULL; 00455 if (st_lookup(table, (char *)d, &d_tree)) { 00456 SynthSetSharedFlag(dd, d_tree); 00457 if (MlTree_Regular(d_tree)->candidate) { 00458 if (!SynthUseCandidate(table, dd, d_tree, verbosity)) { 00459 bdd_recursive_deref_zdd(dd, d); 00460 bdd_recursive_deref_zdd(dd, q); 00461 return(NULL); 00462 } 00463 } 00464 if (MlTree_IsComplement(d_tree)) { 00465 d_tree = MlTree_Regular(d_tree); 00466 comp_d_tree = d_tree; 00467 d_tree = (MlTree *)NULL; 00468 } 00469 } 00470 00471 m = (* SynthGetZddProductFunc())(dd, d, q); 00472 if (!m) { 00473 bdd_recursive_deref_zdd(dd, d); 00474 bdd_recursive_deref_zdd(dd, q); 00475 return(NULL); 00476 } 00477 bdd_ref(m); 00478 r = bdd_zdd_diff(dd, f, m); 00479 if (!r) { 00480 bdd_recursive_deref_zdd(dd, d); 00481 bdd_recursive_deref_zdd(dd, q); 00482 bdd_recursive_deref_zdd(dd, m); 00483 return(NULL); 00484 } 00485 bdd_ref(r); 00486 00487 r_tree = (MlTree *)NULL; 00488 if (st_lookup(table, (char *)r, &r_tree)) { 00489 SynthSetSharedFlag(dd, r_tree); 00490 if (MlTree_Regular(r_tree)->candidate) { 00491 if (!SynthUseCandidate(table, dd, r_tree, verbosity)) { 00492 bdd_recursive_deref_zdd(dd, d); 00493 bdd_recursive_deref_zdd(dd, q); 00494 bdd_recursive_deref_zdd(dd, m); 00495 bdd_recursive_deref_zdd(dd, r); 00496 return(NULL); 00497 } 00498 } 00499 if (MlTree_IsComplement(r_tree)) { 00500 r_tree = MlTree_Regular(r_tree); 00501 comp_r_tree = r_tree; 00502 r_tree = (MlTree *)NULL; 00503 } 00504 } 00505 00506 if (IsCubeFree(dd, d)) { 00507 tree = SynthFactorTreeRecur(dd, table, SynthGenericFactorTree, 00508 f, q, d, r, m, q_tree, d_tree, r_tree, 00509 comp_q_tree, comp_d_tree, comp_r_tree, 00510 bring, level, space, message, ref, verbosity); 00511 bdd_recursive_deref_zdd(dd, d); 00512 bdd_recursive_deref_zdd(dd, q); 00513 bdd_recursive_deref_zdd(dd, m); 00514 bdd_recursive_deref_zdd(dd, r); 00515 return(tree); 00516 } 00517 00518 bdd_recursive_deref_zdd(dd, q); 00519 bdd_recursive_deref_zdd(dd, r); 00520 00521 c = CommonCube(dd, d); 00522 if (!c) { 00523 bdd_recursive_deref_zdd(dd, d); 00524 return(NULL); 00525 } 00526 bdd_ref(c); 00527 bdd_recursive_deref_zdd(dd, d); 00528 tree = LiteralFactoringTree(dd, table, f, c, level + 1, 00529 ref, bring, verbosity); 00530 if (!tree) { 00531 bdd_recursive_deref_zdd(dd, c); 00532 return(NULL); 00533 } 00534 tmp_tree = tree; 00535 tree = SynthCheckAndMakeComplement(dd, table, tree, &comp_flag, verbosity); 00536 if (!tree) { 00537 bdd_recursive_deref_zdd(dd, c); 00538 if (*ref == 0) 00539 SynthFreeMlTree(MlTree_Regular(tree), 1); 00540 return(NULL); 00541 } else if (tree != tmp_tree) { 00542 *ref = 1; 00543 if (comp_flag) 00544 tree = MlTree_Not(tree); 00545 } 00546 bdd_recursive_deref_zdd(dd, c); 00547 00548 if (verbosity > 1) 00549 SynthPrintMlTreeMessage(dd, tree, message); 00550 if (VerifyTreeMode) { 00551 SynthVerifyTree(dd, tree, 0); 00552 SynthVerifyMlTable(dd, table); 00553 } 00554 return(tree); 00555 } 00556 00557 00570 bdd_node * 00571 SynthMakeCubeFree(bdd_manager *dd, 00572 bdd_node *f) 00573 { 00574 int i, v; 00575 int nvars, max_count, max_pos = 0; 00576 int *count; 00577 bdd_node *one = bdd_read_one(dd); 00578 bdd_node *zero = bdd_read_zero(dd); 00579 bdd_node *divisor, *node; 00580 bdd_node *tmp1, *tmp2; 00581 int ncubes; 00582 00583 if (f == one || f == zero) 00584 return(f); 00585 00586 /* Compare the number of occurrences of each literal to the number of 00587 * cubes in the cover. If no literal appears more than once, or if no 00588 * literal appears in all cubes, f is already cube-free. 00589 */ 00590 ncubes = bdd_zdd_count(dd, f); 00591 v = -1; 00592 max_count = 1; 00593 nvars = bdd_num_zdd_vars(dd); 00594 count = ALLOC(int, nvars); 00595 (void)memset((void *)count, 0, sizeof(int) * nvars); 00596 SynthCountLiteralOccurrence(dd, f, count); 00597 for (i = 0; i < nvars; i++) { 00598 if (count[i] > max_count) { 00599 v = i; 00600 max_count = count[i]; 00601 max_pos = i; 00602 } 00603 } 00604 if (v == -1 || max_count < ncubes) { 00605 FREE(count); 00606 return(f); 00607 } 00608 00609 /* Divide the cover by the first literal appearing in all cubes. */ 00610 node = bdd_zdd_get_node(dd, v, one, zero); 00611 if (!node) { 00612 FREE(count); 00613 return(NULL); 00614 } 00615 bdd_ref(node); 00616 divisor = (* SynthGetZddDivideFunc())(dd, f, node); 00617 if (!divisor) { 00618 bdd_recursive_deref_zdd(dd, node); 00619 FREE(count); 00620 return(NULL); 00621 } 00622 bdd_ref(divisor); 00623 bdd_recursive_deref_zdd(dd, node); 00624 00625 /* Divide the cover by the remaining literals appearing in all cubes. */ 00626 for (i = max_pos + 1; i < nvars; i++) { 00627 if (count[i] == max_count) { 00628 tmp1 = divisor; 00629 tmp2 = bdd_zdd_get_node(dd, i, one, zero); 00630 if (!tmp2) { 00631 FREE(count); 00632 bdd_recursive_deref_zdd(dd, tmp1); 00633 return(NULL); 00634 } 00635 bdd_ref(tmp2); 00636 divisor = (* SynthGetZddDivideFunc())(dd, divisor, tmp2); 00637 if (!divisor) { 00638 FREE(count); 00639 bdd_recursive_deref_zdd(dd, tmp1); 00640 bdd_recursive_deref_zdd(dd, tmp2); 00641 return(NULL); 00642 } 00643 bdd_ref(divisor); 00644 bdd_recursive_deref_zdd(dd, tmp1); 00645 bdd_recursive_deref_zdd(dd, tmp2); 00646 } 00647 } 00648 FREE(count); 00649 bdd_deref(divisor); 00650 return(divisor); 00651 } 00652 00653 00654 /*---------------------------------------------------------------------------*/ 00655 /* Definition of static functions */ 00656 /*---------------------------------------------------------------------------*/ 00657 00669 static MlTree * 00670 LiteralFactoringTree(bdd_manager *dd, 00671 st_table *table, 00672 bdd_node *f, 00673 bdd_node *c, 00674 int level, 00675 int *ref, 00676 MlTree *bring, 00677 int verbosity) 00678 { 00679 bdd_node *one = bdd_read_one(dd); 00680 bdd_node *zero = bdd_read_zero(dd); 00681 bdd_node *l, *q, *r; 00682 bdd_node *m; 00683 char message[80]; 00684 char space[80]; 00685 MlTree *tree, *q_tree, *d_tree, *r_tree; 00686 int q_ref, d_ref, r_ref, m_ref; 00687 char comp_mess[120]; 00688 MlTree *comp_q_tree = (MlTree *)NULL; 00689 MlTree *comp_d_tree = (MlTree *)NULL; 00690 MlTree *comp_r_tree = (MlTree *)NULL; 00691 MlTree *m_tree; 00692 int q_tree_exist, r_tree_exist; 00693 MlTree *tmp_tree; 00694 int comp_flag; 00695 00696 if (verbosity > 1) { 00697 SynthGetSpaceString(space, level * 2, 80); 00698 sprintf(message, "%s[%d] in : ", space, level); 00699 SynthPrintZddTreeMessage(dd, f, message); 00700 sprintf(message, "%s[%d]out : ", space, level); 00701 } 00702 00703 l = BestLiteral(dd, f, c); 00704 if (!l) 00705 return(NULL); 00706 bdd_ref(l); 00707 d_tree = (MlTree *)NULL; 00708 if (st_lookup(table, (char *)l, &d_tree)) { 00709 SynthSetSharedFlag(dd, d_tree); 00710 if (MlTree_Regular(d_tree)->candidate) { 00711 if (!SynthUseCandidate(table, dd, d_tree, verbosity)) { 00712 bdd_recursive_deref_zdd(dd, l); 00713 return(NULL); 00714 } 00715 } 00716 if (MlTree_IsComplement(d_tree)) { 00717 d_tree = MlTree_Regular(d_tree); 00718 comp_d_tree = d_tree; 00719 d_tree = (MlTree *)NULL; 00720 } 00721 } 00722 q = (* SynthGetZddDivideFunc())(dd, f, l); 00723 if (!q) { 00724 bdd_recursive_deref_zdd(dd, l); 00725 return(NULL); 00726 } 00727 bdd_ref(q); 00728 q_tree = (MlTree *)NULL; 00729 if (st_lookup(table, (char *)q, &q_tree)) { 00730 SynthSetSharedFlag(dd, q_tree); 00731 if (MlTree_Regular(q_tree)->candidate) { 00732 if (!SynthUseCandidate(table, dd, q_tree, verbosity)) { 00733 bdd_recursive_deref_zdd(dd, l); 00734 bdd_recursive_deref_zdd(dd, q); 00735 return(NULL); 00736 } 00737 } 00738 if (MlTree_IsComplement(q_tree)) { 00739 q_tree = MlTree_Regular(q_tree); 00740 comp_q_tree = q_tree; 00741 q_tree = (MlTree *)NULL; 00742 } 00743 } 00744 00745 m = (* SynthGetZddProductFunc())(dd, l, q); 00746 if (!m) { 00747 bdd_recursive_deref_zdd(dd, l); 00748 bdd_recursive_deref_zdd(dd, q); 00749 return(NULL); 00750 } 00751 bdd_ref(m); 00752 r = bdd_zdd_diff(dd, f, m); 00753 if (!r) { 00754 bdd_recursive_deref_zdd(dd, l); 00755 bdd_recursive_deref_zdd(dd, q); 00756 bdd_recursive_deref_zdd(dd, m); 00757 return(NULL); 00758 } 00759 bdd_ref(r); 00760 00761 r_tree = (MlTree *)NULL; 00762 if (st_lookup(table, (char *)r, &r_tree)) { 00763 SynthSetSharedFlag(dd, r_tree); 00764 if (MlTree_Regular(r_tree)->candidate) { 00765 if (!SynthUseCandidate(table, dd, r_tree, verbosity)) { 00766 bdd_recursive_deref_zdd(dd, l); 00767 bdd_recursive_deref_zdd(dd, q); 00768 bdd_recursive_deref_zdd(dd, m); 00769 bdd_recursive_deref_zdd(dd, r); 00770 return(NULL); 00771 } 00772 } 00773 if (MlTree_IsComplement(r_tree)) { 00774 r_tree = MlTree_Regular(r_tree); 00775 comp_r_tree = r_tree; 00776 r_tree = (MlTree *)NULL; 00777 } 00778 } 00779 00780 if (verbosity > 1) 00781 (void) fprintf(vis_stdout,"%s[%d] quotient\n", 00782 space, level); 00783 q_tree_exist = 0; 00784 if (q_tree) { 00785 q_ref = 1; 00786 q_tree_exist = 1; 00787 } else if (comp_q_tree) { 00788 q_tree = comp_q_tree; 00789 q_ref = 1; 00790 if (verbosity > 1) { 00791 sprintf(comp_mess, "%s\t(C) : ", space); 00792 SynthPrintZddTreeMessage(dd, q, comp_mess); 00793 } 00794 } else { 00795 q_tree = SynthGenericFactorTree(dd, table, q, level + 1, &q_ref, 00796 NULL, 0, NULL, verbosity); 00797 if (!q_tree) { 00798 bdd_recursive_deref_zdd(dd, l); 00799 bdd_recursive_deref_zdd(dd, q); 00800 bdd_recursive_deref_zdd(dd, m); 00801 bdd_recursive_deref_zdd(dd, r); 00802 return(NULL); 00803 } 00804 if (MlTree_IsComplement(q_tree)) { 00805 q_tree = MlTree_Regular(q_tree); 00806 comp_q_tree = q_tree; 00807 } else 00808 bdd_ref(q_tree->node); 00809 } 00810 tmp_tree = q_tree; 00811 q_tree = SynthCheckAndMakeComplement(dd, table, q_tree, &comp_flag, 00812 verbosity); 00813 if (!q_tree) { 00814 bdd_recursive_deref_zdd(dd, l); 00815 bdd_recursive_deref_zdd(dd, q); 00816 bdd_recursive_deref_zdd(dd, m); 00817 bdd_recursive_deref_zdd(dd, r); 00818 if (comp_q_tree != q_tree) 00819 bdd_recursive_deref_zdd(dd, tmp_tree->node); 00820 if (q_ref == 0) 00821 SynthFreeMlTree(MlTree_Regular(tmp_tree), 1); 00822 return(NULL); 00823 } 00824 if (q_tree != tmp_tree) { 00825 if (comp_flag) 00826 comp_q_tree = q_tree; 00827 q_ref = 1; 00828 } 00829 00830 if (verbosity > 1) 00831 (void) fprintf(vis_stdout,"%s[%d] literal\n", space, level); 00832 if (d_tree) { 00833 d_ref = 1; 00834 if (verbosity > 1) { 00835 sprintf(comp_mess, "%s\t(R) : ", space); 00836 SynthPrintZddTreeMessage(dd, l, comp_mess); 00837 } 00838 } else if (comp_d_tree) { 00839 d_tree = comp_d_tree; 00840 d_ref = 1; 00841 if (verbosity > 1) { 00842 sprintf(comp_mess, "%s\t(C) : ", space); 00843 SynthPrintZddTreeMessage(dd, l, comp_mess); 00844 } 00845 } else { 00846 d_tree = SynthFindOrCreateMlTree(table, dd, l, 1, 0, &d_ref, verbosity); 00847 if (!d_tree) { 00848 bdd_recursive_deref_zdd(dd, l); 00849 bdd_recursive_deref_zdd(dd, q); 00850 bdd_recursive_deref_zdd(dd, m); 00851 bdd_recursive_deref_zdd(dd, r); 00852 if (comp_q_tree != q_tree) 00853 bdd_recursive_deref_zdd(dd, q_tree->node); 00854 if (q_ref == 0) 00855 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00856 return(NULL); 00857 } 00858 if (MlTree_IsComplement(d_tree)) { 00859 comp_d_tree = MlTree_Regular(d_tree); 00860 d_tree = comp_d_tree; 00861 } 00862 if (verbosity > 1) { 00863 sprintf(comp_mess, "%s\t : ", space); 00864 SynthPrintZddTreeMessage(dd, l, comp_mess); 00865 } 00866 tmp_tree = d_tree; 00867 d_tree = SynthCheckAndMakeComplement(dd, table, d_tree, &comp_flag, 00868 verbosity); 00869 if (!d_tree) { 00870 bdd_recursive_deref_zdd(dd, l); 00871 bdd_recursive_deref_zdd(dd, q); 00872 bdd_recursive_deref_zdd(dd, m); 00873 bdd_recursive_deref_zdd(dd, r); 00874 if (comp_q_tree != q_tree) 00875 bdd_recursive_deref_zdd(dd, q_tree->node); 00876 if (q_ref == 0) 00877 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00878 if (d_ref == 0) 00879 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00880 return(NULL); 00881 } else if (d_tree == tmp_tree) { 00882 if (d_ref == 0) 00883 SynthPutMlTreeInList(dd, d_tree, 0); 00884 } else { 00885 if (comp_flag) 00886 comp_d_tree = d_tree; 00887 d_ref = 1; 00888 } 00889 } 00890 00891 m_tree = (MlTree *)NULL; 00892 m_ref = 0; 00893 if (UseMtree && m != f) { 00894 m_tree = SynthFindOrCreateMlTree(table, dd, m, 0, 1, &m_ref, verbosity); 00895 if (!m_tree) { 00896 bdd_recursive_deref_zdd(dd, l); 00897 bdd_recursive_deref_zdd(dd, q); 00898 bdd_recursive_deref_zdd(dd, m); 00899 bdd_recursive_deref_zdd(dd, r); 00900 if (comp_q_tree != q_tree) 00901 bdd_recursive_deref_zdd(dd, q_tree->node); 00902 if (q_ref == 0) 00903 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00904 if (d_ref == 0) 00905 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00906 return(NULL); 00907 } 00908 if (m_ref == 0) { 00909 m_tree->q = q_tree; 00910 m_tree->d = d_tree; 00911 m_tree->r = (MlTree *)NULL; 00912 if (comp_q_tree) 00913 m_tree->q_comp = 1; 00914 if (comp_d_tree) 00915 m_tree->d_comp = 1; 00916 m_tree->q_ref = q_ref; 00917 m_tree->d_ref = d_ref; 00918 m_tree->r_ref = 0; 00919 00920 tmp_tree = m_tree; 00921 m_tree = SynthCheckAndMakeComplement(dd, table, m_tree, &comp_flag, 00922 verbosity); 00923 if (!m_tree) { 00924 bdd_recursive_deref_zdd(dd, l); 00925 bdd_recursive_deref_zdd(dd, q); 00926 bdd_recursive_deref_zdd(dd, m); 00927 bdd_recursive_deref_zdd(dd, r); 00928 if (comp_q_tree != q_tree) 00929 bdd_recursive_deref_zdd(dd, q_tree->node); 00930 if (q_ref == 0) 00931 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00932 if (d_ref == 0) 00933 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00934 return(NULL); 00935 } else if (m_tree == tmp_tree) 00936 SynthPutMlTreeInList(dd, m_tree, 1); 00937 else { 00938 if (m_tree->candidate) 00939 SynthPutMlTreeInList(dd, m_tree, 1); 00940 else 00941 m_tree = NIL(MlTree); 00942 } 00943 if (m_tree && VerifyTreeMode) { 00944 SynthVerifyTree(dd, m_tree, 0); 00945 SynthVerifyMlTable(dd, table); 00946 } 00947 } 00948 } 00949 bdd_recursive_deref_zdd(dd, m); 00950 00951 if (verbosity > 1) 00952 (void) fprintf(vis_stdout, "%s[%d] remainder\n", space, level); 00953 r_tree_exist = 0; 00954 if (r_tree) { 00955 r_ref = 1; 00956 r_tree_exist = 1; 00957 } else if (comp_r_tree) { 00958 r_tree = comp_r_tree; 00959 r_ref = 1; 00960 if (verbosity > 1) { 00961 sprintf(comp_mess, "%s\t(C) : ", space); 00962 SynthPrintZddTreeMessage(dd, r, comp_mess); 00963 } 00964 } else if (comp_d_tree) { 00965 r_tree = SynthGenericFactorTree(dd, table, r, level + 1, &r_ref, 00966 NULL, 0, NULL, verbosity); 00967 if (!r_tree) { 00968 bdd_recursive_deref_zdd(dd, l); 00969 bdd_recursive_deref_zdd(dd, q); 00970 bdd_recursive_deref_zdd(dd, r); 00971 if (comp_q_tree != q_tree) 00972 bdd_recursive_deref_zdd(dd, q_tree->node); 00973 if (q_ref == 0) 00974 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00975 if (d_ref == 0) 00976 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 00977 if (m_tree && m_ref == 0) 00978 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 00979 return(NULL); 00980 } 00981 if (MlTree_IsComplement(r_tree)) { 00982 r_tree = MlTree_Regular(r_tree); 00983 comp_r_tree = r_tree; 00984 } else 00985 bdd_ref(r_tree->node); 00986 } else { 00987 if (Resubstitution) { 00988 r_tree = SynthGenericFactorTree(dd, table, r, level + 1, 00989 &r_ref, d_tree, 1, NULL, verbosity); 00990 if (!r_tree && (bdd_read_reordered_field(dd) || noMemoryFlag)) { 00991 bdd_recursive_deref_zdd(dd, l); 00992 bdd_recursive_deref_zdd(dd, q); 00993 bdd_recursive_deref_zdd(dd, r); 00994 if (comp_q_tree != q_tree) 00995 bdd_recursive_deref_zdd(dd, q_tree->node); 00996 if (q_ref == 0) 00997 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 00998 if (d_ref == 0) 00999 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01000 if (m_tree && m_ref == 0) 01001 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01002 return(NULL); 01003 } 01004 } 01005 if (!r_tree) { 01006 r_tree = SynthGenericFactorTree(dd, table, r, level + 1, 01007 &r_ref, NULL, 0, NULL, verbosity); 01008 if (!r_tree) { 01009 bdd_recursive_deref_zdd(dd, l); 01010 bdd_recursive_deref_zdd(dd, q); 01011 bdd_recursive_deref_zdd(dd, r); 01012 if (comp_q_tree != q_tree) 01013 bdd_recursive_deref_zdd(dd, q_tree->node); 01014 if (q_ref == 0) 01015 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01016 if (d_ref == 0) 01017 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01018 if (m_tree && m_ref == 0) 01019 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01020 return(NULL); 01021 } 01022 } else { 01023 if (r != one && r != zero) 01024 SynthSetSharedFlag(dd, d_tree); 01025 } 01026 if (MlTree_IsComplement(r_tree)) { 01027 r_tree = MlTree_Regular(r_tree); 01028 comp_r_tree = r_tree; 01029 } else 01030 bdd_ref(r_tree->node); 01031 } 01032 if (RemainderComplement) { 01033 tmp_tree = r_tree; 01034 r_tree = SynthCheckAndMakeComplement(dd, table, r_tree, &comp_flag, 01035 verbosity); 01036 if (!r_tree) { 01037 bdd_recursive_deref_zdd(dd, l); 01038 bdd_recursive_deref_zdd(dd, q); 01039 bdd_recursive_deref_zdd(dd, r); 01040 if (comp_q_tree != q_tree) 01041 bdd_recursive_deref_zdd(dd, q_tree->node); 01042 if (comp_r_tree != r_tree) 01043 bdd_recursive_deref_zdd(dd, r_tree->node); 01044 if (q_ref == 0) 01045 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01046 if (d_ref == 0) 01047 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01048 if (r_ref == 0) 01049 SynthFreeMlTree(MlTree_Regular(r_tree), 1); 01050 if (m_tree && m_ref == 0) 01051 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01052 return(NULL); 01053 } 01054 if (r_tree != tmp_tree) { 01055 if (comp_flag) 01056 comp_r_tree = r_tree; 01057 r_ref = 1; 01058 } 01059 } 01060 01061 bdd_recursive_deref_zdd(dd, l); 01062 bdd_recursive_deref_zdd(dd, q); 01063 bdd_recursive_deref_zdd(dd, r); 01064 if ((!q_tree_exist) && (!comp_q_tree)) 01065 bdd_recursive_deref_zdd(dd, q_tree->node); 01066 if ((!r_tree_exist) && (!comp_r_tree)) 01067 bdd_recursive_deref_zdd(dd, r_tree->node); 01068 01069 if (bring) { 01070 tree = bring; 01071 tree->leaf = 0; 01072 tree->q = q_tree; 01073 tree->d = d_tree; 01074 tree->r = r_tree; 01075 if (comp_q_tree) 01076 tree->q_comp = 1; 01077 if (comp_d_tree) 01078 tree->d_comp = 1; 01079 if (comp_r_tree) 01080 tree->r_comp = 1; 01081 tree->q_ref = q_ref; 01082 tree->d_ref = d_ref; 01083 tree->r_ref = r_ref; 01084 if (UseMtree && m_tree && m_ref == 0) { 01085 MlTree_Regular(m_tree)->r = tree; 01086 if (m_tree->r->id == 0) { 01087 assert(0); 01088 /* 01089 if (!SynthUseCandidate(table, dd, m_tree, verbosity)) { 01090 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01091 return(NULL); 01092 } 01093 */ 01094 } 01095 } 01096 if (verbosity > 1) 01097 SynthPrintMlTreeMessage(dd, tree, message); 01098 if (VerifyTreeMode) { 01099 SynthVerifyTree(dd, tree, 0); 01100 SynthVerifyMlTable(dd, table); 01101 } 01102 return(tree); 01103 } 01104 01105 tree = SynthFindOrCreateMlTree(table, dd, f, 0, 0, ref, verbosity); 01106 if (!tree) { 01107 if (q_ref == 0) 01108 SynthFreeMlTree(MlTree_Regular(q_tree), 1); 01109 if (d_ref == 0) 01110 SynthFreeMlTree(MlTree_Regular(d_tree), 1); 01111 if (r_ref == 0) 01112 SynthFreeMlTree(MlTree_Regular(r_tree), 1); 01113 if (m_tree && m_ref == 0) 01114 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01115 return(NULL); 01116 } 01117 if (*ref == 1) 01118 (void) fprintf(vis_stdout, "** synth warning: May be duplicate.\n"); 01119 tree->q = q_tree; 01120 tree->d = d_tree; 01121 tree->r = r_tree; 01122 if (comp_q_tree) 01123 tree->q_comp = 1; 01124 if (comp_d_tree) 01125 tree->d_comp = 1; 01126 if (comp_r_tree) 01127 tree->r_comp = 1; 01128 tree->q_ref = q_ref; 01129 tree->d_ref = d_ref; 01130 tree->r_ref = r_ref; 01131 if (UseMtree && m_tree && m_ref == 0) { 01132 MlTree_Regular(m_tree)->r = tree; 01133 if (m_tree->r->id == 0) { 01134 assert(0); 01135 /* 01136 if (!SynthUseCandidate(table, dd, m_tree, verbosity)) { 01137 SynthFreeMlTree(MlTree_Regular(tree), 1); 01138 SynthFreeMlTree(MlTree_Regular(m_tree), 1); 01139 return(NULL); 01140 } 01141 */ 01142 } 01143 } 01144 if (verbosity > 1) 01145 SynthPrintMlTreeMessage(dd, tree, message); 01146 SynthPutMlTreeInList(dd, tree, 0); 01147 if (VerifyTreeMode) { 01148 SynthVerifyTree(dd, tree, 0); 01149 SynthVerifyMlTable(dd, table); 01150 } 01151 return(tree); 01152 } 01153 01167 static bdd_node * 01168 BestLiteral(bdd_manager *dd, 01169 bdd_node *f, 01170 bdd_node *c) 01171 { 01172 int i, v; 01173 int nvars, max_count; 01174 int *count_f, *count_c; 01175 bdd_node *one = bdd_read_one(dd); 01176 bdd_node *zero = bdd_read_zero(dd); 01177 bdd_node *node; 01178 01179 v = -1; 01180 max_count = 0; 01181 nvars = bdd_num_zdd_vars(dd); 01182 count_f = ALLOC(int, nvars); 01183 (void)memset((void *)count_f, 0, sizeof(int) * nvars); 01184 SynthCountLiteralOccurrence(dd, f, count_f); 01185 count_c = ALLOC(int, nvars); 01186 (void)memset((void *)count_c, 0, sizeof(int) * nvars); 01187 SynthCountLiteralOccurrence(dd, c, count_c); 01188 01189 for (i = 0; i < nvars; i++) { 01190 if (count_c[i]) { 01191 if (count_f[i] > max_count) { 01192 v = i; 01193 max_count = count_f[i]; 01194 } 01195 } 01196 } 01197 01198 if (v == -1) { 01199 FREE(count_f); 01200 FREE(count_c); 01201 return(zero); 01202 } 01203 01204 node = bdd_zdd_get_node(dd, v, one, zero); 01205 if (!node) { 01206 FREE(count_f); 01207 FREE(count_c); 01208 return(NULL); 01209 } 01210 FREE(count_f); 01211 FREE(count_c); 01212 return(node); 01213 } 01214 01215 01227 static int 01228 IsCubeFree(bdd_manager *dd, 01229 bdd_node *f) 01230 { 01231 int i, v; 01232 int nvars, max_count; 01233 int *count; 01234 bdd_node *one = bdd_read_one(dd); 01235 bdd_node *zero = bdd_read_zero(dd); 01236 int ncubes; 01237 01238 if (f == one || f == zero) 01239 return(1); 01240 01241 ncubes = bdd_zdd_count(dd, f); 01242 v = -1; 01243 max_count = 1; 01244 nvars = bdd_num_zdd_vars(dd); 01245 count = ALLOC(int, nvars); 01246 (void)memset((void *)count, 0, sizeof(int) * nvars); 01247 SynthCountLiteralOccurrence(dd, f, count); 01248 for (i = 0; i < nvars; i++) { 01249 if (count[i] > max_count) { 01250 v = i; 01251 max_count = count[i]; 01252 } 01253 } 01254 FREE(count); 01255 01256 if (v == -1 || max_count < ncubes) 01257 return(1); 01258 01259 return(0); 01260 } 01261 01273 static bdd_node * 01274 CommonCube(bdd_manager *dd, 01275 bdd_node *f) 01276 { 01277 int i, v; 01278 int nvars, max_count, max_pos = 0; 01279 int *count; 01280 bdd_node *one = bdd_read_one(dd); 01281 bdd_node *zero = bdd_read_zero(dd); 01282 bdd_node *node; 01283 bdd_node *tmp1, *tmp2; 01284 int ncubes; 01285 01286 if (f == one || f == zero) { 01287 return(f); 01288 } 01289 01290 ncubes = bdd_zdd_count(dd, f); 01291 v = -1; 01292 max_count = 1; 01293 nvars = bdd_num_zdd_vars(dd); 01294 count = ALLOC(int, nvars); 01295 (void)memset((void *)count, 0, sizeof(int) * nvars); 01296 SynthCountLiteralOccurrence(dd, f, count); 01297 for (i = 0; i < nvars; i++) { 01298 if (count[i] > max_count) { 01299 v = i; 01300 max_count = count[i]; 01301 max_pos = i; 01302 } 01303 } 01304 if (v == -1 || max_count < ncubes) { 01305 FREE(count); 01306 return(zero); 01307 } 01308 01309 node = bdd_zdd_get_node(dd, v, one, zero); 01310 if (!node) { 01311 FREE(count); 01312 return(NULL); 01313 } 01314 bdd_ref(node); 01315 for (i = max_pos + 1; i < nvars; i++) { 01316 if (count[i] == max_count) { 01317 tmp1 = node; 01318 tmp2 = bdd_zdd_get_node(dd, i, one, zero); 01319 if (!tmp2) { 01320 FREE(count); 01321 bdd_recursive_deref_zdd(dd, tmp1); 01322 return(NULL); 01323 } 01324 bdd_ref(tmp2); 01325 node = (* SynthGetZddProductFunc())(dd, node, tmp2); 01326 if (!node) { 01327 FREE(count); 01328 bdd_recursive_deref_zdd(dd, tmp1); 01329 bdd_recursive_deref_zdd(dd, tmp2); 01330 return(NULL); 01331 } 01332 bdd_ref(node); 01333 bdd_recursive_deref_zdd(dd, tmp1); 01334 bdd_recursive_deref_zdd(dd, tmp2); 01335 } 01336 } 01337 FREE(count); 01338 bdd_deref(node); 01339 return(node); 01340 }