00001 #include <stdio.h>
00002 #include <math.h>
00003 #include "util.h"
00004 #include "mdd.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 static bdd_t* mddRetOnvalBdd(mdd_manager *mddMgr, int mddId);
00022 static bdd_t* mddIntRetOnvalBdd(mdd_manager *mddMgr, int valNum, int low, int hi, int level, array_t *bddVarArr);
00023 static void mddFreeBddArr(array_t *bddArr);
00024
00025
00026 #define mddGetVarById( mgr, id ) \
00027 array_fetch(mvar_type, mdd_ret_mvar_list((mgr)),(id))
00028
00029
00030 int
00031 toggle(int x)
00032 {
00033 if (x == 0) return 1;
00034 else {
00035 if (x == 1) return 0;
00036 else {
00037 fail("toggle: invalid boolean value\n");
00038 return -1;
00039 }
00040 }
00041 }
00042
00043 int
00044 no_bit_encode(int n)
00045 {
00046 int i = 0;
00047 int j = 1;
00048
00049 if (n < 2) return 1;
00050
00051 while (j < n) {
00052 j = j * 2;
00053 i++;
00054 }
00055 return i;
00056 }
00057
00058 void
00059 print_mvar_list(mdd_manager *mgr)
00060 {
00061 mvar_type mv;
00062 int i;
00063 int no_mvar;
00064 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00065
00066 no_mvar = array_n(mvar_list);
00067 printf("print_mvar_list:\n");
00068 printf("id\tname\tvalues\tbits\tstride\tstart_vertex\n");
00069 for (i=0; i<no_mvar; i++) {
00070 mv = array_fetch(mvar_type, mvar_list, i);
00071 (void) printf("%d\t%s\t%d\t%d\n",
00072 mv.mvar_id, mv.name, mv.values,
00073 mv.encode_length);
00074 }
00075 }
00076
00077 void
00078 print_strides(array_t *mvar_strides)
00079 {
00080 int i, s;
00081
00082 (void) printf("mvar_strides: ");
00083 for (i=0; i<array_n(mvar_strides); i++) {
00084 s = array_fetch(int, mvar_strides, i);
00085 (void) printf("%d ", s);
00086 }
00087 (void) printf("\n");
00088 }
00089
00090 void
00091 print_bdd_list_id(array_t *bdd_list)
00092 {
00093 bdd_t *b;
00094 int i, is_complemented;
00095
00096 (void) printf("bdd_list id's: ");
00097 for (i=0; i<array_n(bdd_list); i++) {
00098 b = array_fetch(bdd_t *, bdd_list, i);
00099 (void)bdd_get_node(b, &is_complemented);
00100 if (is_complemented) (void) printf("!");
00101 (void) printf("%d ", bdd_top_var_id(b));
00102 }
00103 (void) printf("\n");
00104 }
00105
00106 void
00107 print_bvar_list_id(mdd_manager *mgr)
00108 {
00109 bvar_type bv;
00110 int i, is_complemented;
00111 array_t *bvar_list = mdd_ret_bvar_list(mgr);
00112
00113 (void) printf("bvar_list id's: ");
00114 for (i=0; i<array_n(bvar_list); i++) {
00115 bv = array_fetch(bvar_type, bvar_list, i);
00116 (void)bdd_get_node(bv.node,&is_complemented);
00117 if (is_complemented) (void) printf("!");
00118 (void) printf("%d ", bdd_top_var_id(bv.node));
00119 }
00120 (void) printf("\n");
00121 }
00122
00123 void
00124 print_bdd(bdd_manager *mgr, bdd_t *top)
00125 {
00126
00127 int is_complemented;
00128 bdd_t *child, *top_uncomp;
00129
00130 if (bdd_is_tautology(top,1)) {
00131 (void) printf("ONE ");
00132 return;
00133 }
00134 if (bdd_is_tautology(top,0)) {
00135 (void) printf("ZERO ");
00136 return;
00137 }
00138 (void)bdd_get_node(top, &is_complemented);
00139 if (is_complemented != 0) (void) printf("!");
00140 (void) printf("%d ", bdd_top_var_id(top));
00141 (void) printf("v ");
00142 (void) printf("< ");
00143
00144 if (is_complemented) top_uncomp = bdd_not(top);
00145 else top_uncomp = mdd_dup(top);
00146
00147 child = bdd_then(top);
00148
00149 print_bdd(mgr, child);
00150 (void) printf("> ");
00151
00152 mdd_free(child);
00153 child = bdd_else(top);
00154
00155 print_bdd(mgr, child);
00156 (void) printf("^ ");
00157
00158 mdd_free(top_uncomp);
00159 mdd_free(child);
00160
00161 return;
00162 }
00163
00164 mvar_type
00165 find_mvar_id(mdd_manager *mgr, unsigned short id)
00166 {
00167 mvar_type mv;
00168 bvar_type bv;
00169 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00170 array_t *bvar_list = mdd_ret_bvar_list(mgr);
00171
00172 if (id >= array_n(bvar_list))
00173 fail("find_mvar_id: invalid parameter range for id\n");
00174 bv = array_fetch(bvar_type, bvar_list, id);
00175 if ((bv.mvar_id < 0) || (bv.mvar_id >= array_n(mvar_list)))
00176 fail("find_mvar_id: bvar contains invalid mvar_id\n");
00177 mv = array_fetch(mvar_type, mvar_list, bv.mvar_id);
00178 return mv;
00179 }
00180
00181 void
00182 clear_all_marks(mdd_manager *mgr)
00183 {
00184 int i, j;
00185 mvar_type mv;
00186 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00187
00188
00189 for (i=0; i<array_n(mvar_list); i++) {
00190 mv = array_fetch(mvar_type, mvar_list, i);
00191 for (j=0; j<mv.encode_length; j++)
00192 mv.encoding[j] = 2;
00193 }
00194 }
00195
00196 void
00197 mdd_mark(
00198 mdd_manager *mgr,
00199 bdd_t *top ,
00200 int phase)
00201 {
00202 int i, top_id, found = 0;
00203 int bit_position = 0;
00204 mvar_type mv;
00205
00206 top_id = bdd_top_var_id(top);
00207 mv = find_mvar_id(mgr, top_id);
00208
00209 for (i=0; i<(mv.encode_length); i++){
00210 if ( mdd_ret_bvar_id( &mv, i) == top_id ){
00211 bit_position = i;
00212 found = 1;
00213 break;
00214 };
00215 };
00216
00217
00218 if (found == 0)
00219 fail("mdd_mark: interleaving error\n");
00220
00221 mv.encoding[bit_position] = phase;
00222
00223 }
00224
00225 void
00226 mdd_unmark(mdd_manager *mgr, bdd_t *top)
00227 {
00228 int i, top_id, found = 0;
00229 int bit_position = 0;
00230 mvar_type mv;
00231
00232
00233 top_id = bdd_top_var_id(top);
00234 mv = find_mvar_id(mgr, top_id);
00235
00236 for (i=0; i<mv.encode_length; i++)
00237 if ( mdd_ret_bvar_id( &mv, i) == top_id ){
00238 bit_position = i;
00239 found = 1;
00240 break;
00241 };
00242
00243 if (found == 0)
00244 fail("mdd_unmark: interleaving error\n");
00245 mv.encoding[bit_position] = 2;
00246 }
00247
00248 mvar_type
00249 find_mvar(mdd_manager *mgr, char *name)
00250 {
00251 int i;
00252 mvar_type mv;
00253 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00254
00255 for (i=0; i<array_n(mvar_list); i++) {
00256 mv = array_fetch(mvar_type, mvar_list, i);
00257 if (strcmp(mv.name, name) == 0) return mv;
00258 }
00259 fail("find_mvar: cannot find name in mvar_list\n");
00260 return mv;
00261 }
00262
00263 array_t *
00264 mdd_ret_mvar_list(mdd_manager *mgr)
00265 {
00266 bdd_external_hooks *hook;
00267 array_t *mvar_list;
00268
00269 hook = bdd_get_external_hooks(mgr);
00270 mvar_list = ((mdd_hook_type *)(hook->mdd))->mvar_list;
00271
00272 return mvar_list;
00273 }
00274
00275 void
00276 mdd_set_mvar_list(mdd_manager *mgr, array_t *mvar_list)
00277 {
00278 bdd_external_hooks *hook;
00279
00280 hook = bdd_get_external_hooks(mgr);
00281 ((mdd_hook_type *)(hook->mdd))->mvar_list = mvar_list;
00282 }
00283
00284
00285 array_t *
00286 mdd_ret_bvar_list(mdd_manager *mgr)
00287 {
00288 bdd_external_hooks *hook;
00289 array_t *bvar_list;
00290
00291 hook = bdd_get_external_hooks(mgr);
00292 bvar_list = ((mdd_hook_type *)(hook->mdd))->bvar_list;
00293
00294 return bvar_list;
00295 }
00296
00297
00298 void
00299 mdd_set_bvar_list(mdd_manager *mgr, array_t *bvar_list)
00300 {
00301 bdd_external_hooks *hook;
00302
00303 hook = bdd_get_external_hooks(mgr);
00304 ((mdd_hook_type *)(hook->mdd))->bvar_list = bvar_list;
00305 }
00306
00307
00308 int
00309 mdd_ret_bvar_id(mvar_type *mvar_ptr, int i)
00310 {
00311
00312 return ( array_fetch(int, mvar_ptr->bvars, i) );
00313 }
00314
00315 bvar_type
00316 mdd_ret_bvar(mvar_type *mvar_ptr, int i, array_t *bvar_list)
00317 {
00318 int bvar_id;
00319
00320 bvar_id = array_fetch(int, mvar_ptr->bvars, i);
00321
00322 return array_fetch(bvar_type, bvar_list, bvar_id);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331 double
00332 mdd_count_onset(
00333 mdd_manager *mddMgr,
00334 mdd_t *aMdd,
00335 array_t *mddIdArr)
00336 {
00337 bdd_t *onvalBdd, *aOnvalBdd, *onsetBdd, *tmpBdd;
00338 double onsetNum;
00339 array_t *bddVarArr;
00340 int i, arrSize, mddId;
00341
00342 arrSize = array_n( mddIdArr );
00343 onvalBdd = bdd_one( mddMgr );
00344
00345 for ( i = 0 ; i < arrSize ; i++ ) {
00346 mddId = array_fetch( int, mddIdArr, i );
00347 aOnvalBdd = mddRetOnvalBdd( mddMgr, mddId );
00348
00349 tmpBdd = bdd_and( onvalBdd, aOnvalBdd, 1, 1 );
00350 bdd_free( onvalBdd );
00351 bdd_free( aOnvalBdd );
00352 onvalBdd = tmpBdd;
00353 }
00354 onsetBdd = bdd_and( onvalBdd, aMdd, 1, 1 );
00355 bdd_free( onvalBdd );
00356
00357 bddVarArr = mdd_id_array_to_bdd_array( mddMgr, mddIdArr );
00358 onsetNum = bdd_count_onset( onsetBdd, bddVarArr );
00359 bdd_free( onsetBdd );
00360 mddFreeBddArr( bddVarArr );
00361 return( onsetNum );
00362 }
00363
00364 mdd_t *
00365 mdd_onset_bdd(
00366 mdd_manager *mddMgr,
00367 mdd_t *aMdd,
00368 array_t *mddIdArr)
00369 {
00370 bdd_t *onvalBdd, *aOnvalBdd, *onsetBdd, *tmpBdd;
00371 int i, arrSize, mddId;
00372
00373 arrSize = array_n( mddIdArr );
00374 onvalBdd = bdd_one( mddMgr );
00375
00376 for ( i = 0 ; i < arrSize ; i++ ) {
00377 mddId = array_fetch( int, mddIdArr, i );
00378 aOnvalBdd = mddRetOnvalBdd( mddMgr, mddId );
00379
00380 tmpBdd = bdd_and( onvalBdd, aOnvalBdd, 1, 1 );
00381 bdd_free( onvalBdd );
00382 bdd_free( aOnvalBdd );
00383 onvalBdd = tmpBdd;
00384 }
00385 onsetBdd = bdd_and( onvalBdd, aMdd, 1, 1 );
00386 bdd_free( onvalBdd );
00387 return( onsetBdd );
00388 }
00389
00390 int
00391 mdd_epd_count_onset(
00392 mdd_manager *mddMgr,
00393 mdd_t *aMdd,
00394 array_t *mddIdArr,
00395 EpDouble *epd)
00396 {
00397 bdd_t *onvalBdd, *aOnvalBdd, *onsetBdd, *tmpBdd;
00398 array_t *bddVarArr;
00399 int i, arrSize, mddId;
00400 int status;
00401
00402 arrSize = array_n( mddIdArr );
00403 onvalBdd = bdd_one( mddMgr );
00404
00405 for ( i = 0 ; i < arrSize ; i++ ) {
00406 mddId = array_fetch( int, mddIdArr, i );
00407 aOnvalBdd = mddRetOnvalBdd( mddMgr, mddId );
00408
00409 tmpBdd = bdd_and( onvalBdd, aOnvalBdd, 1, 1 );
00410 bdd_free( onvalBdd );
00411 bdd_free( aOnvalBdd );
00412 onvalBdd = tmpBdd;
00413 }
00414 onsetBdd = bdd_and( onvalBdd, aMdd, 1, 1 );
00415 bdd_free( onvalBdd );
00416
00417 bddVarArr = mdd_id_array_to_bdd_array( mddMgr, mddIdArr );
00418 status = bdd_epd_count_onset( onsetBdd, bddVarArr, epd );
00419 if (status)
00420 return(status);
00421 bdd_free( onsetBdd );
00422 mddFreeBddArr( bddVarArr );
00423 return(0);
00424 }
00425
00426
00427 static bdd_t*
00428 mddRetOnvalBdd(
00429 mdd_manager *mddMgr,
00430 int mddId)
00431 {
00432 bdd_t *onvalBdd;
00433 mvar_type mVar;
00434 int valNum, high;
00435 array_t *bddVarArr;
00436
00437 mVar = mddGetVarById( mddMgr, mddId );
00438 valNum = mVar.values;
00439 high = (int) pow( (double) 2, (double) mVar.encode_length );
00440 assert( (valNum == 1) || ( (valNum <= high) && (valNum > high/2) ));
00441 if ( valNum == high )
00442 onvalBdd = bdd_one( mddMgr );
00443 else {
00444 bddVarArr = mdd_id_to_bdd_array( mddMgr, mddId );
00445 onvalBdd = mddIntRetOnvalBdd( mddMgr, valNum, 0, high,
00446 0, bddVarArr );
00447 mddFreeBddArr( bddVarArr );
00448 }
00449 return( onvalBdd );
00450 }
00451
00452
00453 static bdd_t*
00454 mddIntRetOnvalBdd(
00455 mdd_manager *mddMgr,
00456 int valNum,
00457 int low,
00458 int hi,
00459 int level,
00460 array_t *bddVarArr)
00461 {
00462 int mid;
00463 bdd_t *curVar, *recBdd;
00464 bdd_t *onvalBdd = NIL(bdd_t);
00465
00466 mid = (low + hi) / 2;
00467 curVar = array_fetch( bdd_t *, bddVarArr, level );
00468
00469 if ( valNum > mid ) {
00470 recBdd = mddIntRetOnvalBdd( mddMgr, valNum, mid, hi,
00471 level+1, bddVarArr );
00472 onvalBdd = bdd_or( recBdd, curVar, 1, 0 );
00473 bdd_free( recBdd );
00474 }
00475 else if ( valNum < mid ) {
00476 recBdd = mddIntRetOnvalBdd( mddMgr, valNum, low, mid,
00477 level+1, bddVarArr );
00478 onvalBdd = bdd_and( recBdd, curVar, 1, 0 );
00479 bdd_free( recBdd );
00480 }
00481 else if ( valNum == mid )
00482 onvalBdd = bdd_not( curVar );
00483 return( onvalBdd );
00484 }
00485
00486
00487
00488
00489 static void
00490 mddFreeBddArr(array_t *bddArr)
00491 {
00492 int i, arrSize;
00493
00494 arrSize = array_n( bddArr );
00495 for ( i = 0 ; i < arrSize ; i++ )
00496 bdd_free( array_fetch( bdd_t *, bddArr, i ) );
00497 array_free( bddArr );
00498 }
00499
00500 array_t *
00501 mdd_ret_bvars_of_mvar(mvar_type *mvar_ptr)
00502 {
00503 return mvar_ptr->bvars;
00504 }
00505
00506
00507
00508
00509 static mdd_t *mdd_get_care_set(mdd_manager *mdd_mgr)
00510 {
00511 mdd_t *temp;
00512 mvar_type mv;
00513 mdd_manager *bdd_mgr;
00514
00515 int mvar_id,i,j,val_j,value;
00516 array_t *mvar_list;
00517 bdd_t *care_set, *care_val, *care_cube,*bit_j;
00518
00519 mvar_list = mdd_ret_mvar_list(mdd_mgr);
00520 bdd_mgr = mdd_mgr;
00521
00522 care_set = bdd_one(bdd_mgr);
00523
00524 for (mvar_id =0; mvar_id < array_n(mvar_list); mvar_id++)
00525 {
00526 mv = array_fetch(mvar_type, mvar_list, mvar_id);
00527 care_val = bdd_zero(bdd_mgr);
00528
00529 for (i=0; i< (mv.values); i++)
00530 {
00531 value = i;
00532 care_cube = bdd_one(bdd_mgr);
00533 for(j=0; j< mv.encode_length; j++ )
00534 {
00535 bit_j = bdd_get_variable(bdd_mgr,mdd_ret_bvar_id(&mv, j));
00536 val_j = value % 2;
00537 value = value/2;
00538 temp = care_cube;
00539 care_cube = bdd_and(temp,bit_j,1,val_j);
00540 bdd_free(temp);
00541 }
00542 temp = care_val;
00543 care_val = bdd_or(temp,care_cube,1,1);
00544 bdd_free(temp);
00545 bdd_free(care_cube);
00546 }
00547 temp = care_set;
00548 care_set = bdd_and(temp,care_val,1,1);
00549 bdd_free(care_val);
00550 bdd_free(temp);
00551 }
00552 return care_set;
00553 }
00554
00555
00556
00557
00558 mdd_t *mdd_cproject(
00559 mdd_manager *mgr,
00560 mdd_t *T,
00561 array_t *mvars)
00562 {
00563 mdd_t *care_set, *new_T, *T_proj;
00564 array_t *bdd_vars;
00565 int i, j, mv_no;
00566 mvar_type mv;
00567 bdd_t *temp;
00568 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00569
00570
00571 care_set = mdd_get_care_set(mgr);
00572 new_T = bdd_and(T,care_set,1,1);
00573 bdd_free(care_set);
00574
00575 if ( mvars == NIL(array_t) ) {
00576 T_proj = bdd_dup(T);
00577 printf("\nWARNING: Empty Array of Smoothing Variables\n");
00578 return T_proj;
00579 }
00580 else if ( array_n(mvars) == 0) {
00581 T_proj = bdd_dup(T);
00582 printf("\nWARNING: Empty Array of Smoothing Variables\n");
00583 return T_proj;
00584 }
00585
00586
00587 bdd_vars = array_alloc(bdd_t*, 0);
00588 for (i=0; i<array_n(mvars); i++) {
00589 mv_no = array_fetch(int, mvars, i);
00590 mv = array_fetch(mvar_type, mvar_list, mv_no);
00591 if (mv.status == MDD_BUNDLED) {
00592 (void) fprintf(stderr,
00593 "\nmdd_smooth: bundled variable %s used\n",mv.name);
00594 fail("");
00595 }
00596
00597 for (j = 0;j < mv.encode_length; j ++) {
00598 temp = bdd_get_variable(mgr, mdd_ret_bvar_id(&mv,j) );
00599 array_insert_last(bdd_t *, bdd_vars, temp);
00600 }
00601 }
00602
00603
00604 T_proj = bdd_cproject(new_T,bdd_vars);
00605 bdd_free(new_T);
00606
00607 for (i=0; i<array_n(bdd_vars); i++) {
00608 temp = array_fetch(bdd_t *, bdd_vars, i);
00609 bdd_free(temp);
00610 }
00611 array_free(bdd_vars);
00612
00613
00614 return T_proj;
00615 }
00616
00617 void
00618 mdd_print_support(mdd_t *f)
00619 {
00620 mdd_manager *mgr = bdd_get_manager(f);
00621 array_t *support_list = mdd_get_support(mgr, f);
00622 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00623 int nSupports = array_n(support_list);
00624 int i, j;
00625 mvar_type mv;
00626 int id;
00627
00628 for (i = 0; i < nSupports; i++) {
00629 id = array_fetch(int, support_list, i);
00630 mv = array_fetch(mvar_type, mvar_list, id);
00631 if (id == mv.mvar_id)
00632 printf("[%d] = %s\n", i, mv.name);
00633 else {
00634 for (j = 0; j < array_n(mvar_list); j++) {
00635 mv = array_fetch(mvar_type, mvar_list, j);
00636 if (id == mv.mvar_id) {
00637 printf(" [%d] = %s\n", i, mv.name);
00638 break;
00639 }
00640 }
00641 }
00642 }
00643
00644 array_free(support_list);
00645 }
00646
00647 void
00648 mdd_print_support_to_file(FILE *fout, char *format, mdd_t *f)
00649 {
00650 mdd_manager *mgr = bdd_get_manager(f);
00651 array_t *support_list = mdd_get_support(mgr, f);
00652 array_t *mvar_list = mdd_ret_mvar_list(mgr);
00653 int nSupports = array_n(support_list);
00654 int i, j;
00655 mvar_type mv;
00656 int id;
00657
00658 for (i = 0; i < nSupports; i++) {
00659 id = array_fetch(int, support_list, i);
00660 mv = array_fetch(mvar_type, mvar_list, id);
00661 if (id == mv.mvar_id)
00662 fprintf(fout, format, mv.name);
00663 else {
00664 for (j = 0; j < array_n(mvar_list); j++) {
00665 mv = array_fetch(mvar_type, mvar_list, j);
00666 if (id == mv.mvar_id) {
00667 fprintf(fout, format, mv.name);
00668 break;
00669 }
00670 }
00671 }
00672 }
00673
00674 array_free(support_list);
00675 }
00676
00677 char *
00678 mdd_read_var_name(mdd_t *f)
00679 {
00680 mdd_manager *mgr;
00681 array_t *support_list;
00682 array_t *mvar_list;
00683 int i, id;
00684 mvar_type mv;
00685
00686 if (bdd_size(f) != 2) {
00687 fprintf(stderr,
00688 "** mdd error: mdd_read_var_name can be called for a variable\n");
00689 return(NIL(char));
00690 }
00691
00692 mgr = bdd_get_manager(f);
00693 support_list = mdd_get_support(mgr, f);
00694 mvar_list = mdd_ret_mvar_list(mgr);
00695
00696 id = array_fetch(int, support_list, 0);
00697 mv = array_fetch(mvar_type, mvar_list, id);
00698 if (id == mv.mvar_id) {
00699 array_free(support_list);
00700 return(mv.name);
00701 } else {
00702 for (i = 0; i < array_n(mvar_list); i++) {
00703 mv = array_fetch(mvar_type, mvar_list, i);
00704 if (id == mv.mvar_id) {
00705 array_free(support_list);
00706 return(mv.name);
00707 }
00708 }
00709 }
00710
00711 array_free(support_list);
00712 return(NIL(char));
00713 }
00714
00715 int
00716 mdd_read_mdd_id(mdd_t *f)
00717 {
00718 mdd_manager *mgr;
00719 array_t *support_list;
00720 int id;
00721
00722 if (bdd_size(f) != 2) {
00723 fprintf(stderr,
00724 "** mdd error: mdd_read_mdd_id can be called for a variable\n");
00725 return(0);
00726 }
00727
00728 mgr = bdd_get_manager(f);
00729 support_list = mdd_get_support(mgr, f);
00730 id = array_fetch(int, support_list, 0);
00731 array_free(support_list);
00732 return(id);
00733 }
00734
00745 array_t *
00746 mdd_id_to_bdd_id_array(mdd_manager *mddManager, int mddId)
00747 {
00748 array_t *bddIdArray;
00749 mvar_type mddVar;
00750 array_t *mvar_list;
00751 int i, j;
00752
00753 mvar_list = mdd_ret_mvar_list(mddManager);
00754 mddVar = array_fetch(mvar_type, mvar_list, mddId);
00755 bddIdArray = array_alloc(int, mddVar.encode_length);
00756
00757 for (i=0; i<mddVar.encode_length; i++){
00758 j = mdd_ret_bvar_id(&mddVar, i);
00759 array_insert_last(int, bddIdArray, j);
00760 }
00761 return bddIdArray;
00762 }
00763
00774 array_t *
00775 mdd_id_to_bdd_array(mdd_manager *mddManager, int mddId)
00776 {
00777 array_t *bddArray;
00778 mvar_type mddVar;
00779 int i, id;
00780
00781 mddVar = mddGetVarById(mddManager, mddId);
00782 bddArray = array_alloc(bdd_t*, mddVar.encode_length);
00783
00784 for (i = 0; i < mddVar.encode_length; i++) {
00785 id = mdd_ret_bvar_id(&mddVar, i);
00786 array_insert_last(bdd_t*, bddArray, bdd_get_variable(mddManager, id));
00787 }
00788 return bddArray;
00789 }
00790
00791
00802 array_t *
00803 mdd_id_array_to_bdd_array(mdd_manager *mddManager, array_t *mddIdArray)
00804 {
00805 array_t *bddArray;
00806 int i, j;
00807 int id, size;
00808 mvar_type mddVar;
00809
00810 bddArray = array_alloc(bdd_t*, 0);
00811 size = array_n(mddIdArray);
00812
00813 for (i = 0; i < size; i++) {
00814 id = array_fetch(int, mddIdArray, i);
00815 mddVar = mddGetVarById(mddManager, id);
00816 for (j = 0; j < mddVar.encode_length; j++) {
00817 id = mdd_ret_bvar_id(&mddVar, j);
00818 array_insert_last(bdd_t *, bddArray, bdd_get_variable(mddManager, id));
00819 }
00820 }
00821 return bddArray;
00822 }
00823
00836 array_t *
00837 mdd_id_array_to_bdd_id_array(mdd_manager *mddManager, array_t *mddIdArray)
00838 {
00839 array_t *bddIdArray;
00840 int i;
00841
00842 bddIdArray = array_alloc(int, 0);
00843 for (i=0; i<array_n(mddIdArray); i++){
00844 int mddId;
00845 array_t *tmpBddIdArray;
00846 mddId = array_fetch(int, mddIdArray, i);
00847 tmpBddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId);
00848 array_append(bddIdArray, tmpBddIdArray);
00849 array_free(tmpBddIdArray);
00850 }
00851 return bddIdArray;
00852 }
00853
00854
00864 mdd_t *
00865 mdd_id_array_to_bdd_cube(mdd_manager *mddManager, array_t *mddIdArray)
00866 {
00867 int i, j;
00868 int id, size;
00869 mvar_type mddVar;
00870 mdd_t *cube, *var, *tmp;
00871 int nVars;
00872 char *vars;
00873
00874 size = array_n(mddIdArray);
00875 nVars = bdd_num_vars(mddManager);
00876 vars = ALLOC(char, sizeof(char) * nVars);
00877 memset(vars, 0, sizeof(char) * nVars);
00878
00879 for (i = 0; i < size; i++) {
00880 id = array_fetch(int, mddIdArray, i);
00881 mddVar = mddGetVarById(mddManager, id);
00882 for (j = 0; j < mddVar.encode_length; j++) {
00883 id = mdd_ret_bvar_id(&mddVar, j);
00884 vars[bdd_get_level_from_id(mddManager, id)] = 1;
00885 }
00886 }
00887 cube = mdd_one(mddManager);
00888 for (i = nVars - 1; i >= 0; i--) {
00889 if (vars[i] == 0)
00890 continue;
00891 id = (int)bdd_get_id_from_level(mddManager, (long)i);
00892 var = bdd_get_variable(mddManager, id);
00893 tmp = mdd_and(cube, var, 1, 1);
00894 mdd_free(cube);
00895 mdd_free(var);
00896 cube = tmp;
00897 }
00898 FREE(vars);
00899 return cube;
00900 }
00901
00911 int
00912 mdd_get_number_of_bdd_vars(mdd_manager *mddManager, array_t *mddIdArray)
00913 {
00914 int i, n;
00915
00916 n = 0;
00917 for (i=0; i<array_n(mddIdArray); i++){
00918 int mddId;
00919 array_t *tmpBddIdArray;
00920 mddId = array_fetch(int, mddIdArray, i);
00921 tmpBddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId);
00922 n += array_n(tmpBddIdArray);
00923 array_free(tmpBddIdArray);
00924 }
00925 return n;
00926 }
00927
00937 int
00938 mdd_get_number_of_bdd_support(mdd_manager *mddManager, mdd_t *f)
00939 {
00940 array_t *bvar_list = mdd_ret_bvar_list(mddManager);
00941 var_set_t *vset;
00942 int i, number = 0;
00943
00944 vset = bdd_get_support(f);
00945 for (i = 0; i < array_n(bvar_list); i++) {
00946 if (var_set_get_elt(vset, i) == 1) {
00947 number++;
00948 }
00949 }
00950
00951 (void) var_set_free(vset);
00952 return number;
00953 }
00954
00996 array_t *
00997 mdd_fn_array_to_bdd_rel_array(
00998 mdd_manager *mddManager,
00999 int mddId,
01000 array_t *mddFnArray)
01001 {
01002 array_t *bddRelationArray, *mddLiteralArray, *valueArray, *bddArray;
01003 mvar_type mddVar;
01004 int i, j, numValues, numEncodingBits;
01005 bdd_t *bdd, *bddRelation, *bddNot;
01006 bdd_t *mddFn, *posCofactor, *negCofactor, *tmpBddRelation;
01007 mdd_t *mddLiteral, *literalRelation;
01008 array_t *mvar_list;
01009
01010 numValues = array_n(mddFnArray);
01011
01012 if (numValues == 2) {
01013 bdd_t *onRelation, *offRelation;
01014
01015 bddArray = mdd_id_to_bdd_array(mddManager, mddId);
01016 bdd = array_fetch(bdd_t *, bddArray, 0);
01017 array_free(bddArray);
01018 mddFn = array_fetch(mdd_t *, mddFnArray, 0);
01019 offRelation = bdd_and(bdd, mddFn, 0, 1);
01020 mddFn = array_fetch(mdd_t *, mddFnArray, 1);
01021 onRelation = bdd_and(bdd, mddFn, 1, 1);
01022 bdd_free(bdd);
01023 bddRelation = bdd_or(onRelation, offRelation, 1, 1);
01024 bdd_free(onRelation);
01025 bdd_free(offRelation);
01026 bddRelationArray = array_alloc(bdd_t *, 0);
01027 array_insert_last(bdd_t *, bddRelationArray, bddRelation);
01028 return bddRelationArray;
01029 }
01030 mvar_list = mdd_ret_mvar_list(mddManager);
01031 mddVar = array_fetch(mvar_type, mvar_list, mddId);
01032 assert(mddVar.values == numValues);
01033
01034
01035
01036
01037
01038
01039
01040 valueArray = array_alloc(int, 1);
01041 mddLiteralArray = array_alloc(mdd_t*, 0);
01042 for (i=0; i<numValues; i++){
01043 array_insert(int, valueArray, 0, i);
01044
01045 mddLiteral = mdd_literal(mddManager, mddId, valueArray);
01046
01047 if (bdd_is_cube(mddLiteral) == FALSE){
01048 fprintf(stderr,
01049 "The encoding of the variable %s for the value %d isnot a cube.\n",
01050 mddVar.name, i);
01051 fprintf(stderr, "It can result in wrong answers.\n");
01052 }
01053 array_insert_last(mdd_t*, mddLiteralArray, mddLiteral);
01054 }
01055 array_free(valueArray);
01056
01057 bddRelationArray = array_alloc(bdd_t*, 0);
01058 numEncodingBits = mddVar.encode_length;
01059 bddArray = mdd_id_to_bdd_array(mddManager, mddId);
01060 for (i=0; i<numEncodingBits; i++) {
01061 bddRelation = bdd_zero((bdd_manager *)mddManager);
01062 bdd = array_fetch(bdd_t*, bddArray, i);
01063 bddNot = bdd_not(bdd);
01064 for (j=0; j<numValues; j++){
01065 mddLiteral = array_fetch(mdd_t*, mddLiteralArray, j);
01066 mddFn = array_fetch(mdd_t*, mddFnArray, j);
01067 posCofactor = bdd_cofactor(mddLiteral, bdd);
01068 if (bdd_is_tautology(posCofactor, 0)) {
01069 literalRelation = bdd_and(bddNot, mddFn, 1, 1);
01070 bdd_free(posCofactor);
01071 } else {
01072 negCofactor = bdd_cofactor(mddLiteral, bddNot);
01073 if (bdd_is_tautology(negCofactor, 0)) {
01074 literalRelation = bdd_and(bdd, mddFn, 1, 1);
01075 } else {
01076 assert(bdd_equal(posCofactor, negCofactor));
01077 literalRelation = bdd_dup(mddFn);
01078 }
01079 bdd_free(posCofactor);
01080 bdd_free(negCofactor);
01081 }
01082 tmpBddRelation = bdd_or(bddRelation, literalRelation, 1, 1);
01083 bdd_free(literalRelation);
01084 bdd_free(bddRelation);
01085 bddRelation = tmpBddRelation;
01086 }
01087 array_insert_last(bdd_t*, bddRelationArray, bddRelation);
01088 bdd_free(bdd);
01089 bdd_free(bddNot);
01090 }
01091
01092 mdd_array_free(mddLiteralArray);
01093 array_free(bddArray);
01094 return bddRelationArray;
01095 }
01096
01138 array_t *
01139 mdd_fn_array_to_bdd_fn_array(
01140 mdd_manager *mddManager,
01141 int mddId,
01142 array_t *mddFnArray)
01143 {
01144 array_t *bddFunctionArray, *mddLiteralArray, *valueArray, *bddArray;
01145 mvar_type mddVar;
01146 int i, j, numValues, numEncodingBits;
01147 bdd_t *bdd, *bddFunction, *bddNot;
01148 bdd_t *onSet, *offSet, *dcSet, *lower, *upper;
01149 bdd_t *mddFn, *posCofactor, *negCofactor, *tmp;
01150 mdd_t *mddLiteral;
01151 array_t *mvar_list;
01152
01153 numValues = array_n(mddFnArray);
01154
01155 if (numValues == 2) {
01156 bddFunctionArray = array_alloc(bdd_t *, 0);
01157 mddFn = array_fetch(mdd_t *, mddFnArray, 1);
01158 bddFunction = mdd_dup(mddFn);
01159 array_insert_last(bdd_t *, bddFunctionArray, bddFunction);
01160 return bddFunctionArray;
01161 }
01162 mvar_list = mdd_ret_mvar_list(mddManager);
01163 mddVar = array_fetch(mvar_type, mvar_list, mddId);
01164 assert(mddVar.values == numValues);
01165
01166
01167
01168
01169
01170
01171
01172 valueArray = array_alloc(int, 1);
01173 mddLiteralArray = array_alloc(mdd_t*, 0);
01174 for (i=0; i<numValues; i++){
01175 array_insert(int, valueArray, 0, i);
01176
01177 mddLiteral = mdd_literal(mddManager, mddId, valueArray);
01178
01179 if (bdd_is_cube(mddLiteral) == FALSE) {
01180 fprintf(stderr,
01181 "The encoding of the variable %s for the value %d isnot a cube.\n",
01182 mddVar.name, i);
01183 fprintf(stderr, "It can result in wrong answers.\n");
01184 }
01185 array_insert_last(mdd_t*, mddLiteralArray, mddLiteral);
01186 }
01187 array_free(valueArray);
01188
01189 bddFunctionArray = array_alloc(bdd_t*, 0);
01190 numEncodingBits = mddVar.encode_length;
01191 bddArray = mdd_id_to_bdd_array(mddManager, mddId);
01192 for (i=0; i<numEncodingBits; i++) {
01193 onSet = bdd_zero((bdd_manager *)mddManager);
01194 offSet = bdd_zero((bdd_manager *)mddManager);
01195 dcSet = bdd_zero((bdd_manager *)mddManager);
01196 bdd = array_fetch(bdd_t*, bddArray, i);
01197 bddNot = bdd_not(bdd);
01198 for (j=0; j<numValues; j++) {
01199 mddLiteral = array_fetch(mdd_t*, mddLiteralArray, j);
01200 posCofactor = bdd_cofactor(mddLiteral, bdd);
01201 mddFn = array_fetch(mdd_t*, mddFnArray, j);
01202
01203 if (bdd_is_tautology(posCofactor, 0)) {
01204 tmp = bdd_or(offSet, mddFn, 1, 1);
01205 bdd_free(offSet);
01206 offSet = tmp;
01207 bdd_free(posCofactor);
01208 continue;
01209 }
01210
01211 negCofactor = bdd_cofactor(mddLiteral, bddNot);
01212 if (bdd_is_tautology(negCofactor, 0)) {
01213 tmp = bdd_or(onSet, mddFn, 1, 1);
01214 bdd_free(onSet);
01215 onSet = tmp;
01216 bdd_free(posCofactor);
01217 bdd_free(negCofactor);
01218 continue;
01219 }
01220
01221 assert(bdd_equal(posCofactor, negCofactor));
01222 bdd_free(posCofactor);
01223 bdd_free(negCofactor);
01224
01225 tmp = bdd_or(dcSet, mddFn, 1, 1);
01226 bdd_free(dcSet);
01227 dcSet = tmp;
01228 }
01229 bdd_free(bdd);
01230 bdd_free(bddNot);
01231 lower = bdd_and(onSet, offSet, 1, 0);
01232 bdd_free(offSet);
01233 upper = bdd_or(onSet, dcSet, 1, 1);
01234 bdd_free(onSet);
01235 bdd_free(dcSet);
01236 bddFunction = bdd_between(lower, upper);
01237 bdd_free(lower);
01238 bdd_free(upper);
01239 array_insert_last(bdd_t*, bddFunctionArray, bddFunction);
01240 }
01241
01242 mdd_array_free(mddLiteralArray);
01243 array_free(bddArray);
01244 return bddFunctionArray;
01245 }
01246
01247
01248 array_t *
01249 mdd_pick_arbitrary_minterms(
01250 mdd_manager *mddMgr,
01251 mdd_t *aMdd,
01252 array_t *mddIdArr,
01253 int n)
01254 {
01255 bdd_t *onvalBdd, *aOnvalBdd, *onsetBdd, *tmpBdd;
01256 array_t *bddVarArr;
01257 int i, arrSize, mddId;
01258 array_t *mintermArray;
01259
01260 arrSize = array_n( mddIdArr );
01261 onvalBdd = bdd_one( mddMgr );
01262
01263 for ( i = 0 ; i < arrSize ; i++ ) {
01264 mddId = array_fetch( int, mddIdArr, i );
01265 aOnvalBdd = mddRetOnvalBdd( mddMgr, mddId );
01266
01267 tmpBdd = bdd_and( onvalBdd, aOnvalBdd, 1, 1 );
01268 bdd_free( onvalBdd );
01269 bdd_free( aOnvalBdd );
01270 onvalBdd = tmpBdd;
01271 }
01272 onsetBdd = bdd_and( onvalBdd, aMdd, 1, 1 );
01273 bdd_free( onvalBdd );
01274
01275 bddVarArr = mdd_id_array_to_bdd_array(mddMgr, mddIdArr);
01276 mintermArray = bdd_bdd_pick_arbitrary_minterms(onsetBdd, bddVarArr,
01277 array_n(bddVarArr), n);
01278 bdd_free(onsetBdd);
01279 mddFreeBddArr(bddVarArr);
01280 return(mintermArray);
01281 }
01282
01283
01284 mdd_t *
01285 mdd_subset_with_mask_vars(
01286 mdd_manager *mddMgr,
01287 mdd_t *aMdd,
01288 array_t *mddIdArr,
01289 array_t *maskIdArr)
01290 {
01291 bdd_t *onvalBdd, *aOnvalBdd, *onsetBdd, *tmpBdd;
01292 array_t *bddVarArr, *maskVarArr;
01293 int i, arrSize, mddId;
01294 mdd_t *subset;
01295
01296 arrSize = array_n( mddIdArr );
01297 onvalBdd = bdd_one( mddMgr );
01298
01299 for ( i = 0 ; i < arrSize ; i++ ) {
01300 mddId = array_fetch( int, mddIdArr, i );
01301 aOnvalBdd = mddRetOnvalBdd( mddMgr, mddId );
01302
01303 tmpBdd = bdd_and( onvalBdd, aOnvalBdd, 1, 1 );
01304 bdd_free( onvalBdd );
01305 bdd_free( aOnvalBdd );
01306 onvalBdd = tmpBdd;
01307 }
01308 onsetBdd = bdd_and( onvalBdd, aMdd, 1, 1 );
01309 bdd_free( onvalBdd );
01310
01311 bddVarArr = mdd_id_array_to_bdd_array(mddMgr, mddIdArr);
01312 maskVarArr = mdd_id_array_to_bdd_array(mddMgr, maskIdArr);
01313
01314 subset = bdd_subset_with_mask_vars(onsetBdd, bddVarArr, maskVarArr);
01315 bdd_free(onsetBdd);
01316 mddFreeBddArr(bddVarArr);
01317 mddFreeBddArr(maskVarArr);
01318 return(subset);
01319 }
01320
01321
01322
01323 mvar_type
01324 mdd_get_var_by_id(mdd_manager *mddMgr, int id)
01325 {
01326 return(mddGetVarById(mddMgr, id));
01327 }
01328
01329
01330
01331 int
01332 mdd_check_support(
01333 mdd_manager *mddMgr,
01334 mdd_t *mdd,
01335 array_t *supportIdArray)
01336 {
01337 int i, mddId;
01338 st_table *supportTable = st_init_table(st_numcmp, st_numhash);
01339 array_t *tmpIdArray;
01340 int allSupportFlag = 1;
01341
01342 for (i = 0; i < array_n(supportIdArray); i++) {
01343 mddId = array_fetch(int, supportIdArray, i);
01344 st_insert(supportTable, (char *)(long)mddId, NULL);
01345 }
01346
01347 tmpIdArray = mdd_get_support(mddMgr, mdd);
01348 for (i = 0; i < array_n(tmpIdArray); i++) {
01349 mddId = array_fetch(int, tmpIdArray, i);
01350 if (!st_lookup(supportTable, (char *)(long)mddId, NULL)) {
01351 allSupportFlag = 0;
01352 break;
01353 }
01354 }
01355
01356 st_free_table(supportTable);
01357 array_free(tmpIdArray);
01358 return(allSupportFlag);
01359 }
01360
01361
01362 boolean
01363 mdd_equal_mod_care_set_array(mdd_t *aSet, mdd_t *bSet, array_t *careSetArray)
01364 {
01365 mdd_t *tmpMdd1, *tmpMdd2;
01366 mdd_t *careSet;
01367 int i;
01368 boolean result;
01369
01370 if (mdd_equal(aSet, bSet))
01371 return 1;
01372
01373 arrayForEachItem(mdd_t *, careSetArray, i, careSet) {
01374 tmpMdd1 = mdd_and(aSet, careSet, 1, 1);
01375 tmpMdd2 = mdd_and(bSet, careSet, 1, 1);
01376
01377 result = mdd_equal(tmpMdd1, tmpMdd2);
01378 mdd_free(tmpMdd1);
01379 mdd_free(tmpMdd2);
01380 if (result == 1)
01381 return 1;
01382 }
01383
01384 return 0;
01385 }
01386
01387
01388 boolean
01389 mdd_lequal_mod_care_set_array(mdd_t *aSet, mdd_t *bSet,
01390 boolean aPhase, boolean bPhase,
01391 array_t *careSetArray)
01392 {
01393 mdd_t *tmpMdd, *careSet;
01394 int i, result;
01395
01396 if (mdd_lequal(aSet, bSet, aPhase, bPhase))
01397 return 1;
01398
01399 arrayForEachItem(mdd_t *, careSetArray, i, careSet) {
01400 tmpMdd = mdd_and(aSet, careSet, aPhase, 1);
01401
01402 result = mdd_lequal(tmpMdd, bSet, 1, bPhase);
01403 mdd_free(tmpMdd);
01404 if (result == 1)
01405 return 1;
01406 }
01407
01408 return 0;
01409 }
01410
01411
01412
01413
01414 mdd_t *
01415 mdd_range_mdd(
01416 mdd_manager *mgr,
01417 array_t *support
01418 )
01419 {
01420 int var, varIndex;
01421 mdd_t *range;
01422
01423 range = mdd_one(mgr);
01424 arrayForEachItem(int, support, varIndex, var){
01425 mdd_t *rangeForVar;
01426 mdd_t *tmp;
01427
01428 rangeForVar = mddRetOnvalBdd(mgr, var);
01429 tmp = mdd_and( rangeForVar, range, 1, 1);
01430 mdd_free(rangeForVar);
01431 mdd_free(range);
01432 range = tmp;
01433 }
01434
01435 return range;
01436 }
01437
01438
01439
01440
01441
01442