VIS

src/baig/baigNode.c

Go to the documentation of this file.
00001 
00020 #include "vm.h"
00021 #include "baig.h"
00022 #include "baigInt.h"
00023 
00024 static char rcsid[] UNUSED = "$Id: baigNode.c,v 1.33 2009/04/12 00:14:03 fabio Exp $";
00025 
00026 /*---------------------------------------------------------------------------*/
00027 /* Constant declarations                                                     */
00028 /*---------------------------------------------------------------------------*/
00029 
00032 /*---------------------------------------------------------------------------*/
00033 /* Static function prototypes                                                */
00034 /*---------------------------------------------------------------------------*/
00035 
00036 static void connectOutput(bAig_Manager_t *manager, bAigEdge_t from, bAigEdge_t to, int inputIndex);
00037 static bAigEdge_t HashTableLookup(bAig_Manager_t *manager, bAigEdge_t node1, bAigEdge_t node2);
00038 static int HashTableAdd(bAig_Manager_t *manager, bAigEdge_t nodeIndexParent, bAigEdge_t nodeIndex1, bAigEdge_t nodeIndex2);
00039 static int HashTableDelete(bAig_Manager_t *manager, bAigEdge_t node);
00040 
00044 /*---------------------------------------------------------------------------*/
00045 /* Definition of exported functions                                          */
00046 /*---------------------------------------------------------------------------*/
00047 
00048 
00060 nameType_t *
00061 bAig_NodeReadName(
00062    bAig_Manager_t *manager,
00063    bAigEdge_t     node)
00064 {
00065   return manager->nameList[bAigNodeID(node)];
00066 }
00067 
00079 void 
00080 bAig_NodeSetName(
00081    bAig_Manager_t *manager,
00082    bAigEdge_t     node,
00083    nameType_t     *name)
00084 {
00085   nameType_t *tmpName = manager->nameList[bAigNodeID(node)];
00086   FREE(tmpName);
00087   st_insert(manager->SymbolTable, name, (char*) (long) node);
00088   manager->nameList[bAigNodeID(node)] = name;
00089 }
00090 
00102 int
00103 bAig_NodeReadIndexOfRightChild(
00104    bAig_Manager_t *manager,
00105    bAigEdge_t nodeIndex)
00106 {
00107   return rightChild(nodeIndex);
00108 }
00109 
00121 bAigEdge_t
00122 bAig_NodeReadIndexOfLeftChild(
00123    bAig_Manager_t *manager,
00124    bAigEdge_t nodeIndex)
00125 {
00126   return leftChild(nodeIndex);
00127 }
00128 
00140 bAigEdge_t
00141 bAig_GetCanonical(
00142     bAig_Manager_t *manager, 
00143     bAigEdge_t nodeIndex)
00144 {
00145 bAigEdge_t next;
00146 
00147 /*if(nodeIndex == bAig_NULL)    return(nodeIndex);*/
00148 
00149 //Bing: 
00150  if(nodeIndex == bAig_NULL||
00151     nodeIndex == bAig_One ||
00152     nodeIndex == bAig_Zero)
00153    return(nodeIndex); 
00154 
00155   while(bAigGetPassFlag(manager, nodeIndex)) {
00156     next = canonical(nodeIndex);
00157     if(bAig_IsInverted(nodeIndex))  next = bAig_Not(next);
00158     nodeIndex = next;
00159   }
00160   return(nodeIndex);
00161 }
00162 
00174 int
00175 bAig_Merge(
00176     bAig_Manager_t *manager,
00177     bAigEdge_t nodeIndex1,
00178     bAigEdge_t nodeIndex2)
00179 {
00180 bAigEdge_t newNodeIndex, nodeIndex, tnodeIndex;
00181 bAigEdge_t leftIndex, rightIndex;
00182 bAigEdge_t outIndex, *pfan;
00183 int id1, id2;
00184 bAigEdge_t cur;
00185 bdd_t **bddArray;
00186 array_t *nodeArray;
00187 int i, ii, iii;
00188 long *ManagerNodesArray;
00189 
00190   nodeIndex1 = bAig_GetCanonical(manager, nodeIndex1);
00191   nodeIndex2 = bAig_GetCanonical(manager, nodeIndex2);
00192 
00193   if(nodeIndex1 == nodeIndex2)  return(nodeIndex1);
00194 
00195 
00196   ManagerNodesArray = manager->NodesArray;
00197 
00198 
00199   newNodeIndex = nodeIndex1;     
00200   if (bAig_NonInvertedEdge(nodeIndex1) > bAig_NonInvertedEdge(nodeIndex2)){
00201     nodeIndex1 = nodeIndex2;
00202     nodeIndex2 = newNodeIndex;
00203   }
00204 
00205   if(bAig_IsInverted(nodeIndex2)) {
00206     nodeIndex1 = bAig_Not(nodeIndex1);
00207     nodeIndex2 = bAig_Not(nodeIndex2);
00208   }
00209 
00210   nodeArray = array_alloc(bAigEdge_t, 0);
00211   nodeIndex = nodeIndex2;
00212   array_insert_last(bAigEdge_t, nodeArray, nodeIndex);
00213   while(bAig_NonInvertedEdge(canonical(nodeIndex)) != bAig_NonInvertedEdge(nodeIndex2)){
00214     if(bAig_IsInverted(nodeIndex))
00215       nodeIndex = bAig_Not(canonical(nodeIndex));
00216     else
00217       nodeIndex = canonical(nodeIndex);
00218     array_insert_last(bAigEdge_t, nodeArray, nodeIndex);
00219   }
00220 
00221   bAigSetPassFlag(manager, nodeIndex2);
00222   nodeIndex = nodeIndex1;
00223   while(bAig_NonInvertedEdge(canonical(nodeIndex)) != bAig_NonInvertedEdge(nodeIndex1)) {
00224     if(bAig_IsInverted(nodeIndex))
00225       nodeIndex = bAig_Not(canonical(nodeIndex));
00226     else
00227       nodeIndex = canonical(nodeIndex);
00228   }
00229 
00230   for(i=0; i<array_n(nodeArray); i++) {
00231     tnodeIndex = array_fetch(bAigEdge_t, nodeArray, i);
00232     if(bAig_IsInverted(nodeIndex))
00233       canonical(nodeIndex) = bAig_Not(tnodeIndex);
00234     else 
00235       canonical(nodeIndex) = tnodeIndex;
00236 
00237     if(bAig_IsInverted(nodeIndex))
00238       nodeIndex = bAig_Not(canonical(nodeIndex));
00239     else
00240       nodeIndex = canonical(nodeIndex);
00241   }
00242 
00243   if(bAig_IsInverted(nodeIndex))        {
00244     canonical(nodeIndex) = bAig_Not(nodeIndex1);
00245   }
00246   else {
00247     canonical(nodeIndex) = nodeIndex1;
00248   }
00249   array_free(nodeArray);
00250 
00251   nodeArray = array_alloc(bAigEdge_t, 0);
00252   bAigEdgeForEachFanout(manager, nodeIndex2, cur, ii, iii, pfan) {
00253     cur = cur >> 1;
00254     cur = bAig_NonInvertedEdge(cur);
00255     array_insert_last(bAigEdge_t, nodeArray, cur);
00256   }
00257 
00258   for(i=0; i<array_n(nodeArray); i++) {
00259     outIndex = array_fetch(bAigEdge_t, nodeArray, i);
00260     leftIndex = leftChild(outIndex);
00261     rightIndex = rightChild(outIndex);
00262 
00263     HashTableDelete(manager, outIndex);
00264 
00265     newNodeIndex = bAig_And(manager, leftIndex, rightIndex);
00266 
00267     bAig_Merge(manager, newNodeIndex, outIndex);
00268 
00269   }
00270   array_free(nodeArray);
00271 
00272   bddArray = manager->bddArray;
00273   id1 = bAigNodeID(nodeIndex1);
00274   id2 = bAigNodeID(nodeIndex2);
00275   if(bddArray[id1] == 0 && bddArray[id2]){ 
00276     if(bAig_IsInverted(nodeIndex2)) {
00277       if(bAig_IsInverted(nodeIndex1)) {
00278         bddArray[id1] = bdd_dup(bddArray[id2]);
00279       }
00280       else {
00281         bddArray[id1] = bdd_not(bddArray[id2]);
00282       }
00283     }
00284     else {
00285       if(bAig_IsInverted(nodeIndex1)) {
00286         bddArray[id1] = bdd_not(bddArray[id2]);
00287       }
00288       else {
00289         bddArray[id1] = bdd_dup(bddArray[id2]);
00290       }
00291     }
00292   }
00293   return(nodeIndex1);
00294 }
00295 
00296 
00297 
00310 void
00311 bAig_PrintNode(
00312   bAig_Manager_t *manager,
00313   bAigEdge_t i)
00314 {
00315   int j, size;
00316   long cur, *pfan;
00317 
00318   fprintf(vis_stdout, "nodeIndex : %ld (%ld)\n", i, bAigNodeID(i)); 
00319   fprintf(vis_stdout, "child     : %ld%c, %ld%c\n", 
00320           bAig_NonInvertedEdge(leftChild(i)), bAig_IsInverted(leftChild(i)) ? '\'' : ' ', 
00321           bAig_NonInvertedEdge(rightChild(i)), bAig_IsInverted(rightChild(i)) ? '\'' : ' ');
00322   fprintf(vis_stdout, "canonical : %s (%ld)\n", 
00323           bAigGetPassFlag(manager, i) ? "pass" : "true", bAig_GetCanonical(manager, i));
00324   fprintf(vis_stdout, "refCount  : %ld\n", nFanout(i));
00325   fprintf(vis_stdout, "          : ");
00326   size = nFanout(i);
00327   for(j=0, pfan = (bAigEdge_t *)fanout(i); j<size; j++) {
00328     cur = pfan[j];
00329     cur = cur >> 1;
00330     fprintf(vis_stdout, " %ld", cur);
00331   }
00332   fprintf(vis_stdout, "\n");
00333 
00334   fprintf(vis_stdout, "next      : %ld\n", next(i));
00335   fflush(vis_stdout);
00336 }
00337    
00338 
00352 bAigEdge_t
00353 bAig_And(
00354    bAig_Manager_t *manager,
00355    bAigEdge_t nodeIndex1,
00356    bAigEdge_t nodeIndex2)
00357 {
00358 
00359   bAigEdge_t newNodeIndex;
00360 
00361   nodeIndex1 = bAig_GetCanonical(manager, nodeIndex1);
00362   nodeIndex2 = bAig_GetCanonical(manager, nodeIndex2);
00363 
00364   newNodeIndex = nodeIndex1;     /* The left node has the smallest index */
00365   if (bAig_NonInvertedEdge(nodeIndex1) > bAig_NonInvertedEdge(nodeIndex2)){
00366     nodeIndex1 = nodeIndex2;
00367     nodeIndex2 = newNodeIndex;
00368   }
00369 
00370   if ( nodeIndex2 == bAig_Zero ) {
00371     return bAig_Zero;
00372   }
00373   if ( nodeIndex1 == bAig_Zero ) {
00374     return bAig_Zero;
00375   }
00376   if ( nodeIndex2 == bAig_One ) {
00377     return nodeIndex1;
00378   }
00379   if ( nodeIndex1 == bAig_One ) {
00380     return nodeIndex2;
00381   }
00382   if ( nodeIndex1 == nodeIndex2 ) {
00383     return nodeIndex1;
00384   }
00385   if ( nodeIndex1 == bAig_Not(nodeIndex2) ) {
00386     return bAig_Zero;
00387   }
00388 
00389   /* Look for the new node in the Hash table */
00390   newNodeIndex = HashTableLookup(manager, nodeIndex1, nodeIndex2);
00391 
00392   if (newNodeIndex == bAig_NULL){ 
00393     if(bAigIsVar(manager, nodeIndex1) && bAigIsVar(manager, nodeIndex2))
00394       newNodeIndex = bAig_And2(manager, nodeIndex1, nodeIndex2);
00395     else if(bAigIsVar(manager, nodeIndex1)) 
00396       newNodeIndex = bAig_And3(manager, nodeIndex1, nodeIndex2);
00397     else if(bAigIsVar(manager, nodeIndex2)) 
00398       newNodeIndex = bAig_And3(manager, nodeIndex2, nodeIndex1);
00399     else {
00400       newNodeIndex = bAig_And4(manager, nodeIndex1, nodeIndex2);
00401     }
00402   }
00403     
00404   return newNodeIndex;
00405 
00406 }
00407 
00419 bAigEdge_t
00420 bAig_And2(
00421    bAig_Manager_t *manager,
00422    bAigEdge_t nodeIndex1,
00423    bAigEdge_t nodeIndex2)
00424 {
00425   bAigEdge_t newNodeIndex;
00426 
00427   nodeIndex1 = bAig_GetCanonical(manager, nodeIndex1);
00428   nodeIndex2 = bAig_GetCanonical(manager, nodeIndex2);
00429 
00430   newNodeIndex = nodeIndex1;     /* The left node has the smallest index */
00431   if (bAig_NonInvertedEdge(nodeIndex1) > bAig_NonInvertedEdge(nodeIndex2)){
00432     nodeIndex1 = nodeIndex2;
00433     nodeIndex2 = newNodeIndex;
00434   }
00435   if ( nodeIndex2 == bAig_Zero ) {
00436     return bAig_Zero;
00437   }
00438   if ( nodeIndex1 == bAig_Zero ) {
00439     return bAig_Zero;
00440   }
00441   if ( nodeIndex2 == bAig_One ) {
00442     return nodeIndex1;
00443   }
00444   if ( nodeIndex1 == bAig_One ) {
00445     return nodeIndex2;
00446   }
00447   if ( nodeIndex1 == nodeIndex2 ) {
00448     return nodeIndex1;
00449   }
00450   if ( nodeIndex1 == bAig_Not(nodeIndex2) ) {
00451     return bAig_Zero;
00452   }
00453   newNodeIndex = HashTableLookup(manager, nodeIndex1, nodeIndex2);
00454 
00455   if (newNodeIndex == bAig_NULL){ 
00456     newNodeIndex = bAigCreateAndNode(manager, nodeIndex1, nodeIndex2) ;
00457 
00458     HashTableAdd(manager, newNodeIndex, nodeIndex1, nodeIndex2);
00459     connectOutput(manager, nodeIndex1, newNodeIndex, 0);
00460     connectOutput(manager, nodeIndex2, newNodeIndex, 1);
00461 
00462 #if 0
00463 #ifdef LEARNING_
00464     tNodeIndex = HashTableLookup(manager, bAig_Not(nodeIndex1), nodeIndex2);
00465     if(tNodeIndex) bAig_Learn(manager, nodeIndex1, nodeIndex2);
00466 
00467     tNodeIndex = HashTableLookup(manager, nodeIndex1, bAig_Not(nodeIndex2));
00468     if(tNodeIndex) bAig_Learn(manager, nodeIndex2, nodeIndex1);
00469 #endif
00470 #endif
00471   }
00472   return newNodeIndex;
00473 
00474 }
00475 
00476 
00490 bAigEdge_t
00491 bAig_Or(
00492    bAig_Manager_t *manager,
00493    bAigEdge_t nodeIndex1,
00494    bAigEdge_t nodeIndex2)
00495 {
00496   return ( bAig_Not(bAig_And(manager,  bAig_Not(nodeIndex1),  bAig_Not(nodeIndex2))));
00497 }
00498 
00512 bAigEdge_t
00513 bAig_Xor(
00514    bAig_Manager_t *manager,
00515    bAigEdge_t nodeIndex1,
00516    bAigEdge_t nodeIndex2)
00517 {
00518  return bAig_Or(manager,
00519             bAig_And(manager, nodeIndex1, bAig_Not(nodeIndex2)),
00520             bAig_And(manager, bAig_Not(nodeIndex1),nodeIndex2)
00521         );
00522 }
00523 
00537 bAigEdge_t
00538 bAig_Eq(
00539    bAig_Manager_t *manager,
00540    bAigEdge_t nodeIndex1,
00541    bAigEdge_t nodeIndex2)
00542 {
00543  return bAig_Not(
00544             bAig_Xor(manager, nodeIndex1, nodeIndex2)
00545             );
00546 }
00547 
00561 bAigEdge_t
00562 bAig_Then(
00563    bAig_Manager_t *manager,
00564    bAigEdge_t nodeIndex1,
00565    bAigEdge_t nodeIndex2)
00566 {
00567  return bAig_Or(manager,
00568                 bAig_Not(nodeIndex1),
00569                 nodeIndex2);
00570 }
00571 
00583 bAigEdge_t
00584 bAig_CreateNode(
00585    bAig_Manager_t  *manager,
00586    bAigEdge_t nodeIndex1,
00587    bAigEdge_t nodeIndex2)
00588 {
00589   
00590   bAigEdge_t newNode = manager->nodesArraySize;
00591 
00592   if (manager->nodesArraySize >= manager->maxNodesArraySize ){
00593     manager->maxNodesArraySize = 2* manager->maxNodesArraySize;
00594     manager->NodesArray = REALLOC(bAigEdge_t, manager->NodesArray, manager->maxNodesArraySize);
00595     manager->nameList   = REALLOC(char *,     manager->nameList  , manager->maxNodesArraySize/bAigNodeSize);
00596     manager->bddIdArray = REALLOC(int ,     manager->bddIdArray  , manager->maxNodesArraySize/bAigNodeSize);
00597     manager->bddArray   = REALLOC(bdd_t *,     manager->bddArray  , manager->maxNodesArraySize/bAigNodeSize);
00598   }
00599   manager->NodesArray[bAig_NonInvertedEdge(newNode)+bAigRight] = nodeIndex2;
00600   manager->NodesArray[bAig_NonInvertedEdge(newNode)+bAigLeft]  = nodeIndex1;
00601  
00602   next(newNode)     = bAig_NULL;
00603   fanout(newNode) = 0;
00604   canonical(newNode) = newNode;
00605   flags(newNode) = 0;
00606   nFanout(newNode) = 0;
00607   manager->bddIdArray[bAigNodeID(newNode)] = -1; 
00608   manager->bddArray[bAigNodeID(newNode)] = 0; 
00609 
00610   manager->nodesArraySize +=bAigNodeSize;
00611   
00612   //Bing: for interpolation
00613   aig_value(newNode) = 2;
00614   manager->nameList[bAigNodeID(newNode)] = 0;
00615   manager->NodesArray[newNode+bAigClass] = manager->class_;
00616   
00617   return(newNode);
00618 }
00619 
00620 
00628 bAigEdge_t
00629 bAig_FindNodeByName(
00630   bAig_Manager_t *manager,
00631   nameType_t     *name)
00632 {
00633    
00634   bAigEdge_t node;
00635 
00636   if (!st_lookup(manager->SymbolTable, name, &node)){
00637     node = bAig_NULL;
00638   }
00639 
00640   return bAig_GetCanonical(manager, node);
00641 }
00642 
00643 
00655 bAigEdge_t
00656 bAig_CreateVarNode(
00657    bAig_Manager_t  *manager,
00658    nameType_t      *name)
00659 {
00660    
00661   bAigEdge_t varIndex;
00662 
00663 
00664   if (!st_lookup(manager->SymbolTable, name, &varIndex)){
00665     varIndex = bAig_CreateNode(manager, bAig_NULL, bAig_NULL);
00666     if (varIndex == bAig_NULL){
00667       return (varIndex);
00668     } 
00669     /* Insert the varaible in the Symbol Table */
00670     st_insert(manager->SymbolTable, name, (char*) (long) varIndex);
00671     manager->nameList[bAigNodeID(varIndex)] = name; 
00672     return(varIndex);
00673   }
00674   else {
00675     return (varIndex);
00676   }
00677 }
00678 
00686 int 
00687 bAig_isVarNode(
00688    bAig_Manager_t *manager,
00689    bAigEdge_t      node)
00690 {
00691   if((rightChild(node) == bAig_NULL) && (leftChild(node) == bAig_NULL)) {
00692     return 1;
00693   }
00694   return 0;
00695 }
00696 
00697 
00698 
00713 bAigEdge_t
00714 bAig_bddTobAig(
00715    bAig_Manager_t *bAigManager,
00716    bdd_t          *fn)
00717 {
00718   bdd_gen     *gen;
00719   bdd_node    *node, *thenNode, *elseNode, *funcNode;
00720   bdd_manager *bddManager = bdd_get_manager(fn);
00721   /*
00722     Used to read the variable name of a bdd node.
00723   */
00724   array_t     *mvar_list  = mdd_ret_mvar_list(bddManager);
00725   array_t     *bvar_list  = mdd_ret_bvar_list(bddManager);
00726   bvar_type   bv;
00727   mvar_type   mv;
00728   
00729   bdd_node    *one        = bdd_read_one(bddManager);  
00730   int         is_complemented;
00731   int         flag;  
00732   bAigEdge_t  var, left, right, result;
00733   
00734   char      name[100];
00735   st_table  *bddTObaigTable;
00736   
00737   if (fn == NULL){
00738     return bAig_NULL;
00739   }
00740   funcNode = bdd_get_node(fn, &is_complemented);
00741   if (bdd_is_constant(funcNode)){
00742     return (is_complemented?bAig_Zero:bAig_One);
00743   }
00744   bddTObaigTable = st_init_table(st_numcmp, st_numhash);
00745   st_insert(bddTObaigTable, (char *) (long) bdd_regular(one),  (char *) bAig_One);
00746 
00747   foreach_bdd_node(fn, gen, node){
00748     int nodeIndex = bdd_node_read_index(node);
00749     int index, rtnNodeIndex;
00750 
00751     if (bdd_is_constant(node)){
00752       continue;
00753     }
00754 
00755     bv = array_fetch(bvar_type, bvar_list, nodeIndex);
00756     /*
00757       get the multi-valued varaible.
00758      */
00759     mv = array_fetch(mvar_type, mvar_list, bv.mvar_id);
00760     arrayForEachItem(int, mv.bvars, index, rtnNodeIndex) {
00761       if (nodeIndex == rtnNodeIndex){
00762         break;
00763       }
00764     }
00765     assert(index < mv.encode_length);
00766     /*
00767     printf("Name of bdd node %s %d\n", mv.name, index);
00768     */
00769     sprintf(name, "%s_%d", mv.name, index);
00770     /*
00771       Create or Retrieve the bAigEdge_t  w.r.t. 'name'
00772     */
00773     var  = bAig_CreateVarNode(bAigManager, util_strsav(name));
00774 
00775     thenNode  = bdd_bdd_T(node);
00776     flag = st_lookup(bddTObaigTable, (char *) (long) bdd_regular(thenNode),
00777                      &left);
00778     assert(flag);
00779       
00780     elseNode  = bdd_bdd_E(node);
00781     flag = st_lookup(bddTObaigTable, (char *) (long) bdd_regular(elseNode),
00782                      &right);
00783     assert(flag);
00784     /*
00785      test if the elseNode is complemented arc?
00786     */
00787     if (bdd_is_complement(elseNode)){
00788       right = bAig_Not(right);
00789     }
00790     if (right ==  bAig_Zero){        /* result = var*then */
00791       result =  bAig_And(bAigManager, var, left);
00792     } else if (right ==  bAig_One){        /* result = then + not(var) */
00793       result =  bAig_Or(bAigManager, left, bAig_Not(var));
00794     } else if (left ==  bAig_One) { /* result = var + else */
00795       result =  bAig_Or(bAigManager, var, right);      
00796     } else {                        /* result = var * then + not(var)*else */
00797       result =  bAig_Or(bAigManager, bAig_And(bAigManager, var, left),
00798                         bAig_And(bAigManager, bAig_Not(var), right));
00799     }
00800     st_insert(bddTObaigTable, (char *) (long) bdd_regular(node),
00801               (char *) (long) result);
00802   }
00803   flag = st_lookup(bddTObaigTable, (char *) (long) bdd_regular(funcNode),
00804                    &result);  
00805   assert(flag);
00806   st_free_table(bddTObaigTable);
00807 
00808   if (is_complemented){
00809     return bAig_Not(result);
00810   } else {
00811     return result;
00812   }
00813 } /* end of bAig_bddtobAig() */
00814 
00815 
00823 int
00824 bAig_PrintDot(
00825   FILE *fp,
00826   bAig_Manager_t *manager)
00827 {
00828   long i;
00829 
00830   /*
00831    * Write out the header for the output file.
00832    */
00833   (void) fprintf(fp, "digraph \"AndInv\" {\n  rotate=90;\n");
00834   (void) fprintf(fp, "  margin=0.5;\n  label=\"AndInv\";\n");
00835   (void) fprintf(fp, "  size=\"10,7.5\";\n  ratio=\"fill\";\n");
00836  
00837   
00838   for (i=bAigFirstNodeIndex ; i< manager->nodesArraySize ; i+=bAigNodeSize){
00839     (void) fprintf(fp,"Node%ld  [label=\"%s \"];\n",i,bAig_NodeReadName(manager, i));
00840   }
00841   for (i=bAigFirstNodeIndex ; i< manager->nodesArraySize ; i+=bAigNodeSize){
00842     if (rightChild(i) != bAig_NULL){
00843       if (bAig_IsInverted(rightChild(i))){
00844         (void) fprintf(fp,"Node%ld -> Node%ld [color = red];\n",bAig_NonInvertedEdge(rightChild(i)), i);
00845       }
00846       else{
00847         (void) fprintf(fp,"Node%ld -> Node%ld;\n",bAig_NonInvertedEdge(rightChild(i)), i);
00848       }
00849       if (bAig_IsInverted(leftChild(i))){
00850         (void) fprintf(fp,"Node%ld -> Node%ld [color = red];\n",bAig_NonInvertedEdge(leftChild(i)), i);
00851       }
00852       else{
00853         (void) fprintf(fp,"Node%ld -> Node%ld;\n",bAig_NonInvertedEdge(leftChild(i)), i);
00854       }
00855     }/* if */ 
00856   }/*for */
00857 
00858   (void) fprintf(fp, "}\n");
00859 
00860   return 1;
00861 }
00862 
00863 
00864 
00876 void 
00877 bAigSetPassFlag(
00878     bAig_Manager_t  *manager,
00879     bAigEdge_t node)
00880 {
00881 
00882    flags(node) |= CanonicalBitMask;
00883 }
00884 
00896 void 
00897 bAigResetPassFlag(
00898     bAig_Manager_t  *manager,
00899     bAigEdge_t node)
00900 {
00901 
00902    flags(node) &= ResetCanonicalBitMask;
00903 }
00904 
00916 int
00917 bAigGetPassFlag(
00918     bAig_Manager_t  *manager,
00919     bAigEdge_t node)
00920    
00921 {
00922 
00923   return((flags(node) & CanonicalBitMask) != 0);
00924 }
00925 
00926 
00927 
00939 bAigEdge_t
00940 bAigCreateAndNode(
00941    bAig_Manager_t  *manager,
00942    bAigEdge_t node1,
00943    bAigEdge_t node2)
00944 {
00945    
00946   bAigEdge_t varIndex;
00947   char       *name = NIL(char);
00948   char       *node1Str = util_inttostr(node1);
00949   char       *node2Str = util_inttostr(node2);
00950 
00951   name = util_strcat4("Nd", node1Str,"_", node2Str);
00952   while (st_lookup(manager->SymbolTable, name, &varIndex)){
00953     printf("Find redundant node at %ld %ld\n", node1, node2);
00954     name = util_strcat3(name, node1Str, node2Str);
00955   }
00956   FREE(node1Str);
00957   FREE(node2Str);
00958   varIndex = bAig_CreateNode(manager, node1, node2);
00959   if (varIndex == bAig_NULL){
00960     FREE(name);
00961     return (varIndex);
00962   } 
00963   /* Insert the varaible in the Symbol Table */
00964   st_insert(manager->SymbolTable, name, (char*) (long) varIndex);
00965   manager->nameList[bAigNodeID(varIndex)] = name; 
00966 
00967   return(varIndex);
00968 
00969 }
00970 
00971 /*---------------------------------------------------------------------------*/
00972 /* Definition of static functions                                            */
00973 /*---------------------------------------------------------------------------*/
00974 
00986 static void
00987 connectOutput(
00988    bAig_Manager_t *manager,
00989    bAigEdge_t from,
00990    bAigEdge_t to,
00991    int inputIndex)
00992 {
00993   bAigEdge_t *pfan;
00994   int nfan;
00995 
00996   to = bAig_NonInvertedEdge(to);
00997   pfan = (bAigEdge_t *)fanout(from);
00998   nfan = nFanout(from);
00999   if(nfan == 0) pfan = ALLOC(bAigEdge_t, 2);
01000   else          pfan = REALLOC(bAigEdge_t, pfan, nfan+2);
01001   to += bAig_IsInverted(from);
01002   to = to << 1;
01003   to += inputIndex;
01004   pfan[nfan++] = to;
01005   pfan[nfan] = 0;
01006   fanout(from) = (long)pfan;
01007   nFanout(from) = nfan;
01008 }
01009 
01010 
01065 static bAigEdge_t
01066 HashTableLookup(
01067   bAig_Manager_t *manager,  
01068   bAigEdge_t  node1,
01069   bAigEdge_t  node2)
01070 {
01071   bAigEdge_t key = HashTableFunction(node1, node2);
01072   bAigEdge_t node;
01073   
01074   node = manager->HashTable[key];
01075   if  (node == bAig_NULL) {
01076     return bAig_NULL;
01077   }
01078   else{
01079     while ( (rightChild(bAig_NonInvertedEdge(node)) != node2) ||
01080             (leftChild(bAig_NonInvertedEdge(node))  != node1)) {
01081   
01082       if (next(bAig_NonInvertedEdge(node)) == bAig_NULL){
01083         return(bAig_NULL); 
01084       }
01085       node = next(bAig_NonInvertedEdge(node)); /* Get the next Node */
01086     } /* While loop */ 
01087     return(node);
01088 
01089   } /* If Then Else */
01090     
01091 } /* End of HashTableLookup() */
01092 
01104 static int
01105 HashTableAdd(
01106   bAig_Manager_t   *manager,  
01107   bAigEdge_t  nodeIndexParent,
01108   bAigEdge_t  nodeIndex1,
01109   bAigEdge_t  nodeIndex2)
01110 {
01111   bAigEdge_t key = HashTableFunction(nodeIndex1, nodeIndex2);
01112   bAigEdge_t nodeIndex;
01113   bAigEdge_t node;
01114                                                 
01115   nodeIndex = manager->HashTable[key];
01116   if  (nodeIndex == bAig_NULL) {
01117     manager->HashTable[key] = nodeIndexParent;
01118     return TRUE;
01119   }
01120   else{
01121     node = nodeIndex;
01122     nodeIndex = next(bAig_NonInvertedEdge(nodeIndex));  /* Get the Node */
01123     while (nodeIndex != bAig_NULL) {
01124       node = nodeIndex;
01125       nodeIndex = next(bAig_NonInvertedEdge(nodeIndex));
01126     }
01127     next(bAig_NonInvertedEdge(node)) = nodeIndexParent;
01128     return TRUE;
01129   }
01130     
01131 } /* End of HashTableAdd() */
01132 
01133 
01145 static int
01146 HashTableDelete(
01147   bAig_Manager_t   *manager,  
01148   bAigEdge_t  node)
01149 {
01150   bAigEdge_t key = HashTableFunction(leftChild(node), rightChild(node));
01151   bAigEdge_t nodeIndex;
01152                                                 
01153   nodeIndex = manager->HashTable[key];
01154   if (nodeIndex == node) {
01155     manager->HashTable[key] = next(node);
01156     return TRUE;
01157   }
01158   else{
01159     while(nodeIndex && next(bAig_NonInvertedEdge(nodeIndex)) != node)
01160       nodeIndex = next(bAig_NonInvertedEdge(nodeIndex));
01161 
01162     next(bAig_NonInvertedEdge(nodeIndex)) = 
01163         next(bAig_NonInvertedEdge(next(bAig_NonInvertedEdge(nodeIndex))));
01164     return TRUE;
01165   }
01166     
01167 } /* End of HashTableAdd() */
01168 
01169 
01182 bAigEdge_t
01183 bAig_And4(
01184            bAig_Manager_t *manager,
01185            bAigEdge_t l,
01186            bAigEdge_t r)
01187 {
01188   int caseIndex, caseSig;
01189   bAigEdge_t ll, lr, rl, rr;
01190   bAigEdge_t t1, t2;
01191 
01192   ll = leftChild(l);
01193   lr = rightChild(l);
01194   rl = leftChild(r);
01195   rr = rightChild(r);
01196 
01197   if(bAigCompareNode(l, rl) ||
01198      bAigCompareNode(l, rr)) {
01199     return(bAig_And3(manager, l, r));
01200   }
01201   else if(bAigCompareNode(r, ll) ||
01202      bAigCompareNode(r, lr)) {
01203     return(bAig_And3(manager, r, l));
01204   }
01205 
01206   if(ll > lr+1) bAigSwap(ll, lr);
01207   if(rl > rr+1) bAigSwap(rl, rr);
01208 
01209   caseIndex = 0; /* (a b)(c d) */
01210   if(bAigCompareNode(ll, rl)) {
01211     if(bAigCompareNode(lr, rr)) {
01212       caseIndex = 4; /* (a b) (a b) */
01213     }
01214     else {
01215       caseIndex = 1; /* (a b) (a c) */
01216       if(lr > rr+1) {
01217         bAigSwap(ll, rl);
01218         bAigSwap(lr, rr); 
01219         bAigSwap(l, r); 
01220       }
01221     }
01222   }
01223   else if(bAigCompareNode(lr, rl)) {
01224     caseIndex = 2; /* (b a)(a c) */
01225   }
01226   else if(bAigCompareNode(lr, rr)) {
01227     caseIndex = 3; /* (b a)(c a) */
01228     if(ll > rl+1) {
01229       bAigSwap(ll, rl);
01230       bAigSwap(lr, rr); 
01231       bAigSwap(l, r); 
01232     }
01233   }
01234   else if(bAigCompareNode(ll, rr)) {
01235     /* (a b)(c a)  */
01236     bAigSwap(ll, rl);
01237     bAigSwap(lr, rr); 
01238     bAigSwap(l, r); 
01239     caseIndex = 2; /* (c a )(a b) because of c < b */
01240   }
01241 
01242   caseSig = 0;
01243   if(bAig_IsInverted(ll)) caseSig += 32;
01244   if(bAig_IsInverted(lr)) caseSig += 16;
01245   if(bAig_IsInverted(l))  caseSig += 8;
01246   if(bAig_IsInverted(rl)) caseSig += 4;
01247   if(bAig_IsInverted(rr)) caseSig += 2;
01248   if(bAig_IsInverted(r))  caseSig += 1;
01261   if(caseIndex == 0) {
01262     return(bAig_And2(manager, l, r));
01263   }
01264   else if(caseIndex == 1) {
01265     switch(caseSig) {
01266         case 19 :
01267         case 17 :
01268         case 3 :
01269         case 1 :
01270         case 55 :
01271         case 53 :
01272         case 39 :
01273         case 37 :
01274       t1 = bAig_And(manager, lr, bAig_Not(rr));
01275       t2 = bAig_And(manager, ll, t1);
01276       return(t2);
01277         case 18 :
01278         case 16 :
01279         case 2 :
01280         case 0 :
01281         case 54 :
01282         case 52 :
01283         case 38 :
01284         case 36 :
01285       t1 = bAig_And(manager, lr, rr);
01286       t2 = bAig_And(manager, ll, t1);
01287       return(t2);
01288         case 26 :
01289         case 24 :
01290         case 10 :
01291         case 8 :
01292         case 62 :
01293         case 60 :
01294         case 46 :
01295         case 44 :
01296       t1 = bAig_And(manager, bAig_Not(lr), rr);
01297       t2 = bAig_And(manager, ll, t1);
01298       return(t2);
01299         case 61 :
01300         case 27 :
01301         case 25 :
01302         case 11 :
01303         case 63 :
01304         case 47 :
01305         case 9 :
01306         case 45 :
01307       t1 = bAig_And(manager, bAig_Not(lr), bAig_Not(rr));
01308       t2 = bAig_Or(manager, bAig_Not(ll), t1);
01309       return(t2);
01310         case 23 :
01311         case 21 :
01312         case 7 :
01313         case 5 :
01314         case 51 :
01315         case 49 :
01316         case 35 :
01317         case 33 :
01318       return(l);
01319         case 30 :
01320         case 28 :
01321         case 14 :
01322         case 12 :
01323         case 58 :
01324         case 56 :
01325         case 42 :
01326         case 40 :
01327       return(r);
01328         case 22 :
01329         case 20 :
01330         case 6 :
01331         case 4 :
01332         case 50 :
01333         case 48 :
01334         case 34 :
01335         case 32 :
01336       return(bAig_Zero);
01337         case 31 :
01338         case 29 :
01339         case 15 :
01340         case 13 :
01341         case 59 :
01342         case 57 :
01343         case 43 :
01344         case 41 :
01345       t1 = bAig_And2(manager, l, r);
01346       return(t1);
01347     }
01348   }
01349   else if(caseIndex == 2) {
01350     switch(caseSig) {
01351         case 35 :
01352         case 33 :
01353         case 3 :
01354         case 1 :
01355         case 55 :
01356         case 53 :
01357         case 23 :
01358         case 21 :
01359       t1 = bAig_And(manager, lr, bAig_Not(rr));
01360       t2 = bAig_And(manager, ll, t1);
01361       return(t2);
01362         case 34 :
01363         case 32 :
01364         case 2 :
01365         case 0 :
01366         case 54 :
01367         case 52 :
01368         case 22 :
01369         case 20 :
01370       t1 = bAig_And(manager, lr, rr);
01371       t2 = bAig_And(manager, ll, t1);
01372       return(t2);
01373         case 42 :
01374         case 40 :
01375         case 10 :
01376         case 8 :
01377         case 62 :
01378         case 60 :
01379         case 30 :
01380         case 28 :
01381       t1 = bAig_And(manager, lr, rr);
01382       t2 = bAig_And(manager, bAig_Not(ll), t1);
01383       return(t2);
01384         case 43 :
01385         case 41 :
01386         case 11 :
01387         case 9 :
01388         case 63 :
01389         case 61 :
01390         case 31 :
01391         case 29 :
01392       t1 = bAig_And(manager, bAig_Not(ll), bAig_Not(rr));
01393       t2 = bAig_Or(manager, bAig_Not(lr), t1);
01394       return(t2);
01395         case 39 :
01396         case 37 :
01397         case 7 :
01398         case 5 :
01399         case 51 :
01400         case 49 :
01401         case 19 :
01402         case 17 :
01403       return(l);
01404         case 46 :
01405         case 44 :
01406         case 14 :
01407         case 12 :
01408         case 58 :
01409         case 56 :
01410         case 26 :
01411         case 24 :
01412       return(r);
01413         case 38 :
01414         case 36 :
01415         case 6 :
01416         case 4 :
01417         case 50 :
01418         case 48 :
01419         case 18 :
01420         case 16 :
01421       return(bAig_Zero);
01422         case 45 :
01423         case 15 :
01424         case 13 :
01425         case 59 :
01426         case 57 :
01427         case 47 :
01428         case 27 :
01429         case 25 :
01430       t1 = bAig_And2(manager, l, r);
01431       return(t1);
01432     }
01433   }
01434   else if(caseIndex == 3) {
01435     switch(caseSig) {
01436         case 37 :
01437         case 33 :
01438         case 5 :
01439         case 1 :
01440         case 55 :
01441         case 51 :
01442         case 23 :
01443         case 19 :
01444       t1 = bAig_And(manager, bAig_Not(rl), lr);
01445       t2 = bAig_And(manager, ll, t1);
01446       return(t2);
01447         case 36 :
01448         case 32 :
01449         case 4 :
01450         case 0 :
01451         case 54 :
01452         case 50 :
01453         case 22 :
01454         case 18 :
01455       t1 = bAig_And(manager, rl, lr);
01456       t2 = bAig_And(manager, ll, t1);
01457       return(t2);
01458         case 44 :
01459         case 40 :
01460         case 12 :
01461         case 8 :
01462         case 62 :
01463         case 58 :
01464         case 30 :
01465         case 26 :
01466       t1 = bAig_And(manager, rl, lr);
01467       t2 = bAig_And(manager, bAig_Not(ll), t1);
01468       return(t2);
01469         case 45 :
01470         case 41 :
01471         case 13 :
01472         case 9 :
01473         case 63 :
01474         case 59 :
01475         case 31 :
01476         case 27 :
01477       t1 = bAig_And(manager, bAig_Not(ll), bAig_Not(rl));
01478       t2 = bAig_Or(manager, bAig_Not(lr), t1);
01479       return(t2);
01480         case 39 :
01481         case 35 :
01482         case 7 :
01483         case 3 :
01484         case 53 :
01485         case 49 :
01486         case 21 :
01487         case 17 :
01488       return(l);
01489         case 46 :
01490         case 42 :
01491         case 14 :
01492         case 10 :
01493         case 60 :
01494         case 56 :
01495         case 28 :
01496         case 24 :
01497       return(r);
01498         case 38 :
01499         case 34 :
01500         case 6 :
01501         case 2 :
01502         case 52 :
01503         case 48 :
01504         case 20 :
01505         case 16 :
01506       return(bAig_Zero);
01507         case 47 :
01508         case 43 :
01509         case 15 :
01510         case 11 :
01511         case 61 :
01512         case 57 :
01513         case 29 :
01514         case 25 :
01515       t1 = bAig_And2(manager, l, r);
01516       return(t1);
01517     }
01518   }
01519   else if(caseIndex == 4) {
01520     switch(caseSig) {
01521         case 22 :
01522         case 20 :
01523         case 6 :
01524         case 4 :
01525         case 50 :
01526         case 48 :
01527         case 34 :
01528         case 32 :
01529         case 2 :
01530         case 16 :
01531         case 52 :
01532         case 1 :
01533         case 8 :
01534         case 19 :
01535         case 26 :
01536         case 37 :
01537         case 44 :
01538         case 38 :
01539         case 55 :
01540         case 62 :
01541       return(bAig_Zero);
01542         case 0 :
01543         case 18 :
01544         case 36 :
01545         case 54 :
01546         case 9 :
01547         case 27 :
01548         case 45 :
01549         case 63 :
01550         case 5 :
01551         case 23 :
01552         case 33 :
01553         case 51 :
01554         case 3 :
01555         case 17 :
01556         case 49 :
01557         case 7 :
01558         case 35 :
01559         case 21 :
01560         case 39 :
01561         case 53 :
01562       return(l);
01563         case 40 :
01564         case 58 :
01565         case 12 :
01566         case 30 :
01567         case 24 :
01568         case 10 :
01569         case 14 :
01570         case 56 :
01571         case 28 :
01572         case 42 :
01573         case 60 :
01574         case 46 :
01575       return(r);
01576         case 11 :
01577         case 47 :
01578         case 25 :
01579         case 61 :
01580       return(bAig_Not(ll));
01581         case 41 :
01582         case 59 :
01583         case 13 :
01584         case 31 :
01585       return(bAig_Not(lr));
01586         case 15 :
01587       t1 = bAig_And(manager, ll, bAig_Not(lr));
01588       t2 = bAig_And(manager, bAig_Not(ll), lr);
01589       return(bAig_Not(bAig_And2(manager, bAig_Not(t1), bAig_Not(t2))));
01590         case 57 :
01591       t1 = bAig_And(manager, rl, bAig_Not(rr));
01592       t2 = bAig_And(manager, bAig_Not(rl), rr);
01593       return(bAig_Not(bAig_And2(manager, bAig_Not(t1), bAig_Not(t2))));
01594         case 29 :
01595       t1 = bAig_And(manager, ll, lr);
01596       t2 = bAig_And(manager, bAig_Not(ll), bAig_Not(lr));
01597       return((bAig_And2(manager, bAig_Not(t1), bAig_Not(t2))));
01598         case 43 :
01599       t1 = bAig_And(manager, rl, rr);
01600       t2 = bAig_And(manager, bAig_Not(rl), bAig_Not(rr));
01601       return((bAig_And2(manager, bAig_Not(t1), bAig_Not(t2))));
01602     }
01603   }
01604   return(0);
01605 }
01606 
01607 
01619 bAigEdge_t
01620 bAig_And3(
01621            bAig_Manager_t *manager,
01622            bAigEdge_t l,
01623            bAigEdge_t r)
01624 {
01625   int caseIndex, caseSig;
01626   bAigEdge_t rl, rr;
01627 
01628   rl = leftChild(r);
01629   rr = rightChild(r);
01630 
01631   caseIndex = 0; /* (a)(b c) */
01632   if(bAigCompareNode(l, rl)) {
01633     caseIndex = 1; /* (a)(a b) */
01634   }
01635   else if(bAigCompareNode(l, rr)) {
01636     caseIndex = 2; /* (a)(b a) */
01637   }
01638 
01639   caseSig = 0;
01640   if(bAig_IsInverted(l))  caseSig += 8;
01641   if(bAig_IsInverted(rl)) caseSig += 4;
01642   if(bAig_IsInverted(rr)) caseSig += 2;
01643   if(bAig_IsInverted(r))  caseSig += 1;
01644   if(caseIndex == 0) {
01645     return(bAig_And2(manager, l, r));
01646   }
01647   else if(caseIndex == 1) {
01648     switch(caseSig) {
01649         case 2 :
01650         case 0 :
01651         case 14 :
01652         case 12 :
01653       return(r);
01654         case 10 :
01655         case 8 :
01656         case 6 :
01657         case 4 :
01658       return(bAig_Zero);
01659         case 3 :
01660         case 1 :
01661         case 15 :
01662         case 13 :
01663       return(bAig_And(manager, rl, bAig_Not(rr)));
01664         case 11 :
01665         case 9 :
01666         case 7 :
01667         case 5 :
01668       return(l);
01669     }
01670   }
01671   else if(caseIndex == 2) {
01672     switch(caseSig) {
01673         case 4 :
01674         case 0 :
01675         case 14 :
01676         case 10 :
01677       return(r);
01678         case 12 :
01679         case 8 :
01680         case 6 :
01681         case 2 :
01682       return(bAig_Zero);
01683         case 5 :
01684         case 1 :
01685         case 15 :
01686         case 11 :
01687       return(bAig_And(manager, bAig_Not(rl), rr));
01688         case 13 :
01689         case 9 :
01690         case 7 :
01691         case 3 :
01692       return(l);
01693     }
01694   }
01695   return(0);
01696 }
01697 
01709 void
01710 bAig_SetMaskTransitiveFanin(
01711         bAig_Manager_t *manager,
01712         int v,
01713         unsigned int mask)
01714 {
01715   if(v == 2)    return;
01716 
01717 
01718   if(flags(v) & mask)   return;
01719 
01720   flags(v) |= mask;
01721 
01722   bAig_SetMaskTransitiveFanin(manager, leftChild(v), mask);
01723   bAig_SetMaskTransitiveFanin(manager, rightChild(v), mask);
01724 }
01725 
01737 void
01738 bAig_ResetMaskTransitiveFanin(
01739         bAig_Manager_t *manager,
01740         int v,
01741         unsigned int mask,
01742         unsigned int resetMask)
01743 {
01744   if(v == 2)    return;
01745 
01746 
01747   if(!(flags(v) & mask))        return;
01748 
01749   flags(v) &= resetMask;
01750   bAig_ResetMaskTransitiveFanin(manager, leftChild(v), mask, resetMask);
01751   bAig_ResetMaskTransitiveFanin(manager, rightChild(v), mask, resetMask);
01752 }
01753 
01754 
01767 int
01768 bAig_GetValueOfNode(bAig_Manager_t *manager, bAigEdge_t v)
01769 {
01770   unsigned int value, lvalue, rvalue;
01771   bAigEdge_t left, right;
01772 
01773 
01774   /*
01775   if(!(flags(v) & CoiMask))     return(2);
01776   **/
01777   if(v == 2)    return(2);
01778 
01779   value = aig_value(v);
01780   if(value == 3)        return(2);
01781   if(value == 2) {
01782     left = bAig_GetCanonical(manager, leftChild(v));
01783     lvalue = bAig_GetValueOfNode(manager, left);
01784     if(lvalue == 0)     {
01785       value = 0;
01786     }
01787     else {
01788       right = bAig_GetCanonical(manager, rightChild(v));
01789       rvalue = bAig_GetValueOfNode(manager, right);
01790       if(rvalue == 0) {
01791         value = 0;
01792       }
01793       else if(rvalue == 1 && lvalue == 1) {
01794         value = 1;
01795       }
01796       else {
01797         value = 2;
01798       }
01799     }
01800   }
01801 
01802   if(value == 2) {
01803     aig_value(v) = 3;
01804     return(value);
01805   }
01806   else  {       
01807     aig_value(v) = value;
01808     return(value ^ bAig_IsInverted(v));
01809   }
01810 }
01811