Main Page | Class List | File List | Class Members | File Members

bdd.c

Go to the documentation of this file.
00001 
00015 extern "C" {
00016 
00017 #include "tarski.h"
00018 
00021 /*---------------------------------------------------------------------------*/
00022 /* Static function prototypes                                                */
00023 /*---------------------------------------------------------------------------*/
00024 
00025 
00028 bdd_manager *bddMgr=0;
00029 st_table *nodeToBdd= ( st_table * ) 0;  // mapping from forumla nodes to bdds
00030 st_table *indexToName= ( st_table * ) 0;  // mapping from forumla nodes to bdds
00031 
00032 /*---------------------------------------------------------------------------*/
00033 /* Definition of exported functions                                          */
00034 /*---------------------------------------------------------------------------*/
00035 
00061 bdd_t *
00062 nodeComputeBdd(
00063   F aNode )
00064 {
00065   if (aNode.raw == NIL( Fnode ) ) {
00066     return NIL( bdd_t );
00067   }
00068   assert( node_test_is_boolean( aNode.raw ) );
00069 
00070   bdd_t *leftBdd;
00071   bdd_t *rightBdd;
00072   bdd_t *result;
00073   int aId;
00074 
00075   if ( nodeToBdd == NIL( st_table ) ) {
00076     nodeToBdd = st_init_table( (int (*)()) node_cmp, (int (*)()) node_hash );
00077   }
00078   if ( indexToName == NIL( st_table ) ) {
00079     indexToName = st_init_table( (int (*)()) st_numcmp, (int (*)()) st_numhash );
00080   }
00081   if ( bddMgr == NIL( bdd_manager ) ) {
00082     bddMgr = bdd_start( 0 );
00083     bdd_dynamic_reordering( bddMgr, BDD_REORDER_SIFT); // turn on variable reordering
00084     bdd_set_gc_mode(bddMgr, 0); // turn on garbage collection
00085   }
00086   if ( st_lookup( nodeToBdd, (char *) aNode.raw, (char **) & result ) ) {
00087     return bdd_dup( result );
00088   }
00089   if ( ( aNode.type() == BooleanPI_c ) ||
00090        ( aNode.type() == BooleanReg_c ) ) {
00091     aId = bdd_num_vars( bddMgr );
00092     result = bdd_get_variable( bddMgr, aId );
00093     st_insert( indexToName, (char *) aId, (char *) aNode.lchild() );
00094   }
00095   else {
00096     F leftNode;
00097     leftNode.raw = aNode.lchild();
00098     F rightNode;
00099     rightNode.raw = aNode.rchild();
00100     leftBdd = nodeComputeBdd( leftNode );
00101     rightBdd = nodeComputeBdd( rightNode );
00102     switch ( aNode.type() ) {
00103       case And_c: result = bdd_and( leftBdd, rightBdd, 1, 1 ); break;
00104       case Or_c: result = bdd_or( leftBdd, rightBdd, 1, 1 ); break;
00105       case Iff_c: result = bdd_xnor( leftBdd, rightBdd ); break;
00106       case Not_c: result = bdd_not( leftBdd ); break;
00107       case TRUE_c: result = bdd_one( bddMgr ); break;
00108       case FALSE_c: result = bdd_zero( bddMgr ); break;
00109       default: printf("Bad type of node in nodeComputeBdd\n"); assert(0);
00110     }
00111     if ( leftBdd != NIL(bdd_t) ) bdd_free( leftBdd );
00112     if ( rightBdd != NIL(bdd_t) ) bdd_free( rightBdd );
00113   }
00114   printf("nodeComputeBdd is returning a bdd of size %d\n", bdd_size( result ) );
00115   st_insert( nodeToBdd, (char *) aNode.raw, (char *) result );
00116   return bdd_dup( result );
00117 }
00118 
00119 
00128 int
00129 test_bdd()
00130 {
00131 
00132   F fs = build_fs();
00133   return 1;
00134 
00135   st_table *fsSupport = nodeGetSupport( fs );
00136   st_generator *stGen;
00137   Fnode *aRawNode;
00138 
00139   cube aCube;
00140   aCube.nodeToValue = fsSupport;
00141   int i;
00142   for ( i = 0 ; i < 100; i++ ) {
00143     st_foreach_item( fsSupport, stGen, ( char ** ) & aRawNode, ( char ** ) 0 ) {
00144       int val = rand() % 2;
00145       st_insert( fsSupport, (char *) aRawNode, (char *) ( val ) );
00146       // printf("%s is getting %d\n", (char *) aRawNode->lchild, val );
00147     }
00148     printf("Eval fs on aCube yields %d\n", fs( aCube ) );
00149   }
00150 
00151   return 0;
00152 
00153 }
00154 
00155 
00168 int 
00169 bdd_print_dot(
00170   bdd_t *aBdd 
00171 )
00172 {
00173   printf("digraph  G {\nsize=\"7.5,10\";\n");
00174 
00175   st_table *processedTable = st_init_table( (int (*)()) bdd_cmp, (int (*)()) bdd_hash );
00176 
00177   bdd_print_recur( aBdd, processedTable );
00178   printf("\n}\n");
00179 
00180   return 1;
00181 }
00182 
00183 
00184 
00198 int 
00199 bdd_print_recur(
00200  bdd_t *aBdd,
00201   st_table *processedTable
00202 )
00203 {
00204   if ( st_lookup( processedTable, (char *) aBdd, 0 ) ) {
00205     return 1;
00206   }
00207   int is_complemented;
00208   bdd_node *aNode = bdd_get_node( ( bdd_t * ) aBdd, & is_complemented);
00209   if ( is_complemented ) {
00210     aNode = (bdd_node *) ( (unsigned int) aNode ^ (unsigned int) 0x1 );
00211   }
00212   if ( bdd_is_tautology( aBdd, 0 ) ) { 
00213     printf("%u  [shape=polygon,sides=4,label=FALSE]\n", (unsigned int) aNode );
00214     st_insert( processedTable, (char *) aBdd, (char *) 0 );
00215     return 1;
00216   }
00217   if ( bdd_is_tautology( aBdd, 1 ) ) { 
00218     printf("%u  [shape=polygon,sides=4,label=TRUE]\n", (unsigned int) aNode );
00219     st_insert( processedTable, (char *) aBdd, (char *) 0 );
00220     return 1;
00221   }
00222  
00223   char *label;
00224   int index = bdd_top_var_id( aBdd );
00225   st_lookup( indexToName, (char *) index, (char **) & label );
00226   printf("%u [shape=ellipse,sides=4,label=\"%s\"]\n", (unsigned int) aNode, label );
00227   
00228   bdd_t *lBdd = bdd_else( aBdd );
00229   bdd_t *rBdd = bdd_then( aBdd );
00230 
00231   bdd_node *lNode = bdd_get_node( ( bdd_t * ) lBdd, & is_complemented);
00232   if ( is_complemented ) {
00233     lNode = (bdd_node *) ( (unsigned int) lNode ^ (unsigned int) 0x1 );
00234   }
00235   bdd_node *rNode = bdd_get_node( ( bdd_t * ) rBdd, & is_complemented);
00236   if ( is_complemented ) {
00237     rNode = (bdd_node *) ( (unsigned int) rNode ^ (unsigned int) 0x1 );
00238   }
00239   printf("%u -> %u [style=dotted];\n", (unsigned int) aNode, (unsigned int) lNode );
00240   printf("%u -> %u [style=solid];\n", (unsigned int) aNode, (unsigned int) rNode );
00241 
00242   bdd_print_recur( lBdd, processedTable );
00243   bdd_print_recur( rBdd, processedTable );
00244 
00245   st_insert( processedTable, (char *) aBdd, (char *) 0 );
00246 
00247   return 1;
00248 }
00249 
00250   
00251 
00252 
00266 int
00267 bdd_cmp(
00268   char *aBdd,
00269   char *bBdd
00270 )
00271 {
00272   int is_complemented;
00273   bdd_node *aNode = bdd_get_node( ( bdd_t * ) aBdd, & is_complemented);
00274   if ( is_complemented ) {
00275     aNode = (bdd_node *) ( (unsigned int) aNode ^ (unsigned int) 0x1 );
00276   }
00277   bdd_node *bNode = bdd_get_node( ( bdd_t * ) bBdd, & is_complemented);
00278   if ( is_complemented ) {
00279     bNode = (bdd_node *) ( (unsigned int) bNode ^ (unsigned int) 0x1 );
00280   }
00281   int result = st_numcmp( (char*) aNode, (char*) bNode );
00282   return result;
00283                                                                                                  
00284 }
00285 
00286 
00287 
00288 
00301 int
00302 bdd_hash(
00303   char *aBdd,
00304   int modulus
00305 )
00306 {
00307   int is_complemented;
00308   bdd_node *aNode = bdd_get_node( ( bdd_t *) aBdd, & is_complemented);
00309   if ( is_complemented ) {
00310     aNode = (bdd_node *) ( (unsigned int) aNode ^ (unsigned int) 0x1) ;
00311   }
00312   int result = st_numhash(  ( char *) aNode, modulus );
00313   return result;
00314 }
00315 
00316 
00317 
00326 cube::cube(){
00327   nodeToValue = st_init_table( (int (*)()) node_cmp, (int (*)()) node_hash );
00328 }
00329 
00330 
00339 cube::~cube(){
00340   // st_free_table( nodeToValue ); // problem - this frees the cube right away
00341                                    // even when we pass in something to a function
00342 }
00343 
00344 
00357 int 
00358 cube::operator[]( F aNode ) {
00359   int result=-1;
00360   st_lookup( nodeToValue, ( char * ) aNode.raw, ( char **) & result );
00361   if ( result == -1 ) {
00362     printf("Failed to find node in cube support\n");
00363     assert(0);
00364   }
00365   assert( ( result == 1 ) || (result == 0 ) );
00366   return result;
00367 }
00368 
00369 
00381 void
00382 cube::insert( F aNode, int value )
00383 {
00384   assert( ( value == 1 ) || ( value == 0 ) );
00385   st_insert( nodeToValue, (char *) aNode.raw, (char *) value );
00386   return;
00387 }
00388 
00389 
00400 int 
00401 F::operator()(
00402   cube aCube
00403 )
00404 {
00405   int leftValue, rightValue;
00406   F lchildWrapped;
00407   F rchildWrapped;
00408   lchildWrapped.raw = this->lchild();
00409   rchildWrapped.raw = this->rchild();
00410   assert( node_test_is_boolean( this->raw ) );
00411 
00412   if ( ( this->type() == BooleanPI_c ) ||
00413        ( this->type() == BooleanReg_c ) ) {
00414     return aCube[ *this ];
00415   }
00416   else if (  this->type() == TRUE_c ) {
00417     return 1;
00418   }
00419   else if (  this->type() == FALSE_c ) {
00420     return 0;
00421   }
00422   else {
00423     leftValue = lchildWrapped( aCube );
00424     if ( this->type() != Not_c ) {
00425       rightValue = rchildWrapped( aCube );
00426     }
00427     switch( this->type() ) {
00428       case Not_c: return !leftValue; break;
00429       case And_c: return leftValue && rightValue; break;
00430       case Or_c: return leftValue || rightValue; break;
00431       case Iff_c: return (leftValue==rightValue); break;
00432       default: printf("Panic, unknown type in eval op, bailing\n"); assert(0);
00433     }
00434   }
00435   assert(0);
00436   return -1; // never get here
00437 }
00438     
00439 } // extern "C"

Generated on Thu Oct 11 11:47:27 2007 for Tarski by  doxygen 1.3.9.1