00001
00015 extern "C" {
00016
00017 #include "tarski.h"
00018
00021
00022
00023
00024
00025
00028 bdd_manager *bddMgr=0;
00029 st_table *nodeToBdd= ( st_table * ) 0;
00030 st_table *indexToName= ( st_table * ) 0;
00031
00032
00033
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);
00084 bdd_set_gc_mode(bddMgr, 0);
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
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
00341
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;
00437 }
00438
00439 }