VIS

src/synth/synthFactor.c

Go to the documentation of this file.
00001 
00017 #include "synthInt.h"
00018 
00019 static char rcsid[] UNUSED = "$Id: synthFactor.c,v 1.49 2005/04/23 14:37:51 jinh Exp $";
00020 
00021 /*---------------------------------------------------------------------------*/
00022 /* Constant declarations                                                     */
00023 /*---------------------------------------------------------------------------*/
00024 
00025 
00026 /*---------------------------------------------------------------------------*/
00027 /* Type declarations                                                         */
00028 /*---------------------------------------------------------------------------*/
00029 
00030 
00031 /*---------------------------------------------------------------------------*/
00032 /* Structure declarations                                                    */
00033 /*---------------------------------------------------------------------------*/
00034 
00046 typedef struct ml_size_list {
00047     int                 size;   /* the number of literals */
00048     char                *string; /* string of the size to put into st_table */
00049     struct ml_size_list *next;
00050 } MlSizeList;
00051 
00052 /*---------------------------------------------------------------------------*/
00053 /* Variable declarations                                                     */
00054 /*---------------------------------------------------------------------------*/
00055 
00056 static  bdd_node        *(* ZddProductFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_product;
00057 static  bdd_node        *(* ZddProductRecurFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_product_recur;
00058 static  bdd_node        *(* ZddDivideFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_weak_div;
00059 static  bdd_node        *(* ZddDivideRecurFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_weak_div_recur;
00060 static  bdd_node        *(* ZddDivisorFunc)(bdd_manager *, bdd_node *) = Synth_ZddQuickDivisor;
00061 static  int             NumTree;
00062 static  int             ResolveConflictMode = 0;
00063 static  st_table        *HeadListTable, *TailListTable;
00064 static  MlTree          *MlTreeHead;
00065 static  MlSizeList      *MlSizeHead;
00066 
00067 int             UseMtree = 1;
00068 int             UseCommonDivisor = 1;
00069 int             TryNodeSharing = 0;
00070 int             Resubstitution = 1;
00071 int             RemainderComplement = 0;
00072 int             noMemoryFlag = 0;
00073 int             VerifyTreeMode = 0;
00074                 /*
00075                 ** 0 : nothing
00076                 ** 1 : incrementally
00077                 ** 2 : recursively after each factorization
00078                 ** 3 : 2 & dump blif file with bdds
00079                 */
00080 
00083 /*---------------------------------------------------------------------------*/
00084 /* Static function prototypes                                                */
00085 /*---------------------------------------------------------------------------*/
00086 
00087 static MlTree * ResolveConflictNode(bdd_manager *dd, st_table *table, MlTree *tree1, MlTree *tree2, int comp_flag, int verbosity);
00088 static void DeleteMlTree(bdd_manager *dd, st_table *table, MlTree *kill_tree, MlTree *live_tree, int deref, int comp_flag);
00089 static void UnlinkMlTree(MlTree *kill_tree);
00090 static void DeleteMlSizeList(MlTree *tree);
00091 static int InsertMlTable(st_table *table, bdd_node *node, MlTree *tree);
00092 static bdd_node * MakeComplementOfZddCover(bdd_manager *dd, bdd_node *node, int verbosity);
00093 static char * GetIntString(int v);
00094 static void VerifyTreeList(void);
00095 
00099 /*---------------------------------------------------------------------------*/
00100 /* Definition of exported functions                                          */
00101 /*---------------------------------------------------------------------------*/
00102 
00103 
00104 
00105 /*---------------------------------------------------------------------------*/
00106 /* Definition of internal functions                                          */
00107 /*---------------------------------------------------------------------------*/
00108 
00109 
00121 bdd_node        *
00122 (* SynthGetZddProductFunc(void))(bdd_manager *, bdd_node *, bdd_node *)
00123 {
00124     return(ZddProductFunc);
00125 }
00126 
00127 
00139 bdd_node        *
00140 (* SynthGetZddProductRecurFunc(void))(bdd_manager *, bdd_node *, bdd_node *)
00141 {
00142     return(ZddProductRecurFunc);
00143 }
00144 
00145 
00157 bdd_node        *
00158 (* SynthGetZddDivideFunc(void))(bdd_manager *, bdd_node *, bdd_node *)
00159 {
00160     return(ZddDivideFunc);
00161 }
00162 
00163 
00175 bdd_node        *
00176 (* SynthGetZddDivideRecurFunc(void))(bdd_manager *, bdd_node *, bdd_node *)
00177 {
00178     return(ZddDivideRecurFunc);
00179 }
00180 
00181 
00193 bdd_node        *
00194 (* SynthGetZddDivisorFunc(void))(bdd_manager *, bdd_node *)
00195 {
00196     return(ZddDivisorFunc);
00197 }
00198 
00199 
00211 void
00212 SynthSetZddDivisorFunc(int mode)
00213 {
00214   if (mode == 0)
00215     ZddDivisorFunc = Synth_ZddQuickDivisor;
00216   else if (mode == 1)
00217     ZddDivisorFunc = Synth_ZddLeastDivisor;
00218   else if (mode == 2)
00219     ZddDivisorFunc = Synth_ZddMostDivisor;
00220   else
00221     ZddDivisorFunc = Synth_ZddLevelZeroDivisor;
00222 }
00223 
00224 
00237 void
00238 SynthGetSpaceString(char *string,
00239                     int n,
00240                     int max)
00241 {
00242   int   i;
00243 
00244   if (n >= max - 1)
00245     n = max - 2;
00246 
00247   for (i = 0; i < n; i++)
00248     string[i] = ' ';
00249   string[n] = '\0';
00250 }
00251 
00252 
00267 MlTree  *
00268 SynthLookupMlTable(st_table *table,
00269                    bdd_manager *dd,
00270                    bdd_node *node,
00271                    int candidate,
00272                    int verbosity)
00273 {
00274   MlTree        *tree, *m_tree;
00275   int           flag;
00276 
00277   flag = st_lookup(table, (char *)node, &tree);
00278   if (flag) {
00279     if (MlTree_Regular(tree)->candidate) {
00280       m_tree = MlTree_Regular(tree);
00281       if (candidate) {
00282         if (!SynthUseCandidate(table, dd, m_tree, verbosity)) {
00283           return(NULL);
00284         }
00285       }
00286     }
00287     if (candidate)
00288       SynthSetSharedFlag(dd, tree);
00289     return(tree);
00290   }
00291 
00292   return((MlTree *)NULL);
00293 }
00294 
00295 
00310 int
00311 SynthUseCandidate(st_table *table,
00312                   bdd_manager *dd,
00313                   MlTree *m_tree,
00314                   int verbosity)
00315 {
00316   MlTree        *parent, *c_tree, *tmp_tree;
00317   bdd_node      *one = bdd_read_one(dd);
00318   bdd_node      *zero = bdd_read_zero(dd);
00319   int           ref;
00320   int           comp_flag;
00321 
00322   m_tree = MlTree_Regular(m_tree);
00323   if (!m_tree->r) {
00324     (void) fprintf(vis_stdout,
00325                    "** synth fatal: Internal error in synthesize_network.\n");
00326     (void) fprintf(vis_stdout,
00327                  "** synth fatal: Please report this bug to VIS developers.\n");
00328     return (0);
00329   }
00330   parent = m_tree->r;
00331   m_tree->r = (MlTree *)NULL;
00332   m_tree->candidate = 0;
00333   c_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &ref, verbosity);
00334   if (!c_tree)
00335     return (0);
00336   if (MlTree_IsComplement(c_tree)) {
00337     c_tree = MlTree_Regular(c_tree);
00338     m_tree->r_comp = 1;
00339   }
00340   tmp_tree = c_tree;
00341   c_tree = SynthCheckAndMakeComplement(dd, table, c_tree,
00342                                        &comp_flag, verbosity);
00343   if (!c_tree)
00344     return (0);
00345   else if (c_tree != tmp_tree) {
00346     if (comp_flag)
00347         m_tree->r_comp = 1;
00348     ref = 1;
00349   }
00350   m_tree->r = c_tree;
00351   m_tree->r_ref = ref;
00352   parent->q = m_tree;
00353   parent->q_ref = 0;
00354   parent->q_comp = 0;
00355   c_tree = SynthFindOrCreateMlTree(table, dd, one, 1, 0, &ref, verbosity);
00356   if (!c_tree)
00357     return (0);
00358   if (MlTree_IsComplement(c_tree)) {
00359     c_tree = MlTree_Regular(c_tree);
00360     parent->d_comp = 1;
00361   } else
00362     parent->d_comp = 0;
00363   parent->d = c_tree;
00364   parent->d_ref = ref;
00365   m_tree->id = NumTree;
00366   NumTree++;
00367   if (verbosity > 1)
00368     (void)fprintf(vis_stdout, "** synth info: Used candidate %d.\n",
00369                   m_tree->id);
00370   if (VerifyTreeMode) {
00371     SynthVerifyTree(dd, parent, 0);
00372     SynthVerifyTree(dd, m_tree, 0);
00373     SynthVerifyMlTable(dd, table);
00374   }
00375   return(1);
00376 }
00377 
00378 
00394 MlTree  *
00395 SynthFindOrCreateMlTree(st_table *table,
00396                         bdd_manager *dd,
00397                         bdd_node *f,
00398                         int leaf,
00399                         int candidate,
00400                         int *ref,
00401                         int verbosity)
00402 {
00403   MlTree        *tree;
00404   bdd_node      *one = bdd_read_one(dd);
00405   bdd_node      *zero = bdd_read_zero(dd);
00406 
00407   tree = SynthLookupMlTable(table, dd, f, 1, verbosity);
00408   if (tree) {
00409     if (MlTree_Regular(tree)->candidate) {
00410       if (!SynthUseCandidate(table, dd, tree, verbosity)) {
00411         return(NULL);
00412       }
00413       SynthSetSharedFlag(dd, tree);
00414     }
00415     *ref = 1;
00416     return(tree);
00417   } else if (bdd_read_reordered_field(dd) || noMemoryFlag == 1)
00418     return(NULL);
00419 
00420   tree = ALLOC(MlTree, 1);
00421   if (!tree) {
00422     noMemoryFlag = 1;
00423     return(NULL);
00424   }
00425   (void)memset((void *)tree, 0, sizeof(MlTree));
00426   tree->node = f;
00427   bdd_ref(f);
00428   tree->leaf = leaf;
00429   if (bdd_bdd_T(f) == one && bdd_bdd_E(f) == zero)
00430     tree->pi = 1;
00431   if (candidate)
00432     tree->candidate = 1;
00433   if (!tree->candidate) {
00434     tree->id = NumTree;
00435     NumTree++;
00436   }
00437   if (!InsertMlTable(table, f, tree)) {
00438     bdd_recursive_deref_zdd(dd, f);
00439     FREE(tree);
00440     return NULL;
00441   }
00442   *ref = 0;
00443 
00444   return(tree);
00445 }
00446 
00447 
00459 void
00460 SynthInitMlTable(void)
00461 {
00462   NumTree = 1;
00463   MlTreeHead = NIL(MlTree);
00464   MlSizeHead = NIL(MlSizeList);
00465   HeadListTable = st_init_table(strcmp, st_strhash);
00466   TailListTable = st_init_table(strcmp, st_strhash);
00467 }
00468 
00469 
00481 void
00482 SynthClearMlTable(bdd_manager *dd,
00483                   st_table *table)
00484 {
00485   st_generator  *gen;
00486   bdd_node              *k;
00487   MlTree                *r;
00488   MlSizeList            *l, *next;
00489 
00490   st_foreach_item(table, gen, (&k), (&r)) {
00491     bdd_recursive_deref_zdd(dd, k);
00492     if (!MlTree_IsComplement(r))
00493       SynthFreeMlTree(r, 0);
00494   }
00495 
00496   NumTree = 1;
00497   MlTreeHead = NIL(MlTree);
00498 
00499   st_free_table(HeadListTable);
00500   st_free_table(TailListTable);
00501   HeadListTable = TailListTable = NIL(st_table);
00502 
00503   l = MlSizeHead;
00504   while (l) {
00505     next = l->next;
00506     FREE(l->string);
00507     FREE(l);
00508     l = next;
00509   }
00510   MlSizeHead = NIL(MlSizeList);
00511 }
00512 
00513 
00532 void
00533 SynthPutMlTreeInList(bdd_manager *dd,
00534                      MlTree *tree,
00535                      int candidate)
00536 {
00537   int           i;
00538   int           word, size;
00539   unsigned int  *mask;
00540   int           top;
00541   MlTree        *last;
00542   MlSizeList    *list, *pre_list, *new_list;
00543 
00544   word = sizeof(int) * 8;
00545   size = bdd_num_zdd_vars(dd) / word + 1;
00546 
00547   if (candidate) {
00548     tree->nLiterals = tree->q->nLiterals + tree->d->nLiterals;
00549 
00550     mask = ALLOC(unsigned int, size);
00551     for (i = 0; i < size; i++)
00552       mask[i] = tree->q->support[i] | tree->d->support[i];
00553     tree->support = mask;
00554   } else {
00555     if (tree->nLiterals == 0) {
00556       top = tree->top;
00557       tree->top = 1;
00558       tree->nLiterals = SynthCountMlLiteral(dd, tree, 0);
00559       tree->top = top;
00560     }
00561 
00562     if (!tree->support) {
00563       mask = ALLOC(unsigned int, size);
00564       (void)memset((void *)mask, 0, size * sizeof(int));
00565       SynthGetSupportMask(dd, tree->node, mask);
00566       tree->support = mask;
00567     }
00568   }
00569 
00570   if ((!MlTreeHead) || (tree->nLiterals > MlTreeHead->nLiterals)) {
00571     tree->next = MlTreeHead;
00572     MlTreeHead = tree;
00573 
00574     list = ALLOC(MlSizeList, 1);
00575     list->size = tree->nLiterals;
00576     list->string = GetIntString(list->size);
00577     list->next = MlSizeHead;
00578     MlSizeHead = list;
00579 
00580     st_insert(HeadListTable, list->string, (char *)tree);
00581     st_insert(TailListTable, list->string, (char *)tree);
00582   } else {
00583     pre_list = NIL(MlSizeList);
00584     list = MlSizeHead;
00585     while (list) {
00586       if (tree->nLiterals == list->size) {
00587         if (list == MlSizeHead) {
00588           tree->next = MlTreeHead;
00589           MlTreeHead = tree;
00590           st_insert(HeadListTable, list->string, (char *)tree);
00591         } else {
00592           st_lookup(TailListTable, list->string, (&last));
00593           tree->next = last->next;
00594           last->next = tree;
00595           st_insert(TailListTable, list->string, (char *)tree);
00596         }
00597         break;
00598       } else if (tree->nLiterals > list->size) {
00599         st_lookup(TailListTable, pre_list->string, (&last));
00600         tree->next = last->next;
00601         last->next = tree;
00602 
00603         new_list = ALLOC(MlSizeList, 1);
00604         new_list->size = tree->nLiterals;
00605         new_list->string = GetIntString(new_list->size);
00606         new_list->next = list;
00607         pre_list->next = new_list;
00608 
00609         st_insert(HeadListTable, new_list->string, (char *)tree);
00610         st_insert(TailListTable, new_list->string, (char *)tree);
00611         break;
00612       } else if (!list->next) {
00613         st_lookup(TailListTable, list->string, (&last));
00614         tree->next = NIL(MlTree);
00615         last->next = tree;
00616 
00617         new_list = ALLOC(MlSizeList, 1);
00618         new_list->size = tree->nLiterals;
00619         new_list->string = GetIntString(new_list->size);
00620         new_list->next = NIL(MlSizeList);
00621         list->next = new_list;
00622 
00623         st_insert(HeadListTable, new_list->string, (char *)tree);
00624         st_insert(TailListTable, new_list->string, (char *)tree);
00625         break;
00626       }
00627       pre_list = list;
00628       list = list->next;
00629     }
00630   }
00631 
00632   if (VerifyTreeMode)
00633     VerifyTreeList();
00634 }
00635 
00636 
00649 MlTree  *
00650 SynthGetHeadTreeOfSize(int size)
00651 {
00652   MlTree        *head;
00653   MlSizeList    *list;
00654 
00655   list = MlSizeHead;
00656   while (list) {
00657     if (size == list->size) {
00658       st_lookup(HeadListTable, list->string, (&head));
00659       return(head);
00660     } else if (size > list->size)
00661       return(NULL);
00662     list = list->next;
00663   }
00664   return(NULL);
00665 }
00666 
00667 
00684 MlTree  *
00685 SynthCheckAndMakeComplement(bdd_manager *dd,
00686                             st_table *table,
00687                             MlTree *tree,
00688                             int *comp_flag,
00689                             int verbosity)
00690 {
00691   bdd_node      *c;
00692   MlTree        *c_tree, *new_;
00693 
00694   if (MlTree_IsComplement(tree))
00695     return(tree);
00696 
00697   *comp_flag = 0;
00698   if (!tree->complement) {
00699     c = MakeComplementOfZddCover(dd, tree->node, verbosity);
00700     if (!c)
00701       return(NULL);
00702     bdd_ref(c);
00703     c_tree = SynthLookupMlTable(table, dd, (char *)c, 0, verbosity);
00704     if (c_tree) {
00705       MlTree *m_tree = MlTree_Regular(c_tree);
00706       if (MlTree_Regular(tree)->candidate &&
00707           MlTree_Regular(c_tree)->candidate) {
00708         /*
00709         **       tree     m_tree
00710         **         |\      /|
00711         **         |   \/   |
00712         **         | /    \ |
00713         **         q        d
00714         **/
00715 
00716         if (ResolveConflictMode == 0 || c_tree == m_tree ||
00717             tree->nLiterals <= m_tree->nLiterals) {
00718           /* throw away m_tree and assign c to tree->complement */
00719           UnlinkMlTree(m_tree);
00720           bdd_recursive_deref_zdd(dd, m_tree->node);
00721           bdd_recursive_deref_zdd(dd, m_tree->complement);
00722           st_delete(table, (char **)(&m_tree->node), NIL(char *));
00723           st_delete(table, (char **)(&m_tree->complement), NIL(char *));
00724           if (m_tree->support)
00725             FREE(m_tree->support);
00726           FREE(m_tree);
00727           tree->complement = c;
00728           if (!InsertMlTable(table, c, MlTree_Not(tree))) {
00729             tree->complement = NIL(bdd_node);
00730             bdd_recursive_deref_zdd(dd, c);
00731             return(NULL);
00732           }
00733         } else if (c_tree != m_tree) {
00734           /* takes m_tree's contents and throws away m_tree */
00735           UnlinkMlTree(tree);
00736           UnlinkMlTree(m_tree);
00737           bdd_recursive_deref_zdd(dd, tree->node);
00738           st_delete(table, (char **)(&tree->node), NIL(char *));
00739           if (tree->support)
00740             FREE(tree->support);
00741           memcpy(tree, m_tree, sizeof(MlTree));
00742           FREE(m_tree);
00743           tree->complement = c;
00744           if (!InsertMlTable(table, tree->node, tree)) 
00745             return(NULL);
00746           if (!InsertMlTable(table, tree->complement, MlTree_Not(tree))) 
00747             return(NULL);
00748         } else { /* It never happens at this time,
00749                   * the case(c_tree == m_tree) is already taken care of.
00750                   * But, it should be implemented to improve
00751                   * in the future.
00752                   */
00753         }
00754         if (VerifyTreeMode) {
00755           SynthVerifyTree(dd, tree, 0);
00756           SynthVerifyMlTable(dd, table);
00757         }
00758         return(tree);
00759       } else if (MlTree_Regular(tree)->candidate) {
00760         /*
00761         **       tree     m_tree
00762         **         |\      /|\
00763         **         |   \/   |   \
00764         **         | /    \ |      \
00765         **         q        d        r
00766         **/
00767 
00768         if (tree->r == m_tree) {
00769           if (c_tree == m_tree)
00770             *comp_flag = 1;
00771           else
00772             *comp_flag = 0;
00773 
00774           if (ResolveConflictMode == 0 || c_tree == m_tree ||
00775               m_tree->nLiterals <= tree->nLiterals) {
00776             /* throw away tree and returns m_tree */
00777             bdd_recursive_deref_zdd(dd, c);
00778             UnlinkMlTree(tree);
00779             bdd_recursive_deref_zdd(dd, tree->node);
00780             st_delete(table, (char **)(&m_tree->node), NIL(char *));
00781             if (tree->support)
00782               FREE(tree->support);
00783             FREE(tree);
00784           } else if (c_tree != m_tree) {
00785             /*
00786             **      tree->complement = m_tree->complement
00787             **
00788             **       tree     m_tree
00789             **         |\      /|\
00790             **         |   \/   |   \
00791             **         | /    \ |      \
00792             **         q        d        r
00793             **/
00794 
00795             MlTree      *r_tree, *tmp_tree;
00796             int         r_comp;
00797             int         ref;
00798             bdd_node    *zero = bdd_read_zero(dd);
00799 
00800             /* takes tree's contents and throw away tree and m_tree->r */
00801 
00802             bdd_recursive_deref_zdd(dd, c);
00803             r_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &ref,
00804                                              verbosity);
00805             if (!r_tree)
00806               return(NULL);
00807             if (MlTree_IsComplement(r_tree)) {
00808               r_tree = MlTree_Regular(r_tree);
00809               m_tree->r_comp = 1;
00810             }
00811             tmp_tree = r_tree;
00812             r_tree = SynthCheckAndMakeComplement(dd, table, r_tree,
00813                                                  &r_comp, verbosity);
00814             if (!r_tree)
00815               return(NULL);
00816             else if (r_tree != tmp_tree) {
00817               if (r_comp)
00818                 m_tree->r_comp = 1;
00819               ref = 1;
00820             }
00821             tree->r = r_tree;
00822             tree->r_ref = ref;
00823             tree->id = m_tree->id;
00824             tree->candidate = 0;
00825 
00826             bdd_recursive_deref_zdd(dd, m_tree->node);
00827             bdd_recursive_deref_zdd(dd, m_tree->complement);
00828             st_delete(table, (char **)(&m_tree->node), NIL(char *));
00829             st_delete(table, (char **)(&m_tree->complement), NIL(char *));
00830             UnlinkMlTree(m_tree);
00831             if (m_tree->support)
00832               FREE(m_tree->support);
00833             ref = m_tree->r_ref;
00834             r_tree = m_tree->r;
00835             memcpy(m_tree, tree, sizeof(MlTree));
00836             FREE(tree);
00837             SynthPutMlTreeInList(dd, m_tree, 0);
00838 
00839             if (ref) {
00840               if (r_tree->shared)
00841                 DeleteMlTree(dd, table, r_tree, NULL, 1, 0);
00842             } else
00843               DeleteMlTree(dd, table, r_tree, NULL, 1, 0);
00844           } else { /* It never happens at this time,
00845                     * the case(c_tree == m_tree) is already taken care of.
00846                     * But, it should be implemented to improve
00847                     * in the future.
00848                     */
00849           }
00850           if (VerifyTreeMode) {
00851             SynthVerifyTree(dd, m_tree, 0);
00852             SynthVerifyMlTable(dd, table);
00853           }
00854           return(m_tree);
00855         }
00856         if (!SynthUseCandidate(table, dd, tree, verbosity)) {
00857           bdd_recursive_deref_zdd(dd, c);
00858           return(NULL);
00859         }
00860         SynthSetSharedFlag(dd, tree);
00861       } else if (MlTree_Regular(c_tree)->candidate) {
00862         if (m_tree->r == tree) {
00863           /*
00864           **      m_tree     tree
00865           **         |\      /|\
00866           **         |   \/   |   \
00867           **         | /    \ |      \
00868           **         q        d        r
00869           **/
00870 
00871           if (ResolveConflictMode == 0 || c_tree == m_tree ||
00872               tree->nLiterals <= m_tree->nLiterals) {
00873             /* throw away m_tree and assign c to tree->complement */
00874             UnlinkMlTree(m_tree);
00875             bdd_recursive_deref_zdd(dd, m_tree->node);
00876             bdd_recursive_deref_zdd(dd, m_tree->complement);
00877             st_delete(table, (char **)(&m_tree->node), NIL(char *));
00878             st_delete(table, (char **)(&m_tree->complement), NIL(char *));
00879             if (m_tree->support)
00880               FREE(m_tree->support);
00881             FREE(m_tree);
00882             tree->complement = c;
00883             if (!InsertMlTable(table, c, MlTree_Not(tree))) {
00884               tree->complement = NIL(bdd_node);
00885               bdd_recursive_deref_zdd(dd, c);
00886               return(NULL);
00887             }
00888           } else if (c_tree != m_tree) {
00889             /*
00890             **      tree->complement = m_tree->complement
00891             **
00892             **      m_tree     tree
00893             **         |\      /|\
00894             **         |   \/   |   \
00895             **         | /    \ |      \
00896             **         q        d        r
00897             **/
00898 
00899             MlTree      *r_tree, *tmp_tree;
00900             int         r_comp;
00901             int         ref;
00902             bdd_node    *zero = bdd_read_zero(dd);
00903 
00904             /* takes m_tree's contents and throw away m_tree and tree->r */
00905 
00906             bdd_recursive_deref_zdd(dd, c);
00907             r_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &ref,
00908                                              verbosity);
00909             if (!r_tree)
00910               return(NULL);
00911             if (MlTree_IsComplement(r_tree)) {
00912               r_tree = MlTree_Regular(r_tree);
00913               m_tree->r_comp = 1;
00914             }
00915             tmp_tree = r_tree;
00916             r_tree = SynthCheckAndMakeComplement(dd, table, r_tree,
00917                                                  &r_comp, verbosity);
00918             if (!r_tree)
00919               return(NULL);
00920             else if (r_tree != tmp_tree) {
00921               if (r_comp)
00922                 m_tree->r_comp = 1;
00923               ref = 1;
00924             }
00925             m_tree->r = r_tree;
00926             m_tree->r_ref = ref;
00927             m_tree->id = tree->id;
00928             m_tree->candidate = 0;
00929 
00930             bdd_recursive_deref_zdd(dd, tree->node);
00931             st_delete(table, (char **)(&tree->node), NIL(char *));
00932             UnlinkMlTree(tree);
00933             if (tree->support)
00934               FREE(tree->support);
00935             ref = tree->r_ref;
00936             r_tree = tree->r;
00937             memcpy(tree, m_tree, sizeof(MlTree));
00938             FREE(m_tree);
00939             SynthPutMlTreeInList(dd, tree, 0);
00940 
00941             if (ref) {
00942               if (r_tree->shared)
00943                 DeleteMlTree(dd, table, r_tree, NULL, 1, 0);
00944             } else
00945               DeleteMlTree(dd, table, r_tree, NULL, 1, 0);
00946           } else { /* It never happens at this time,
00947                     * the case(c_tree == m_tree) is already taken care of.
00948                     * But, it should be implemented to improve
00949                     * in the future.
00950                     */
00951             /*
00952             **      tree->complement = m_tree->node
00953             **
00954             **      m_tree     tree
00955             **         |\      /|\
00956             **         |   \/   |   \
00957             **         | /    \ |      \
00958             **         q        d        r
00959             **/
00960           }
00961           return(tree);
00962         }
00963         if (!SynthUseCandidate(table, dd, m_tree, verbosity)) {
00964           bdd_recursive_deref_zdd(dd, c);
00965           return(NULL);
00966         }
00967         SynthSetSharedFlag(dd, m_tree);
00968       }
00969 
00970       bdd_recursive_deref_zdd(dd, c);
00971       if (c_tree == m_tree)
00972         *comp_flag = 1;
00973       else
00974         *comp_flag = 0;
00975 
00976       if (verbosity)
00977         (void) fprintf(vis_stdout, "** synth warning: Duplicate entry ...\n");
00978       new_ = ResolveConflictNode(dd, table, c_tree, tree, *comp_flag, verbosity);
00979       if (verbosity)
00980         (void) fprintf(vis_stdout, "** synth info: Conflict was resolved.\n");
00981       if (VerifyTreeMode) {
00982         SynthVerifyTree(dd, new_, 0);
00983         SynthVerifyMlTable(dd, table);
00984       }
00985       return(new_);
00986     } else if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) {
00987       bdd_recursive_deref_zdd(dd, c);
00988       return(NULL);
00989     }
00990     tree->complement = c;
00991     if (!InsertMlTable(table, c, MlTree_Not(tree))) {
00992       tree->complement = NIL(bdd_node);
00993       bdd_recursive_deref_zdd(dd, c);
00994       return NULL;
00995     }
00996   }
00997   return(tree);
00998 }
00999 
01000 
01012 void
01013 SynthSetSharedFlag(bdd_manager *dd,
01014                    MlTree *tree)
01015 {
01016   MlTree        *t;
01017   bdd_node      *one = bdd_read_one(dd);
01018   bdd_node      *zero = bdd_read_zero(dd);
01019 
01020   t = MlTree_Regular(tree);
01021   if (t->node == zero || t->node == one)
01022     return;
01023   if (t->pi == 0)
01024     t->shared = 1;
01025 }
01026 
01027 
01043 int
01044 SynthPostFactoring(bdd_manager *dd,
01045                    st_table *table,
01046                    MlTree *(* factoring_func)(bdd_manager *, st_table *,
01047                                               bdd_node *, int, int *, MlTree *,
01048                                               int, MlTree *, int),
01049                    int verbosity)
01050 {
01051   MlTree        *cur, *candy;
01052   int           ref;
01053   bdd_node      *q;
01054   bdd_node      *zero = bdd_read_zero(dd);
01055 
01056   if (VerifyTreeMode) {
01057     SynthVerifyMlTable(dd, table);
01058     VerifyTreeList();
01059   }
01060 
01061   cur = MlTreeHead;
01062   while (cur) {
01063     if (cur->leaf) {
01064       if (cur->nLiterals < 2)
01065         break;
01066       candy = cur->next;
01067       while (candy) {
01068         if (candy->nLiterals == 1)
01069           break;
01070         else if (candy->leaf == 0 ||
01071                  candy->nLiterals == cur->nLiterals) {
01072           candy = candy->next;
01073           continue;
01074         }
01075 
01076         q = (* ZddDivideFunc)(dd, cur->node, candy->node);
01077         if (!q)
01078           return(1);
01079         bdd_ref(q);
01080         /* Even though we deref q, it still exists as a
01081          * pointer and beyond this point, we use it only to
01082          * check if it is zero or not.
01083          */
01084         bdd_recursive_deref_zdd(dd,q);
01085         if (q != zero) {
01086           (void) (* factoring_func)(dd, table, cur->node,
01087                                     0, &ref, candy, 0, cur, verbosity);
01088           if (VerifyTreeMode) {
01089             SynthVerifyTree(dd, cur, 0);
01090             SynthVerifyMlTable(dd, table);
01091             VerifyTreeList();
01092           }
01093           if (bdd_read_reordered_field(dd) || noMemoryFlag == 1)
01094             return(1);
01095 
01096           SynthSetSharedFlag(dd, candy);
01097           break;
01098         } else {
01099           q = (* ZddDivideFunc)(dd, cur->node, 
01100                                 candy->complement);
01101           if (!q)
01102             return(1);
01103           bdd_ref(q);
01104           /* Even though we deref q, it still exists as a
01105            * pointer and beyond this point, we use it only
01106            * to check if it is zero or not.
01107            */
01108           bdd_recursive_deref_zdd(dd,q);
01109           if (q != zero) {
01110             (void) (* factoring_func)(dd, table, cur->node, 0,
01111                                       &ref, candy, 1, cur, verbosity);
01112             if (VerifyTreeMode) {
01113               SynthVerifyTree(dd, cur, 0);
01114               SynthVerifyMlTable(dd, table);
01115               VerifyTreeList();
01116             }
01117             if (bdd_read_reordered_field(dd) || noMemoryFlag == 1 )
01118               return(1);
01119             SynthSetSharedFlag(dd, candy);
01120             break;
01121           }
01122         }
01123         candy = candy->next;
01124       }
01125     }
01126     cur = cur->next;
01127   }
01128   return(0);
01129 }
01130 
01131 
01145 void
01146 SynthUpdateRefOfParent(MlTree *top)
01147 {
01148   MlTree        *cur;
01149 
01150   cur = MlTreeHead;
01151   while (cur) {
01152     if (cur->q == top)
01153       cur->q_ref = 1;
01154     else if (cur->d == top)
01155       cur->d_ref = 1;
01156     else if (cur->r == top)
01157       cur->r_ref = 1;
01158     cur = cur->next;
01159   }
01160 }
01161 
01162 
01176 void
01177 SynthVerifyTree(bdd_manager *dd,
01178                 MlTree *tree,
01179                 int flag)
01180 {
01181   bdd_node      *node, *comp;
01182   bdd_node      *q, *d, *r, *f, *m;
01183   int           bdd_diff;
01184 
01185   if (flag && !tree->leaf) {
01186     if (!tree->q_ref)
01187       SynthVerifyTree(dd, tree->q, flag);
01188     if (!tree->d_ref)
01189       SynthVerifyTree(dd, tree->d, flag);
01190     if (!tree->r_ref)
01191       SynthVerifyTree(dd, tree->r, flag);
01192   }
01193 
01194   node = bdd_make_bdd_from_zdd_cover(dd, tree->node);
01195   if (!node)
01196     return;
01197   bdd_ref(node);
01198   if (tree->complement) {
01199     comp = bdd_make_bdd_from_zdd_cover(dd, tree->complement);
01200     if (!comp) {
01201       bdd_recursive_deref(dd, node);
01202       return;
01203     }
01204     bdd_ref(comp);
01205     
01206     if (node != bdd_not_bdd_node(comp)) {
01207       (void) fprintf(vis_stdout,
01208         "** synth error: Invalid complement node in tree [%d].\n", tree->id);
01209     }
01210     
01211     bdd_recursive_deref(dd, comp);
01212   }
01213 
01214   if (tree->leaf) {
01215     if (tree->q) {
01216       (void) fprintf(vis_stdout,
01217              "** synth error: q exists in leaf tree [%d].\n", tree->id);
01218     }
01219     if (tree->d) {
01220       (void) fprintf(vis_stdout,
01221              "** synth error: d exists in leaf tree [%d].\n", tree->id);
01222     }
01223     if (tree->r) {
01224       (void) fprintf(vis_stdout,
01225              "** synth error: r exists in leaf tree [%d].\n", tree->id);
01226     }
01227     if (tree->q_ref) {
01228       (void) fprintf(vis_stdout,
01229              "** synth error: q_ref = 1 in leaf tree [%d].\n", tree->id);
01230     }
01231     if (tree->d_ref) {
01232       (void) fprintf(vis_stdout,
01233              "** synth error: d_ref = 1 in leaf tree [%d].\n", tree->id);
01234     }
01235     if (tree->r_ref) {
01236       (void) fprintf(vis_stdout,
01237              "** synth error: r_ref = 1 in leaf tree [%d].\n", tree->id);
01238     }
01239     if (tree->q_comp) {
01240       (void) fprintf(vis_stdout,
01241              "** synth error: q_comp = 1 in leaf tree [%d].\n", tree->id);
01242     }
01243     if (tree->d_comp) {
01244       (void) fprintf(vis_stdout,
01245              "** synth error: d_comp = 1 in leaf tree [%d].\n", tree->id);
01246     }
01247     if (tree->r_comp) {
01248       (void) fprintf(vis_stdout,
01249              "** synth error: r_comp = 1 in leaf tree [%d].\n", tree->id);
01250     }
01251     bdd_recursive_deref(dd, node);
01252     return;
01253   }
01254   else {
01255     if (tree->pi) {
01256       (void) fprintf(vis_stdout,
01257              "** synth error: pi = 1 in non-leaf tree [%d].\n", tree->id);
01258     }
01259   }
01260 
01261   if (!tree->q) {
01262     (void) fprintf(vis_stdout,
01263                    "** synth error: no q in tree [%d].\n", tree->id);
01264     bdd_recursive_deref(dd, node);
01265     return;
01266   }
01267   if (tree->q_comp)
01268     q = bdd_make_bdd_from_zdd_cover(dd, tree->q->complement);
01269   else
01270     q = bdd_make_bdd_from_zdd_cover(dd, tree->q->node);
01271   if (!q) {
01272     (void) fprintf(vis_stdout,
01273                    "** synth error: no q node in tree [%d].\n", tree->id);
01274     bdd_recursive_deref(dd, node);
01275     return;
01276   }
01277   bdd_ref(q);
01278   if (!tree->d) {
01279     (void) fprintf(vis_stdout,
01280                    "** synth error: no d in tree [%d].\n", tree->id);
01281     bdd_recursive_deref(dd, node);
01282     bdd_recursive_deref(dd, q);
01283     return;
01284   }
01285   if (tree->d_comp)
01286     d = bdd_make_bdd_from_zdd_cover(dd, tree->d->complement);
01287   else
01288     d = bdd_make_bdd_from_zdd_cover(dd, tree->d->node);
01289   if (!d) {
01290     (void) fprintf(vis_stdout,
01291                    "** synth error: no d node in tree [%d].\n", tree->id);
01292     bdd_recursive_deref(dd, node);
01293     bdd_recursive_deref(dd, q);
01294     return;
01295   }
01296   bdd_ref(d);
01297   if (!tree->candidate) {
01298     if (!tree->r) {
01299       (void) fprintf(vis_stdout,
01300                      "** synth error: no r in tree [%d].\n", tree->id);
01301       bdd_recursive_deref(dd, node);
01302       bdd_recursive_deref(dd, q);
01303       bdd_recursive_deref(dd, d);
01304       return;
01305     }
01306     if (tree->r_comp)
01307       r = bdd_make_bdd_from_zdd_cover(dd, tree->r->complement);
01308     else
01309       r = bdd_make_bdd_from_zdd_cover(dd, tree->r->node);
01310     if (!r) {
01311       (void) fprintf(vis_stdout,
01312                      "** synth error: no r node in tree [%d].\n", tree->id);
01313       bdd_recursive_deref(dd, node);
01314       bdd_recursive_deref(dd, q);
01315       bdd_recursive_deref(dd, d);
01316       return;
01317     }
01318     bdd_ref(r);
01319     
01320     m = bdd_bdd_and(dd, q, d);
01321     if (!m) {
01322       bdd_recursive_deref(dd, node);
01323       bdd_recursive_deref(dd, q);
01324       bdd_recursive_deref(dd, d);
01325       bdd_recursive_deref(dd, r);
01326       return;
01327     }
01328     bdd_ref(m);
01329     bdd_recursive_deref(dd, q);
01330     bdd_recursive_deref(dd, d);
01331     f = bdd_bdd_or(dd, m, r);
01332     if (!f) {
01333       bdd_recursive_deref(dd, node);
01334       bdd_recursive_deref(dd, r);
01335       bdd_recursive_deref(dd, m);
01336       return;
01337     }
01338     bdd_ref(f);
01339     bdd_recursive_deref(dd, r);
01340     bdd_recursive_deref(dd, m);
01341   } else {
01342     f = bdd_bdd_and(dd, q, d);
01343     if (!f) {
01344       bdd_recursive_deref(dd, node);
01345       bdd_recursive_deref(dd, q);
01346       bdd_recursive_deref(dd, d);
01347       return;
01348     }
01349     bdd_ref(f);
01350     bdd_recursive_deref(dd, q);
01351     bdd_recursive_deref(dd, d);
01352   }
01353   if (!f) {
01354     bdd_recursive_deref(dd, node);
01355     return;
01356   }
01357 
01358   if (f == node)
01359     bdd_diff = 0;
01360   else
01361     bdd_diff = 1;
01362 
01363   bdd_recursive_deref(dd, f);
01364   bdd_recursive_deref(dd, node);
01365 
01366   if (tree->comp)
01367     node = tree->complement;
01368   else
01369     node = tree->node;
01370   if (tree->q_comp)
01371     q = tree->q->complement;
01372   else
01373     q = tree->q->node;
01374   if (tree->d_comp)
01375     d = tree->d->complement;
01376   else
01377     d = tree->d->node;
01378   if (!tree->candidate) {
01379     if (tree->r_comp)
01380       r = tree->r->complement;
01381     else
01382       r = tree->r->node;
01383     m = (* SynthGetZddProductFunc())(dd, d, q);
01384     if (!m)
01385       return;
01386     bdd_ref(m);
01387     f = bdd_zdd_union(dd, m, r);
01388     if (!f) {
01389       bdd_recursive_deref_zdd(dd, m);
01390       return;
01391     }
01392     bdd_ref(f);
01393     bdd_recursive_deref_zdd(dd, m);
01394   } else {
01395     f = (* SynthGetZddProductFunc())(dd, d, q);
01396     if (!f)
01397       return;
01398     bdd_ref(f);
01399   }
01400   if (f != node) {
01401     if (bdd_diff) {
01402       (void) fprintf(vis_stdout,
01403              "** synth error: BDD & ZDD f != qd+r in tree [%d - 0x%lx].\n",
01404              tree->id, (unsigned long)tree);
01405     }
01406     else {
01407       (void) fprintf(vis_stdout,
01408                      "Warning : ZDD f != qd+r in tree [%d - 0x%lx].\n",
01409                      tree->id, (unsigned long)tree);
01410     }
01411   }
01412   else if (bdd_diff) {
01413     (void) fprintf(vis_stdout,
01414                    "** synth error: BDD f != qd+r in tree [%d - 0x%lx].\n",
01415                    tree->id, (unsigned long)tree);
01416   }
01417   bdd_recursive_deref_zdd(dd, f);
01418 }
01419 
01420 
01434 void
01435 SynthVerifyMlTable(bdd_manager *dd,
01436                    st_table *table)
01437 {
01438   st_generator  *gen;
01439   bdd_node              *node;
01440   MlTree                *tree, *reg;
01441 
01442   st_foreach_item(table, gen, (&node), (&tree)) {
01443     reg = MlTree_Regular(tree);
01444     if ((reg == tree && node != reg->node) ||
01445         (reg != tree && node != reg->complement)) {
01446       (void) fprintf(vis_stdout,
01447                      "** synth error: wrong node in tree [%d].\n", reg->id);
01448     }
01449     tree = reg;
01450     if (tree->id >= NumTree) {
01451       (void) fprintf(vis_stdout,
01452                      "** synth error: wrong id in tree [%d].\n", tree->id);
01453     }
01454     if (!tree->leaf) {
01455       if (!tree->d) {
01456         (void) fprintf(vis_stdout,
01457                "** synth error: d doesn't exist in tree [%d].\n", tree->id);
01458       }
01459       if (!tree->q) {
01460         (void) fprintf(vis_stdout,
01461                "** synth error: q doesn't exist in tree [%d].\n", tree->id);
01462       }
01463       if (!tree->r && !tree->candidate) {
01464         (void) fprintf(vis_stdout,
01465                "** synth error: r doesn't exist in tree [%d].\n", tree->id);
01466       }
01467     }
01468   }
01469 }
01470 
01471 
01483 void
01484 SynthPrintTreeList(MlTree *list)
01485 {
01486   MlTree *cur = list;
01487   if (!cur)
01488     cur = MlTreeHead;
01489   while (cur) {
01490     printf("%d (%d) - %d [0x%lx]\n", cur->id, cur->nLiterals,
01491            cur->leaf, (unsigned long)cur);
01492     cur = cur->next;
01493   }
01494 }
01495 
01496 
01508 void
01509 SynthPrintLeafList(MlTree *list)
01510 {
01511   MlTree *cur = list;
01512   if (!cur)
01513     cur = MlTreeHead;
01514   while (cur) {
01515     if (cur->leaf)
01516       printf("%d (%d) [0x%lx]\n", cur->id, cur->nLiterals, (unsigned long)cur);
01517     cur = cur->next;
01518   }
01519 }
01520 
01521 
01522 /*---------------------------------------------------------------------------*/
01523 /* Definition of static functions                                            */
01524 /*---------------------------------------------------------------------------*/
01525 
01526 
01542 static MlTree *
01543 ResolveConflictNode(bdd_manager *dd,
01544                     st_table *table,
01545                     MlTree *tree1,
01546                     MlTree *tree2,
01547                     int comp_flag,
01548                     int verbosity)
01549 {
01550   MlTree        *live_tree, *kill_tree;
01551 
01552   if (MlTree_IsComplement(tree1))
01553     tree1 = MlTree_Regular(tree1);
01554   if (MlTree_IsComplement(tree2))
01555     tree2 = MlTree_Regular(tree2);
01556 
01557   if (verbosity) {
01558     if (tree1->complement || tree2->complement)
01559       (void) fprintf(vis_stdout, "** synth warning: real conflict.\n");
01560   }
01561 
01562   if (ResolveConflictMode == 0) {
01563     live_tree = tree1;
01564     kill_tree = tree2;
01565   } else {
01566     if (tree1->nLiterals > tree2->nLiterals) {
01567       live_tree = tree2;
01568       kill_tree = tree1;
01569     } else {
01570       live_tree = tree1;
01571       kill_tree = tree2;
01572     }
01573   }
01574 
01575   if (!live_tree->complement) {
01576     if (comp_flag)
01577       live_tree->complement = kill_tree->node;
01578     else
01579       live_tree->complement = kill_tree->complement;
01580     bdd_ref(live_tree->complement);
01581     bdd_recursive_deref_zdd(dd, kill_tree->node);
01582     st_delete(table, (char **)(&kill_tree->node), NIL(char *));
01583     if (kill_tree->complement) {
01584         bdd_recursive_deref_zdd(dd, kill_tree->complement);
01585         st_delete(table, (char **)(&kill_tree->complement), NIL(char *));
01586     }
01587     st_insert(table, (char *)live_tree->complement,
01588               (char *)MlTree_Not(live_tree));
01589   } else {
01590     bdd_recursive_deref_zdd(dd, kill_tree->node);
01591     st_delete(table, (char **)(&kill_tree->node), NIL(char *));
01592     if (kill_tree->complement) {
01593         bdd_recursive_deref_zdd(dd, kill_tree->complement);
01594         st_delete(table, (char **)(&kill_tree->complement), NIL(char *));
01595     }
01596   }
01597 
01598   DeleteMlTree(dd, table, kill_tree, live_tree, 0, comp_flag);
01599   SynthSetSharedFlag(dd, live_tree);
01600 
01601   if (VerifyTreeMode) {
01602     SynthVerifyTree(dd, live_tree, 0);
01603     SynthVerifyMlTable(dd, table);
01604     VerifyTreeList();
01605   }
01606 
01607   return(live_tree);
01608 }
01609 
01610 
01622 static void
01623 DeleteMlTree(bdd_manager *dd,
01624              st_table *table,
01625              MlTree *kill_tree,
01626              MlTree *live_tree,
01627              int deref,
01628              int comp_flag)
01629 {
01630   MlTree        *cur, *pre, *next;
01631   int           ref;
01632 
01633   if (kill_tree->shared && deref) {
01634     ref = 0;
01635     cur = MlTreeHead;
01636     while (cur) {
01637       if (cur == kill_tree) {
01638         cur = cur->next;
01639         continue;
01640       }
01641       if (cur->q == kill_tree)
01642         ref++;
01643       else if (cur->d == kill_tree)
01644         ref++;
01645       else if (cur->r == kill_tree)
01646         ref++;
01647       cur = cur->next;
01648     }
01649 
01650     if (ref == 1)
01651       kill_tree->shared = 0;
01652     return;
01653   }
01654 
01655   DeleteMlSizeList(kill_tree);
01656 
01657   if (kill_tree->id == NumTree - 1)
01658     NumTree--;
01659   if (deref) {
01660     bdd_recursive_deref_zdd(dd, kill_tree->node);
01661     st_delete(table, (char **)(&kill_tree->node), NIL(char *));
01662     if (kill_tree->complement) {
01663         bdd_recursive_deref_zdd(dd, kill_tree->complement);
01664         st_delete(table, (char **)(&kill_tree->complement), NIL(char *));
01665     }
01666   }
01667   pre = NIL(MlTree);
01668   cur = MlTreeHead;
01669   while (cur) {
01670     if (cur == kill_tree) {
01671       next = cur->next;
01672       if (pre)
01673         pre->next = next;
01674       else
01675         MlTreeHead = next;
01676       cur = next;
01677       if (!live_tree)
01678         break;
01679     } else {
01680       if (live_tree) {
01681         if (cur->q == kill_tree) {
01682           if (comp_flag)
01683             cur->q_comp ^= 01;
01684           cur->q = live_tree;
01685           cur->q_ref = 1;
01686           if (VerifyTreeMode)
01687             SynthVerifyTree(dd, cur, 0);
01688         } else if (cur->d == kill_tree) {
01689           if (comp_flag)
01690             cur->d_comp ^= 01;
01691           cur->d = live_tree;
01692           cur->d_ref = 1;
01693           if (VerifyTreeMode)
01694             SynthVerifyTree(dd, cur, 0);
01695         } else if (cur->r == kill_tree) {
01696           if (comp_flag)
01697             cur->r_comp ^= 01;
01698           cur->r = live_tree;
01699           cur->r_ref = 1;
01700           if (VerifyTreeMode)
01701             SynthVerifyTree(dd, cur, 0);
01702         }
01703       }
01704       pre = cur;
01705       cur = cur->next;
01706     }
01707   }
01708 
01709   if (kill_tree->leaf == 0) {
01710     if (kill_tree->q_ref) {
01711       if (kill_tree->q->shared)
01712         DeleteMlTree(dd, table, kill_tree->q, NULL, 1, 0);
01713     } else
01714       DeleteMlTree(dd, table, kill_tree->q, NULL, 1, 0);
01715     if (kill_tree->d_ref) {
01716       if (kill_tree->d->shared)
01717         DeleteMlTree(dd, table, kill_tree->d, NULL, 1, 0);
01718     } else
01719       DeleteMlTree(dd, table, kill_tree->d, NULL, 1, 0);
01720     if (kill_tree->r_ref) {
01721       if (kill_tree->r->shared)
01722         DeleteMlTree(dd, table, kill_tree->r, NULL, 1, 0);
01723     } else
01724       DeleteMlTree(dd, table, kill_tree->r, NULL, 1, 0);
01725   }
01726 
01727   if (kill_tree->support)
01728     FREE(kill_tree->support);
01729   FREE(kill_tree);
01730 }
01731 
01732 
01744 static void
01745 UnlinkMlTree(MlTree *kill_tree)
01746 {
01747   MlTree        *cur, *pre;
01748 
01749   DeleteMlSizeList(kill_tree);
01750 
01751   pre = (MlTree *)NULL;
01752   cur = MlTreeHead;
01753   while (cur) {
01754     if (cur == kill_tree) {
01755         if (pre)
01756           pre->next = cur->next;
01757         else
01758           MlTreeHead = cur->next;
01759         break;
01760     }
01761     pre = cur;
01762     cur = cur->next;
01763   }
01764 }
01765 
01766 
01778 static void
01779 DeleteMlSizeList(MlTree *tree)
01780 {
01781   MlTree        *head, *tail, *cur, *pre;
01782   MlSizeList    *list, *pre_list;
01783   int           size;
01784 
01785   size = tree->nLiterals;
01786   pre_list = NIL(MlSizeList);
01787   list = MlSizeHead;
01788   while (list) {
01789     if (size == list->size) {
01790       st_lookup(HeadListTable, list->string, (&head));
01791       st_lookup(TailListTable, list->string, (&tail));
01792       if (head == tail) {
01793         assert(tree == head);
01794         if (pre_list)
01795           pre_list->next = list->next;
01796         else
01797           MlSizeHead = list->next;
01798         st_delete(HeadListTable, (char **)&list->string, NIL(char *));
01799         st_delete(TailListTable, (char **)&list->string, NIL(char *));
01800         FREE(list->string);
01801         FREE(list);
01802       } else {
01803         pre = NIL(MlTree);
01804         cur = head;
01805         while (cur) {
01806           if (cur == tree) {
01807             if (cur == head) {
01808               st_delete(HeadListTable, (char **)&list->string, NIL(char *));
01809               st_insert(HeadListTable, list->string, (char *)cur->next);
01810             } else if (cur == tail) {
01811               st_delete(TailListTable, (char **)&list->string, NIL(char *));
01812               st_insert(TailListTable, list->string, (char *)pre);
01813             }
01814             break;
01815           }
01816           pre = cur;
01817           cur = cur->next;
01818         }
01819       }
01820       break;
01821     } else if (size > list->size)
01822       break;
01823     pre_list = list;
01824     list = list->next;
01825   }
01826 }
01827 
01828 
01840 static int
01841 InsertMlTable(st_table *table,
01842               bdd_node *node,
01843               MlTree *tree)
01844 {
01845   int           flag;
01846 
01847   flag = st_insert(table, (char *)node, (char *)tree);
01848   if (flag == ST_OUT_OF_MEM) {
01849     (void) fprintf(vis_stdout,"** synth error: Out of Memory.\n");
01850     noMemoryFlag = 1;
01851     return (0);
01852   } else if (flag == 1)
01853     (void) fprintf(vis_stdout, "** synth warning: Duplicate entry.\n");
01854   return(1);
01855 }
01856 
01857 
01869 static bdd_node *
01870 MakeComplementOfZddCover(bdd_manager *dd,
01871                          bdd_node *node,
01872                          int verbosity)
01873 {
01874   bdd_node      *comp;
01875 
01876   if (verbosity > 1) {
01877     (void) fprintf(vis_stdout,"*****\n");
01878     SynthPrintZddTreeMessage(dd, node, "R : ");
01879   }
01880 
01881   comp = bdd_zdd_complement(dd, node);
01882   if (!comp)
01883     return(NULL);
01884 
01885   if (verbosity > 1) {
01886     SynthPrintZddTreeMessage(dd, comp, "C : ");
01887     (void) fprintf(vis_stdout,"*****\n");
01888   }
01889 
01890   return(comp);
01891 }
01892 
01893 
01905 static  char *
01906 GetIntString(int v)
01907 {
01908   char  string[12];
01909   char  *ret;
01910 
01911   sprintf(string, "%d", v);
01912   ret = (char *)ALLOC(char, strlen(string) + 1);
01913   strcpy(ret, string);
01914   return(ret);
01915 }
01916 
01917 
01930 static void
01931 VerifyTreeList(void)
01932 {
01933   int           count;
01934   MlTree        *cur, *candy;
01935 
01936   cur = MlTreeHead;
01937   while (cur) {
01938     count = 0;
01939     candy = cur->next;
01940     if (candy && candy->nLiterals > cur->nLiterals) {
01941       (void) fprintf(vis_stdout,
01942              "** synth error: predecessor[%d]'s size < successor[%d]'s size.\n",
01943                      cur->id, candy->id);
01944     }
01945     while (candy) {
01946       if (cur->id != 0) {
01947         if (candy->id == cur->id && candy != cur) {
01948           (void) fprintf(vis_stdout,
01949                  "** synth error: same id already exists [%d].\n", cur->id);
01950           break;
01951         }
01952       }
01953       if (candy == cur) {
01954         if (count > 0) {
01955           (void) fprintf(vis_stdout,
01956                  "** synth error: same address already exists [%d - 0x%lx].\n",
01957                          cur->id, (unsigned long)cur);
01958           break;
01959         }
01960         count++;
01961       }
01962       candy = candy->next;
01963     }
01964     cur = cur->next;
01965   }
01966 }