00001
00023 #include "extra.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00047
00048
00049
00050
00053
00054
00055
00056
00057
00070 Extra_UnateInfo_t * Extra_UnateComputeFast(
00071 DdManager * dd,
00072 DdNode * bFunc)
00073 {
00074 DdNode * bSupp;
00075 DdNode * zRes;
00076 Extra_UnateInfo_t * p;
00077
00078 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
00079 zRes = Extra_zddUnateInfoCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
00080
00081 p = Extra_UnateInfoCreateFromZdd( dd, zRes, bSupp );
00082
00083 Cudd_RecursiveDeref( dd, bSupp );
00084 Cudd_RecursiveDerefZdd( dd, zRes );
00085
00086 return p;
00087
00088 }
00089
00090
00102 DdNode * Extra_zddUnateInfoCompute(
00103 DdManager * dd,
00104 DdNode * bF,
00105 DdNode * bVars)
00106 {
00107 DdNode * res;
00108 do {
00109 dd->reordered = 0;
00110 res = extraZddUnateInfoCompute( dd, bF, bVars );
00111 } while (dd->reordered == 1);
00112 return(res);
00113
00114 }
00115
00116
00128 DdNode * Extra_zddGetSingletonsBoth(
00129 DdManager * dd,
00130 DdNode * bVars)
00131 {
00132 DdNode * res;
00133 do {
00134 dd->reordered = 0;
00135 res = extraZddGetSingletonsBoth( dd, bVars );
00136 } while (dd->reordered == 1);
00137 return(res);
00138
00139 }
00140
00152 Extra_UnateInfo_t * Extra_UnateInfoAllocate( int nVars )
00153 {
00154 Extra_UnateInfo_t * p;
00155
00156 p = ALLOC( Extra_UnateInfo_t, 1 );
00157 memset( p, 0, sizeof(Extra_UnateInfo_t) );
00158 p->nVars = nVars;
00159 p->pVars = ALLOC( Extra_UnateVar_t, nVars );
00160 memset( p->pVars, 0, nVars * sizeof(Extra_UnateVar_t) );
00161 return p;
00162 }
00163
00175 void Extra_UnateInfoDissolve( Extra_UnateInfo_t * p )
00176 {
00177 free( p->pVars );
00178 free( p );
00179 }
00180
00192 void Extra_UnateInfoPrint( Extra_UnateInfo_t * p )
00193 {
00194 char * pBuffer;
00195 int i;
00196 pBuffer = ALLOC( char, p->nVarsMax+1 );
00197 memset( pBuffer, ' ', p->nVarsMax );
00198 pBuffer[p->nVarsMax] = 0;
00199 for ( i = 0; i < p->nVars; i++ )
00200 if ( p->pVars[i].Neg )
00201 pBuffer[ p->pVars[i].iVar ] = 'n';
00202 else if ( p->pVars[i].Pos )
00203 pBuffer[ p->pVars[i].iVar ] = 'p';
00204 else
00205 pBuffer[ p->pVars[i].iVar ] = '.';
00206 printf( "%s\n", pBuffer );
00207 free( pBuffer );
00208 }
00209
00210
00224 Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bSupp )
00225 {
00226 Extra_UnateInfo_t * p;
00227 DdNode * bTemp, * zSet, * zCube, * zTemp;
00228 int * pMapVars2Nums;
00229 int i, nSuppSize;
00230
00231 nSuppSize = Extra_bddSuppSize( dd, bSupp );
00232
00233
00234 p = Extra_UnateInfoAllocate( nSuppSize );
00235
00236
00237 pMapVars2Nums = ALLOC( int, dd->size );
00238 memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
00239
00240
00241 p->nVarsMax = dd->size;
00242 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00243 {
00244 p->pVars[i].iVar = bTemp->index;
00245 pMapVars2Nums[bTemp->index] = i;
00246 }
00247
00248
00249 zSet = zPairs; Cudd_Ref( zSet );
00250
00251 while ( zSet != z0 )
00252 {
00253
00254 zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
00255
00256
00257 assert( cuddT(zCube) == z1 && cuddE(zCube) == z0 );
00258 if ( zCube->index & 1 )
00259 p->pVars[ pMapVars2Nums[zCube->index/2] ].Neg = 1;
00260 else
00261 p->pVars[ pMapVars2Nums[zCube->index/2] ].Pos = 1;
00262
00263 p->nUnate++;
00264
00265
00266 zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
00267 Cudd_RecursiveDerefZdd( dd, zTemp );
00268 Cudd_RecursiveDerefZdd( dd, zCube );
00269
00270 }
00271 Cudd_RecursiveDerefZdd( dd, zSet );
00272 FREE( pMapVars2Nums );
00273 return p;
00274
00275 }
00276
00277
00278
00290 Extra_UnateInfo_t * Extra_UnateComputeSlow( DdManager * dd, DdNode * bFunc )
00291 {
00292 int nSuppSize;
00293 DdNode * bSupp, * bTemp;
00294 Extra_UnateInfo_t * p;
00295 int i, Res;
00296
00297
00298 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
00299 nSuppSize = Extra_bddSuppSize( dd, bSupp );
00300
00301
00302
00303
00304
00305 p = Extra_UnateInfoAllocate( nSuppSize );
00306
00307
00308 p->nVarsMax = dd->size;
00309 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00310 {
00311 Res = Extra_bddCheckUnateNaive( dd, bFunc, bTemp->index );
00312 p->pVars[i].iVar = bTemp->index;
00313 if ( Res == -1 )
00314 p->pVars[i].Neg = 1;
00315 else if ( Res == 1 )
00316 p->pVars[i].Pos = 1;
00317 p->nUnate += (Res != 0);
00318 }
00319 Cudd_RecursiveDeref( dd, bSupp );
00320 return p;
00321
00322 }
00323
00335 int Extra_bddCheckUnateNaive(
00336 DdManager * dd,
00337 DdNode * bF,
00338 int iVar)
00339 {
00340 DdNode * bCof0, * bCof1;
00341 int Res;
00342
00343 assert( iVar < dd->size );
00344
00345 bCof0 = Cudd_Cofactor( dd, bF, Cudd_Not(Cudd_bddIthVar(dd,iVar)) ); Cudd_Ref( bCof0 );
00346 bCof1 = Cudd_Cofactor( dd, bF, Cudd_bddIthVar(dd,iVar) ); Cudd_Ref( bCof1 );
00347
00348 if ( Cudd_bddLeq( dd, bCof0, bCof1 ) )
00349 Res = 1;
00350 else if ( Cudd_bddLeq( dd, bCof1, bCof0 ) )
00351 Res =-1;
00352 else
00353 Res = 0;
00354
00355 Cudd_RecursiveDeref( dd, bCof0 );
00356 Cudd_RecursiveDeref( dd, bCof1 );
00357 return Res;
00358 }
00359
00360
00361
00362
00363
00364
00365
00381 DdNode *
00382 extraZddUnateInfoCompute(
00383 DdManager * dd,
00384 DdNode * bFunc,
00385 DdNode * bVars )
00386 {
00387 DdNode * zRes;
00388 DdNode * bFR = Cudd_Regular(bFunc);
00389
00390 if ( cuddIsConstant(bFR) )
00391 {
00392 if ( cuddIsConstant(bVars) )
00393 return z0;
00394 return extraZddGetSingletonsBoth( dd, bVars );
00395 }
00396 assert( bVars != b1 );
00397
00398 if ( zRes = cuddCacheLookup2Zdd(dd, extraZddUnateInfoCompute, bFunc, bVars) )
00399 return zRes;
00400 else
00401 {
00402 DdNode * zRes0, * zRes1;
00403 DdNode * zTemp, * zPlus;
00404 DdNode * bF0, * bF1;
00405 DdNode * bVarsNew;
00406 int nVarsExtra;
00407 int LevelF;
00408 int AddVar;
00409
00410
00411
00412
00413 nVarsExtra = 0;
00414 LevelF = dd->perm[bFR->index];
00415 for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
00416 nVarsExtra++;
00417
00418 assert( bFR->index == bVarsNew->index );
00419
00420
00421 if ( bFR != bFunc )
00422 {
00423 bF0 = Cudd_Not( cuddE(bFR) );
00424 bF1 = Cudd_Not( cuddT(bFR) );
00425 }
00426 else
00427 {
00428 bF0 = cuddE(bFR);
00429 bF1 = cuddT(bFR);
00430 }
00431
00432
00433 zRes0 = extraZddUnateInfoCompute( dd, bF0, cuddT(bVarsNew) );
00434 if ( zRes0 == NULL )
00435 return NULL;
00436 cuddRef( zRes0 );
00437
00438
00439
00440 if ( zRes0 == z0 )
00441 zRes = zRes0;
00442 else
00443 {
00444 zRes1 = extraZddUnateInfoCompute( dd, bF1, cuddT(bVarsNew) );
00445 if ( zRes1 == NULL )
00446 {
00447 Cudd_RecursiveDerefZdd( dd, zRes0 );
00448 return NULL;
00449 }
00450 cuddRef( zRes1 );
00451
00452
00453
00454
00455 zRes = cuddZddIntersect( dd, zRes0, zRes1 );
00456 if ( zRes == NULL )
00457 {
00458 Cudd_RecursiveDerefZdd( dd, zRes0 );
00459 Cudd_RecursiveDerefZdd( dd, zRes1 );
00460 return NULL;
00461 }
00462 cuddRef( zRes );
00463 Cudd_RecursiveDerefZdd( dd, zRes0 );
00464 Cudd_RecursiveDerefZdd( dd, zRes1 );
00465 }
00466
00467
00468 AddVar = -1;
00469 if ( Cudd_bddLeq( dd, bF0, bF1 ) )
00470 AddVar = 0;
00471 else if ( Cudd_bddLeq( dd, bF1, bF0 ) )
00472 AddVar = 1;
00473 if ( AddVar >= 0 )
00474 {
00475
00476 zPlus = cuddZddGetNode( dd, 2*bFR->index + AddVar, z1, z0 );
00477 if ( zPlus == NULL )
00478 {
00479 Cudd_RecursiveDerefZdd( dd, zRes );
00480 return NULL;
00481 }
00482 cuddRef( zPlus );
00483
00484
00485 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00486 if ( zRes == NULL )
00487 {
00488 Cudd_RecursiveDerefZdd( dd, zTemp );
00489 Cudd_RecursiveDerefZdd( dd, zPlus );
00490 return NULL;
00491 }
00492 cuddRef( zRes );
00493 Cudd_RecursiveDerefZdd( dd, zTemp );
00494 Cudd_RecursiveDerefZdd( dd, zPlus );
00495 }
00496
00497
00498
00499
00500
00501 for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
00502 {
00503
00504 zPlus = cuddZddGetNode( dd, 2*bVarsNew->index+1, z1, z0 );
00505 if ( zPlus == NULL )
00506 {
00507 Cudd_RecursiveDerefZdd( dd, zRes );
00508 return NULL;
00509 }
00510 cuddRef( zPlus );
00511
00512
00513 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00514 if ( zRes == NULL )
00515 {
00516 Cudd_RecursiveDerefZdd( dd, zTemp );
00517 Cudd_RecursiveDerefZdd( dd, zPlus );
00518 return NULL;
00519 }
00520 cuddRef( zRes );
00521 Cudd_RecursiveDerefZdd( dd, zTemp );
00522 Cudd_RecursiveDerefZdd( dd, zPlus );
00523
00524
00525
00526 zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
00527 if ( zPlus == NULL )
00528 {
00529 Cudd_RecursiveDerefZdd( dd, zRes );
00530 return NULL;
00531 }
00532 cuddRef( zPlus );
00533
00534
00535 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00536 if ( zRes == NULL )
00537 {
00538 Cudd_RecursiveDerefZdd( dd, zTemp );
00539 Cudd_RecursiveDerefZdd( dd, zPlus );
00540 return NULL;
00541 }
00542 cuddRef( zRes );
00543 Cudd_RecursiveDerefZdd( dd, zTemp );
00544 Cudd_RecursiveDerefZdd( dd, zPlus );
00545 }
00546 cuddDeref( zRes );
00547
00548
00549 cuddCacheInsert2(dd, extraZddUnateInfoCompute, bFunc, bVars, zRes);
00550 return zRes;
00551 }
00552 }
00553
00554
00567 DdNode * extraZddGetSingletonsBoth(
00568 DdManager * dd,
00569 DdNode * bVars)
00570 {
00571 DdNode * zRes;
00572
00573 if ( bVars == b1 )
00574 return z1;
00575
00576 if ( zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletonsBoth, bVars) )
00577 return zRes;
00578 else
00579 {
00580 DdNode * zTemp, * zPlus;
00581
00582
00583 zRes = extraZddGetSingletonsBoth( dd, cuddT(bVars) );
00584 if ( zRes == NULL )
00585 return NULL;
00586 cuddRef( zRes );
00587
00588
00589
00590 zPlus = cuddZddGetNode( dd, 2*bVars->index+1, z1, z0 );
00591 if ( zPlus == NULL )
00592 {
00593 Cudd_RecursiveDerefZdd( dd, zRes );
00594 return NULL;
00595 }
00596 cuddRef( zPlus );
00597
00598
00599 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00600 if ( zRes == NULL )
00601 {
00602 Cudd_RecursiveDerefZdd( dd, zTemp );
00603 Cudd_RecursiveDerefZdd( dd, zPlus );
00604 return NULL;
00605 }
00606 cuddRef( zRes );
00607 Cudd_RecursiveDerefZdd( dd, zTemp );
00608 Cudd_RecursiveDerefZdd( dd, zPlus );
00609
00610
00611
00612 zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
00613 if ( zPlus == NULL )
00614 {
00615 Cudd_RecursiveDerefZdd( dd, zRes );
00616 return NULL;
00617 }
00618 cuddRef( zPlus );
00619
00620
00621 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00622 if ( zRes == NULL )
00623 {
00624 Cudd_RecursiveDerefZdd( dd, zTemp );
00625 Cudd_RecursiveDerefZdd( dd, zPlus );
00626 return NULL;
00627 }
00628 cuddRef( zRes );
00629 Cudd_RecursiveDerefZdd( dd, zTemp );
00630 Cudd_RecursiveDerefZdd( dd, zPlus );
00631
00632 cuddDeref( zRes );
00633 cuddCacheInsert1( dd, extraZddGetSingletonsBoth, bVars, zRes );
00634 return zRes;
00635 }
00636 }
00637
00638
00639
00640
00641