VIS

src/synth/synthSimple.c

Go to the documentation of this file.
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 }