abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
extraBddSymm.c File Reference
#include "extraBdd.h"

Go to the source code of this file.

Macros

#define DD_GET_SYMM_VARS_TAG   0x0a /* former DD_BDD_XOR_EXIST_ABSTRACT_TAG */
 

Functions

Extra_SymmInfo_tExtra_SymmPairsCompute (DdManager *dd, DdNode *bFunc)
 
DdNodeExtra_zddSymmPairsCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNodeExtra_zddGetSymmetricVars (DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
 
DdNodeExtra_zddGetSingletons (DdManager *dd, DdNode *bVars)
 
DdNodeExtra_bddReduceVarSet (DdManager *dd, DdNode *bVars, DdNode *bF)
 
Extra_SymmInfo_tExtra_SymmPairsAllocate (int nVars)
 
void Extra_SymmPairsDissolve (Extra_SymmInfo_t *p)
 
void Extra_SymmPairsPrint (Extra_SymmInfo_t *p)
 
Extra_SymmInfo_tExtra_SymmPairsCreateFromZdd (DdManager *dd, DdNode *zPairs, DdNode *bSupp)
 
int Extra_bddCheckVarsSymmetric (DdManager *dd, DdNode *bF, int iVar1, int iVar2)
 
Extra_SymmInfo_tExtra_SymmPairsComputeNaive (DdManager *dd, DdNode *bFunc)
 
int Extra_bddCheckVarsSymmetricNaive (DdManager *dd, DdNode *bF, int iVar1, int iVar2)
 
DdNodeExtra_zddTuplesFromBdd (DdManager *dd, int K, DdNode *bVarsN)
 
DdNodeExtra_zddSelectOneSubset (DdManager *dd, DdNode *zS)
 
DdNodeextraZddSymmPairsCompute (DdManager *dd, DdNode *bFunc, DdNode *bVars)
 
DdNodeextraZddGetSymmetricVars (DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
 
DdNodeextraZddGetSingletons (DdManager *dd, DdNode *bVars)
 
DdNodeextraBddReduceVarSet (DdManager *dd, DdNode *bVars, DdNode *bF)
 
DdNodeextraBddCheckVarsSymmetric (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNodeextraZddTuplesFromBdd (DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
 
DdNodeextraZddSelectOneSubset (DdManager *dd, DdNode *zS)
 

Macro Definition Documentation

#define DD_GET_SYMM_VARS_TAG   0x0a /* former DD_BDD_XOR_EXIST_ABSTRACT_TAG */

CFile****************************************************************

FileName [extraBddSymm.c]

PackageName [extra]

Synopsis [Efficient methods to compute the information about symmetric variables using the algorithm presented in the paper: A. Mishchenko. Fast Computation of Symmetries in Boolean Functions. Transactions on CAD, Nov. 2003.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 2.0. Started - September 1, 2003.]

Revision [

Id:
extraBddSymm.c,v 1.0 2003/09/01 00:00:00 alanmi Exp

]

Definition at line 47 of file extraBddSymm.c.

Function Documentation

int Extra_bddCheckVarsSymmetric ( DdManager dd,
DdNode bF,
int  iVar1,
int  iVar2 
)

Function********************************************************************

Synopsis [Checks the possibility of two variables being symmetric.]

Description [Returns 0 if vars are not symmetric. Return 1 if vars can be symmetric.]

SideEffects []

SeeAlso []

Definition at line 360 of file extraBddSymm.c.

365 {
366  DdNode * bVars;
367  int Res;
368 
369 // return 1;
370 
371  assert( iVar1 != iVar2 );
372  assert( iVar1 < dd->size );
373  assert( iVar2 < dd->size );
374 
375  bVars = Cudd_bddAnd( dd, dd->vars[iVar1], dd->vars[iVar2] ); Cudd_Ref( bVars );
376 
377  Res = (int)( extraBddCheckVarsSymmetric( dd, bF, bVars ) == b1 );
378 
379  Cudd_RecursiveDeref( dd, bVars );
380 
381  return Res;
382 } /* end of Extra_bddCheckVarsSymmetric */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define b1
Definition: extraBdd.h:76
static int size
Definition: cuddSign.c:86
DdNode ** vars
Definition: cuddInt.h:390
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define assert(ex)
Definition: util_old.h:213
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
DdNode * extraBddCheckVarsSymmetric(DdManager *dd, DdNode *bF, DdNode *bVars)
int Extra_bddCheckVarsSymmetricNaive ( DdManager dd,
DdNode bF,
int  iVar1,
int  iVar2 
)

Function********************************************************************

Synopsis [Checks if the two variables are symmetric.]

Description [Returns 0 if vars are not symmetric. Return 1 if vars are symmetric.]

SideEffects []

SeeAlso []

Definition at line 443 of file extraBddSymm.c.

448 {
449  DdNode * bCube1, * bCube2;
450  DdNode * bCof01, * bCof10;
451  int Res;
452 
453  assert( iVar1 != iVar2 );
454  assert( iVar1 < dd->size );
455  assert( iVar2 < dd->size );
456 
457  bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] ); Cudd_Ref( bCube1 );
458  bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] ); Cudd_Ref( bCube2 );
459 
460  bCof01 = Cudd_Cofactor( dd, bF, bCube1 ); Cudd_Ref( bCof01 );
461  bCof10 = Cudd_Cofactor( dd, bF, bCube2 ); Cudd_Ref( bCof10 );
462 
463  Res = (int)( bCof10 == bCof01 );
464 
465  Cudd_RecursiveDeref( dd, bCof01 );
466  Cudd_RecursiveDeref( dd, bCof10 );
467  Cudd_RecursiveDeref( dd, bCube1 );
468  Cudd_RecursiveDeref( dd, bCube2 );
469 
470  return Res;
471 } /* end of Extra_bddCheckVarsSymmetricNaive */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:123
static int size
Definition: cuddSign.c:86
DdNode ** vars
Definition: cuddInt.h:390
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define assert(ex)
Definition: util_old.h:213
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
DdNode* Extra_bddReduceVarSet ( DdManager dd,
DdNode bVars,
DdNode bF 
)

Function********************************************************************

Synopsis [Filters the set of variables using the support of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 181 of file extraBddSymm.c.

185 {
186  DdNode * res;
187  do {
188  dd->reordered = 0;
189  res = extraBddReduceVarSet( dd, bVars, bF );
190  } while (dd->reordered == 1);
191  return(res);
192 
193 } /* end of Extra_bddReduceVarSet */
Definition: cudd.h:278
DdNode * extraBddReduceVarSet(DdManager *dd, DdNode *bVars, DdNode *bF)
int reordered
Definition: cuddInt.h:409
Extra_SymmInfo_t* Extra_SymmPairsAllocate ( int  nVars)

Function********************************************************************

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 207 of file extraBddSymm.c.

208 {
209  int i;
211 
212  // allocate and clean the storage for symmetry info
213  p = ABC_ALLOC( Extra_SymmInfo_t, 1 );
214  memset( p, 0, sizeof(Extra_SymmInfo_t) );
215  p->nVars = nVars;
216  p->pVars = ABC_ALLOC( int, nVars );
217  p->pSymms = ABC_ALLOC( char *, nVars );
218  p->pSymms[0] = ABC_ALLOC( char , nVars * nVars );
219  memset( p->pSymms[0], 0, nVars * nVars * sizeof(char) );
220 
221  for ( i = 1; i < nVars; i++ )
222  p->pSymms[i] = p->pSymms[i-1] + nVars;
223 
224  return p;
225 } /* end of Extra_SymmPairsAllocate */
char * memset()
char ** pSymms
Definition: extraBdd.h:219
static Llb_Mgr_t * p
Definition: llb3Image.c:950
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
Extra_SymmInfo_t* Extra_SymmPairsCompute ( DdManager dd,
DdNode bFunc 
)

AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Computes the classical symmetry information for the function.]

Description [Returns the symmetry information in the form of Extra_SymmInfo_t structure.]

SideEffects [If the ZDD variables are not derived from BDD variables with multiplicity 2, this function may derive them in a wrong way.]

SeeAlso []

Definition at line 73 of file extraBddSymm.c.

76 {
77  DdNode * bSupp;
78  DdNode * zRes;
80 
81  bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
82  zRes = Extra_zddSymmPairsCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
83 
84  p = Extra_SymmPairsCreateFromZdd( dd, zRes, bSupp );
85 
86  Cudd_RecursiveDeref( dd, bSupp );
87  Cudd_RecursiveDerefZdd( dd, zRes );
88 
89  return p;
90 
91 } /* end of Extra_SymmPairsCompute */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
static Llb_Mgr_t * p
Definition: llb3Image.c:950
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:740
DdNode * Extra_zddSymmPairsCompute(DdManager *dd, DdNode *bF, DdNode *bVars)
Definition: extraBddSymm.c:105
Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd(DdManager *dd, DdNode *zPairs, DdNode *bSupp)
Definition: extraBddSymm.c:288
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
Extra_SymmInfo_t* Extra_SymmPairsComputeNaive ( DdManager dd,
DdNode bFunc 
)

Function********************************************************************

Synopsis [Computes the classical symmetry information for the function.]

Description [Uses the naive way of comparing cofactors.]

SideEffects []

SeeAlso []

Definition at line 396 of file extraBddSymm.c.

397 {
398  DdNode * bSupp, * bTemp;
399  int nSuppSize;
401  int i, k;
402 
403  // compute the support
404  bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
405  nSuppSize = Extra_bddSuppSize( dd, bSupp );
406 //printf( "Support = %d. ", nSuppSize );
407 //Extra_bddPrint( dd, bSupp );
408 //printf( "%d ", nSuppSize );
409 
410  // allocate the storage for symmetry info
411  p = Extra_SymmPairsAllocate( nSuppSize );
412 
413  // assign the variables
414  p->nVarsMax = dd->size;
415  for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
416  p->pVars[i] = bTemp->index;
417 
418  // go through the candidate pairs and check using Idea1
419  for ( i = 0; i < nSuppSize; i++ )
420  for ( k = i+1; k < nSuppSize; k++ )
421  {
422  p->pSymms[k][i] = p->pSymms[i][k] = Extra_bddCheckVarsSymmetricNaive( dd, bFunc, p->pVars[i], p->pVars[k] );
423  if ( p->pSymms[i][k] )
424  p->nSymms++;
425  }
426 
427  Cudd_RecursiveDeref( dd, bSupp );
428  return p;
429 
430 } /* end of Extra_SymmPairsComputeNaive */
char ** pSymms
Definition: extraBdd.h:219
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
Definition: extraBddMisc.c:321
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
static Llb_Mgr_t * p
Definition: llb3Image.c:950
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:740
int size
Definition: cuddInt.h:361
#define b1
Definition: extraBdd.h:76
for(p=first;p->value< newval;p=p->next)
Extra_SymmInfo_t * Extra_SymmPairsAllocate(int nVars)
Definition: extraBddSymm.c:207
#define cuddT(node)
Definition: cuddInt.h:636
int Extra_bddCheckVarsSymmetricNaive(DdManager *dd, DdNode *bF, int iVar1, int iVar2)
Definition: extraBddSymm.c:443
DdHalfWord index
Definition: cudd.h:279
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
Extra_SymmInfo_t* Extra_SymmPairsCreateFromZdd ( DdManager dd,
DdNode zPairs,
DdNode bSupp 
)

Function********************************************************************

Synopsis [Creates the symmetry information structure from ZDD.]

Description [ZDD representation of symmetries is the set of cubes, each of which has two variables in the positive polarity. These variables correspond to the symmetric variable pair.]

SideEffects []

SeeAlso []

Definition at line 288 of file extraBddSymm.c.

289 {
290  int i;
291  int nSuppSize;
293  int * pMapVars2Nums;
294  DdNode * bTemp;
295  DdNode * zSet, * zCube, * zTemp;
296  int iVar1, iVar2;
297 
298  nSuppSize = Extra_bddSuppSize( dd, bSupp );
299 
300  // allocate and clean the storage for symmetry info
301  p = Extra_SymmPairsAllocate( nSuppSize );
302 
303  // allocate the storage for the temporary map
304  pMapVars2Nums = ABC_ALLOC( int, dd->size );
305  memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
306 
307  // assign the variables
308  p->nVarsMax = dd->size;
309 // p->nNodes = Cudd_DagSize( zPairs );
310  p->nNodes = 0;
311  for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
312  {
313  p->pVars[i] = bTemp->index;
314  pMapVars2Nums[bTemp->index] = i;
315  }
316 
317  // write the symmetry info into the structure
318  zSet = zPairs; Cudd_Ref( zSet );
319  while ( zSet != z0 )
320  {
321  // get the next cube
322  zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
323 
324  // add these two variables to the data structure
325  assert( cuddT( cuddT(zCube) ) == z1 );
326  iVar1 = zCube->index/2;
327  iVar2 = cuddT(zCube)->index/2;
328  if ( pMapVars2Nums[iVar1] < pMapVars2Nums[iVar2] )
329  p->pSymms[ pMapVars2Nums[iVar1] ][ pMapVars2Nums[iVar2] ] = 1;
330  else
331  p->pSymms[ pMapVars2Nums[iVar2] ][ pMapVars2Nums[iVar1] ] = 1;
332  // count the symmetric pairs
333  p->nSymms ++;
334 
335  // update the cuver and deref the cube
336  zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
337  Cudd_RecursiveDerefZdd( dd, zTemp );
338  Cudd_RecursiveDerefZdd( dd, zCube );
339 
340  } // for each cube
341  Cudd_RecursiveDerefZdd( dd, zSet );
342 
343  ABC_FREE( pMapVars2Nums );
344  return p;
345 
346 } /* end of Extra_SymmPairsCreateFromZdd */
char * memset()
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
char ** pSymms
Definition: extraBdd.h:219
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
Definition: extraBddMisc.c:321
Definition: cudd.h:278
#define z1
Definition: extraBdd.h:78
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int size
Definition: cuddInt.h:361
#define b1
Definition: extraBdd.h:76
DdNode * Extra_zddSelectOneSubset(DdManager *dd, DdNode *zS)
Definition: extraBddSymm.c:546
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * Cudd_zddDiff(DdManager *dd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:236
#define z0
Definition: extraBdd.h:77
Extra_SymmInfo_t * Extra_SymmPairsAllocate(int nVars)
Definition: extraBddSymm.c:207
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define assert(ex)
Definition: util_old.h:213
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
void Extra_SymmPairsDissolve ( Extra_SymmInfo_t p)

Function********************************************************************

Synopsis [Deallocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 238 of file extraBddSymm.c.

239 {
240  ABC_FREE( p->pVars );
241  ABC_FREE( p->pSymms[0] );
242  ABC_FREE( p->pSymms );
243  ABC_FREE( p );
244 } /* end of Extra_SymmPairsDissolve */
char ** pSymms
Definition: extraBdd.h:219
#define ABC_FREE(obj)
Definition: abc_global.h:232
void Extra_SymmPairsPrint ( Extra_SymmInfo_t p)

Function********************************************************************

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 257 of file extraBddSymm.c.

258 {
259  int i, k;
260  printf( "\n" );
261  for ( i = 0; i < p->nVars; i++ )
262  {
263  for ( k = 0; k <= i; k++ )
264  printf( " " );
265  for ( k = i+1; k < p->nVars; k++ )
266  if ( p->pSymms[i][k] )
267  printf( "1" );
268  else
269  printf( "." );
270  printf( "\n" );
271  }
272 } /* end of Extra_SymmPairsPrint */
char ** pSymms
Definition: extraBdd.h:219
DdNode* Extra_zddGetSingletons ( DdManager dd,
DdNode bVars 
)

Function********************************************************************

Synopsis [Converts a set of variables into a set of singleton subsets.]

Description []

SideEffects []

SeeAlso []

Definition at line 157 of file extraBddSymm.c.

160 {
161  DdNode * res;
162  do {
163  dd->reordered = 0;
164  res = extraZddGetSingletons( dd, bVars );
165  } while (dd->reordered == 1);
166  return(res);
167 
168 } /* end of Extra_zddGetSingletons */
Definition: cudd.h:278
DdNode * extraZddGetSingletons(DdManager *dd, DdNode *bVars)
int reordered
Definition: cuddInt.h:409
DdNode* Extra_zddGetSymmetricVars ( DdManager dd,
DdNode bF,
DdNode bG,
DdNode bVars 
)

Function********************************************************************

Synopsis [Returns a singleton-set ZDD containing all variables that are symmetric with the given one.]

Description []

SideEffects []

SeeAlso []

Definition at line 130 of file extraBddSymm.c.

135 {
136  DdNode * res;
137  do {
138  dd->reordered = 0;
139  res = extraZddGetSymmetricVars( dd, bF, bG, bVars );
140  } while (dd->reordered == 1);
141  return(res);
142 
143 } /* end of Extra_zddGetSymmetricVars */
Definition: cudd.h:278
DdNode * extraZddGetSymmetricVars(DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
Definition: extraBddSymm.c:804
int reordered
Definition: cuddInt.h:409
DdNode* Extra_zddSelectOneSubset ( DdManager dd,
DdNode zS 
)

Function********************************************************************

Synopsis [Selects one subset from the set of subsets represented by a ZDD.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 546 of file extraBddSymm.c.

549 {
550  DdNode *res;
551  do {
552  dd->reordered = 0;
553  res = extraZddSelectOneSubset(dd, zS);
554  } while (dd->reordered == 1);
555  return(res);
556 
557 } /* end of Extra_zddSelectOneSubset */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * extraZddSelectOneSubset(DdManager *dd, DdNode *zS)
DdNode* Extra_zddSymmPairsCompute ( DdManager dd,
DdNode bF,
DdNode bVars 
)

Function********************************************************************

Synopsis [Computes the classical symmetry information as a ZDD.]

Description []

SideEffects []

SeeAlso []

Definition at line 105 of file extraBddSymm.c.

109 {
110  DdNode * res;
111  do {
112  dd->reordered = 0;
113  res = extraZddSymmPairsCompute( dd, bF, bVars );
114  } while (dd->reordered == 1);
115  return(res);
116 
117 } /* end of Extra_zddSymmPairsCompute */
DdNode * extraZddSymmPairsCompute(DdManager *dd, DdNode *bFunc, DdNode *bVars)
Definition: extraBddSymm.c:580
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode* Extra_zddTuplesFromBdd ( DdManager dd,
int  K,
DdNode bVarsN 
)

Function********************************************************************

Synopsis [Builds ZDD representing the set of fixed-size variable tuples.]

Description [Creates ZDD of all combinations of variables in Support that is represented by a BDD.]

SideEffects [New ZDD variables are created if indices of the variables present in the combination are larger than the currently allocated number of ZDD variables.]

SeeAlso []

Definition at line 488 of file extraBddSymm.c.

492 {
493  DdNode *zRes;
494  int autoDynZ;
495 
496  autoDynZ = dd->autoDynZ;
497  dd->autoDynZ = 0;
498 
499  do {
500  /* transform the numeric arguments (K) into a DdNode* argument;
501  * this allows us to use the standard internal CUDD cache */
502  DdNode *bVarSet = bVarsN, *bVarsK = bVarsN;
503  int nVars = 0, i;
504 
505  /* determine the number of variables in VarSet */
506  while ( bVarSet != b1 )
507  {
508  nVars++;
509  /* make sure that the VarSet is a cube */
510  if ( cuddE( bVarSet ) != b0 )
511  return NULL;
512  bVarSet = cuddT( bVarSet );
513  }
514  /* make sure that the number of variables in VarSet is less or equal
515  that the number of variables that should be present in the tuples
516  */
517  if ( K > nVars )
518  return NULL;
519 
520  /* the second argument in the recursive call stannds for <n>;
521  * reate the first argument, which stands for <k>
522  * as when we are talking about the tuple of <k> out of <n> */
523  for ( i = 0; i < nVars-K; i++ )
524  bVarsK = cuddT( bVarsK );
525 
526  dd->reordered = 0;
527  zRes = extraZddTuplesFromBdd(dd, bVarsK, bVarsN );
528 
529  } while (dd->reordered == 1);
530  dd->autoDynZ = autoDynZ;
531  return zRes;
532 
533 } /* end of Extra_zddTuplesFromBdd */
Definition: cudd.h:278
#define b1
Definition: extraBdd.h:76
int reordered
Definition: cuddInt.h:409
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * extraZddTuplesFromBdd(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
#define b0
Definition: extraBdd.h:75
int autoDynZ
Definition: cuddInt.h:417
#define cuddE(node)
Definition: cuddInt.h:652
DdNode* extraBddCheckVarsSymmetric ( DdManager dd,
DdNode bF,
DdNode bVars 
)

Function********************************************************************

Synopsis [Performs the recursive step of Extra_bddCheckVarsSymmetric().]

Description [Returns b0 if the variables are not symmetric. Returns b1 if the variables can be symmetric. The variables are represented in the form of a two-variable cube. In case the cube contains one variable (below Var1 level), the cube's pointer is complemented if the variable Var1 occurred on the current path; otherwise, the cube's pointer is regular. Uses additional complemented bit (Hash_Not) to mark the result if in the BDD rooted that this node there is a branch passing though the node labeled with Var2.]

SideEffects []

SeeAlso []

Definition at line 1169 of file extraBddSymm.c.

1173 {
1174  DdNode * bRes;
1175 
1176  if ( bF == b0 )
1177  return b1;
1178 
1179  assert( bVars != b1 );
1180 
1181  if ( (bRes = cuddCacheLookup2(dd, extraBddCheckVarsSymmetric, bF, bVars)) )
1182  return bRes;
1183  else
1184  {
1185  DdNode * bRes0, * bRes1;
1186  DdNode * bF0, * bF1;
1187  DdNode * bFR = Cudd_Regular(bF);
1188  int LevelF = cuddI(dd,bFR->index);
1189 
1190  DdNode * bVarsR = Cudd_Regular(bVars);
1191  int fVar1Pres;
1192  int iLev1;
1193  int iLev2;
1194 
1195  if ( bVarsR != bVars ) // cube's pointer is complemented
1196  {
1197  assert( cuddT(bVarsR) == b1 );
1198  fVar1Pres = 1; // the first var is present on the path
1199  iLev1 = -1; // we are already below the first var level
1200  iLev2 = dd->perm[bVarsR->index]; // the level of the second var
1201  }
1202  else // cube's pointer is NOT complemented
1203  {
1204  fVar1Pres = 0; // the first var is absent on the path
1205  if ( cuddT(bVars) == b1 )
1206  {
1207  iLev1 = -1; // we are already below the first var level
1208  iLev2 = dd->perm[bVars->index]; // the level of the second var
1209  }
1210  else
1211  {
1212  assert( cuddT(cuddT(bVars)) == b1 );
1213  iLev1 = dd->perm[bVars->index]; // the level of the first var
1214  iLev2 = dd->perm[cuddT(bVars)->index]; // the level of the second var
1215  }
1216  }
1217 
1218  // cofactor the function
1219  // the cofactors are needed only if we are above the second level
1220  if ( LevelF < iLev2 )
1221  {
1222  if ( bFR != bF ) // bFunc is complemented
1223  {
1224  bF0 = Cudd_Not( cuddE(bFR) );
1225  bF1 = Cudd_Not( cuddT(bFR) );
1226  }
1227  else
1228  {
1229  bF0 = cuddE(bFR);
1230  bF1 = cuddT(bFR);
1231  }
1232  }
1233  else
1234  bF0 = bF1 = NULL;
1235 
1236  // consider five cases:
1237  // (1) F is above iLev1
1238  // (2) F is on the level iLev1
1239  // (3) F is between iLev1 and iLev2
1240  // (4) F is on the level iLev2
1241  // (5) F is below iLev2
1242 
1243  // (1) F is above iLev1
1244  if ( LevelF < iLev1 )
1245  {
1246  // the returned result cannot have the hash attribute
1247  // because we still did not reach the level of Var1;
1248  // the attribute never travels above the level of Var1
1249  bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
1250 // assert( !Hash_IsComplement( bRes0 ) );
1251  assert( bRes0 != z0 );
1252  if ( bRes0 == b0 )
1253  bRes = b0;
1254  else
1255  bRes = extraBddCheckVarsSymmetric( dd, bF1, bVars );
1256 // assert( !Hash_IsComplement( bRes ) );
1257  assert( bRes != z0 );
1258  }
1259  // (2) F is on the level iLev1
1260  else if ( LevelF == iLev1 )
1261  {
1262  bRes0 = extraBddCheckVarsSymmetric( dd, bF0, Cudd_Not( cuddT(bVars) ) );
1263  if ( bRes0 == b0 )
1264  bRes = b0;
1265  else
1266  {
1267  bRes1 = extraBddCheckVarsSymmetric( dd, bF1, Cudd_Not( cuddT(bVars) ) );
1268  if ( bRes1 == b0 )
1269  bRes = b0;
1270  else
1271  {
1272 // if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
1273  if ( bRes0 == z0 || bRes1 == z0 )
1274  bRes = b1;
1275  else
1276  bRes = b0;
1277  }
1278  }
1279  }
1280  // (3) F is between iLev1 and iLev2
1281  else if ( LevelF < iLev2 )
1282  {
1283  bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
1284  if ( bRes0 == b0 )
1285  bRes = b0;
1286  else
1287  {
1288  bRes1 = extraBddCheckVarsSymmetric( dd, bF1, bVars );
1289  if ( bRes1 == b0 )
1290  bRes = b0;
1291  else
1292  {
1293 // if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
1294 // bRes = Hash_Not( b1 );
1295  if ( bRes0 == z0 || bRes1 == z0 )
1296  bRes = z0;
1297  else
1298  bRes = b1;
1299  }
1300  }
1301  }
1302  // (4) F is on the level iLev2
1303  else if ( LevelF == iLev2 )
1304  {
1305  // this is the only place where the hash attribute (Hash_Not) can be added
1306  // to the result; it can be added only if the path came through the node
1307  // lebeled with Var1; therefore, the hash attribute cannot be returned
1308  // to the caller function
1309  if ( fVar1Pres )
1310 // bRes = Hash_Not( b1 );
1311  bRes = z0;
1312  else
1313  bRes = b0;
1314  }
1315  // (5) F is below iLev2
1316  else // if ( LevelF > iLev2 )
1317  {
1318  // it is possible that the path goes through the node labeled by Var1
1319  // and still everything is okay; we do not label with Hash_Not here
1320  // because the path does not go through node labeled by Var2
1321  bRes = b1;
1322  }
1323 
1324  cuddCacheInsert2(dd, extraBddCheckVarsSymmetric, bF, bVars, bRes);
1325  return bRes;
1326  }
1327 } /* end of extraBddCheckVarsSymmetric */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define b1
Definition: extraBdd.h:76
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define z0
Definition: extraBdd.h:77
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
#define b0
Definition: extraBdd.h:75
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
DdNode * extraBddCheckVarsSymmetric(DdManager *dd, DdNode *bF, DdNode *bVars)
int * perm
Definition: cuddInt.h:386
DdNode* extraBddReduceVarSet ( DdManager dd,
DdNode bVars,
DdNode bF 
)

Function********************************************************************

Synopsis [Performs a recursive step of Extra_bddReduceVarSet.]

Description [Returns the set of all variables in the given set that are not in the support of the given function.]

SideEffects []

SeeAlso []

Definition at line 1062 of file extraBddSymm.c.

1066 {
1067  DdNode * bRes;
1068  DdNode * bFR = Cudd_Regular(bF);
1069 
1070  if ( cuddIsConstant(bFR) || bVars == b1 )
1071  return bVars;
1072 
1073  if ( (bRes = cuddCacheLookup2(dd, extraBddReduceVarSet, bVars, bF)) )
1074  return bRes;
1075  else
1076  {
1077  DdNode * bF0, * bF1;
1078  DdNode * bVarsThis, * bVarsLower, * bTemp;
1079  int LevelF;
1080 
1081  // if LevelF is below LevelV, scroll through the vars in bVars
1082  LevelF = dd->perm[bFR->index];
1083  for ( bVarsThis = bVars; LevelF > cuddI(dd,bVarsThis->index); bVarsThis = cuddT(bVarsThis) );
1084  // scroll also through the current var, because it should be not be added
1085  if ( LevelF == cuddI(dd,bVarsThis->index) )
1086  bVarsLower = cuddT(bVarsThis);
1087  else
1088  bVarsLower = bVarsThis;
1089 
1090  // cofactor the function
1091  if ( bFR != bF ) // bFunc is complemented
1092  {
1093  bF0 = Cudd_Not( cuddE(bFR) );
1094  bF1 = Cudd_Not( cuddT(bFR) );
1095  }
1096  else
1097  {
1098  bF0 = cuddE(bFR);
1099  bF1 = cuddT(bFR);
1100  }
1101 
1102  // solve subproblems
1103  bRes = extraBddReduceVarSet( dd, bVarsLower, bF0 );
1104  if ( bRes == NULL )
1105  return NULL;
1106  cuddRef( bRes );
1107 
1108  bRes = extraBddReduceVarSet( dd, bTemp = bRes, bF1 );
1109  if ( bRes == NULL )
1110  {
1111  Cudd_RecursiveDeref( dd, bTemp );
1112  return NULL;
1113  }
1114  cuddRef( bRes );
1115  Cudd_RecursiveDeref( dd, bTemp );
1116 
1117  // the current var should not be added
1118  // add the skipped vars
1119  if ( bVarsThis != bVars )
1120  {
1121  DdNode * bVarsExtra;
1122 
1123  // extract the skipped variables
1124  bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsThis );
1125  if ( bVarsExtra == NULL )
1126  {
1127  Cudd_RecursiveDeref( dd, bRes );
1128  return NULL;
1129  }
1130  cuddRef( bVarsExtra );
1131 
1132  // add these variables
1133  bRes = cuddBddAndRecur( dd, bTemp = bRes, bVarsExtra );
1134  if ( bRes == NULL )
1135  {
1136  Cudd_RecursiveDeref( dd, bTemp );
1137  Cudd_RecursiveDeref( dd, bVarsExtra );
1138  return NULL;
1139  }
1140  cuddRef( bRes );
1141  Cudd_RecursiveDeref( dd, bTemp );
1142  Cudd_RecursiveDeref( dd, bVarsExtra );
1143  }
1144  cuddDeref( bRes );
1145 
1146  cuddCacheInsert2( dd, extraBddReduceVarSet, bVars, bF, bRes );
1147  return bRes;
1148  }
1149 } /* end of extraBddReduceVarSet */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define b1
Definition: extraBdd.h:76
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * extraBddReduceVarSet(DdManager *dd, DdNode *bVars, DdNode *bF)
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode* extraZddGetSingletons ( DdManager dd,
DdNode bVars 
)

Function********************************************************************

Synopsis [Performs a recursive step of Extra_zddGetSingletons.]

Description [Returns the set of ZDD singletons, containing those positive polarity ZDD variables that correspond to the BDD variables in bVars.]

SideEffects []

SeeAlso []

Definition at line 1001 of file extraBddSymm.c.

1004 {
1005  DdNode * zRes;
1006 
1007  if ( bVars == b1 )
1008 // if ( bVars == b0 ) // bug fixed by Jin Zhang, Jan 23, 2004
1009  return z1;
1010 
1011  if ( (zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletons, bVars)) )
1012  return zRes;
1013  else
1014  {
1015  DdNode * zTemp, * zPlus;
1016 
1017  // solve subproblem
1018  zRes = extraZddGetSingletons( dd, cuddT(bVars) );
1019  if ( zRes == NULL )
1020  return NULL;
1021  cuddRef( zRes );
1022 
1023  zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
1024  if ( zPlus == NULL )
1025  {
1026  Cudd_RecursiveDerefZdd( dd, zRes );
1027  return NULL;
1028  }
1029  cuddRef( zPlus );
1030 
1031  // add these to the result
1032  zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
1033  if ( zRes == NULL )
1034  {
1035  Cudd_RecursiveDerefZdd( dd, zTemp );
1036  Cudd_RecursiveDerefZdd( dd, zPlus );
1037  return NULL;
1038  }
1039  cuddRef( zRes );
1040  Cudd_RecursiveDerefZdd( dd, zTemp );
1041  Cudd_RecursiveDerefZdd( dd, zPlus );
1042  cuddDeref( zRes );
1043 
1044  cuddCacheInsert1( dd, extraZddGetSingletons, bVars, zRes );
1045  return zRes;
1046  }
1047 } /* end of extraZddGetSingletons */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
#define z1
Definition: extraBdd.h:78
#define b1
Definition: extraBdd.h:76
DdNode * extraZddGetSingletons(DdManager *dd, DdNode *bVars)
#define z0
Definition: extraBdd.h:77
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:553
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddCacheLookup1Zdd(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:664
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode* extraZddGetSymmetricVars ( DdManager dd,
DdNode bF,
DdNode bG,
DdNode bVars 
)

Function********************************************************************

Synopsis [Performs a recursive step of Extra_zddGetSymmetricVars.]

Description [Returns the set of ZDD singletons, containing those positive ZDD variables that correspond to BDD variables x, for which it is true that bF(x=0) == bG(x=1).]

SideEffects []

SeeAlso []

Definition at line 804 of file extraBddSymm.c.

809 {
810  DdNode * zRes;
811  DdNode * bFR = Cudd_Regular(bF);
812  DdNode * bGR = Cudd_Regular(bG);
813 
814  if ( cuddIsConstant(bFR) && cuddIsConstant(bGR) )
815  {
816  if ( bF == bG )
817  return extraZddGetSingletons( dd, bVars );
818  else
819  return z0;
820  }
821  assert( bVars != b1 );
822 
823  if ( (zRes = cuddCacheLookupZdd(dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars)) )
824  return zRes;
825  else
826  {
827  DdNode * zRes0, * zRes1;
828  DdNode * zPlus, * zTemp;
829  DdNode * bF0, * bF1;
830  DdNode * bG0, * bG1;
831  DdNode * bVarsNew;
832 
833  int LevelF = cuddI(dd,bFR->index);
834  int LevelG = cuddI(dd,bGR->index);
835  int LevelFG;
836 
837  if ( LevelF < LevelG )
838  LevelFG = LevelF;
839  else
840  LevelFG = LevelG;
841 
842  // at least one of the arguments is not a constant
843  assert( LevelFG < dd->size );
844 
845  // every variable in bF and bG should be also in bVars, therefore LevelFG cannot be above LevelV
846  // if LevelFG is below LevelV, scroll through the vars in bVars to the same level as LevelFG
847  for ( bVarsNew = bVars; LevelFG > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) );
848  assert( LevelFG == dd->perm[bVarsNew->index] );
849 
850  // cofactor the functions
851  if ( LevelF == LevelFG )
852  {
853  if ( bFR != bF ) // bF is complemented
854  {
855  bF0 = Cudd_Not( cuddE(bFR) );
856  bF1 = Cudd_Not( cuddT(bFR) );
857  }
858  else
859  {
860  bF0 = cuddE(bFR);
861  bF1 = cuddT(bFR);
862  }
863  }
864  else
865  bF0 = bF1 = bF;
866 
867  if ( LevelG == LevelFG )
868  {
869  if ( bGR != bG ) // bG is complemented
870  {
871  bG0 = Cudd_Not( cuddE(bGR) );
872  bG1 = Cudd_Not( cuddT(bGR) );
873  }
874  else
875  {
876  bG0 = cuddE(bGR);
877  bG1 = cuddT(bGR);
878  }
879  }
880  else
881  bG0 = bG1 = bG;
882 
883  // solve subproblems
884  zRes0 = extraZddGetSymmetricVars( dd, bF0, bG0, cuddT(bVarsNew) );
885  if ( zRes0 == NULL )
886  return NULL;
887  cuddRef( zRes0 );
888 
889  // if there is not symmetries in the negative cofactor
890  // there is no need to test the positive cofactor
891  if ( zRes0 == z0 )
892  zRes = zRes0; // zRes takes reference
893  else
894  {
895  zRes1 = extraZddGetSymmetricVars( dd, bF1, bG1, cuddT(bVarsNew) );
896  if ( zRes1 == NULL )
897  {
898  Cudd_RecursiveDerefZdd( dd, zRes0 );
899  return NULL;
900  }
901  cuddRef( zRes1 );
902 
903  // only those variables should belong to the resulting set
904  // for which the property is true for both cofactors
905  zRes = cuddZddIntersect( dd, zRes0, zRes1 );
906  if ( zRes == NULL )
907  {
908  Cudd_RecursiveDerefZdd( dd, zRes0 );
909  Cudd_RecursiveDerefZdd( dd, zRes1 );
910  return NULL;
911  }
912  cuddRef( zRes );
913  Cudd_RecursiveDerefZdd( dd, zRes0 );
914  Cudd_RecursiveDerefZdd( dd, zRes1 );
915  }
916 
917  // add one more singleton if the property is true for this variable
918  if ( bF0 == bG1 )
919  {
920  zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
921  if ( zPlus == NULL )
922  {
923  Cudd_RecursiveDerefZdd( dd, zRes );
924  return NULL;
925  }
926  cuddRef( zPlus );
927 
928  // add these variable pairs to the result
929  zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
930  if ( zRes == NULL )
931  {
932  Cudd_RecursiveDerefZdd( dd, zTemp );
933  Cudd_RecursiveDerefZdd( dd, zPlus );
934  return NULL;
935  }
936  cuddRef( zRes );
937  Cudd_RecursiveDerefZdd( dd, zTemp );
938  Cudd_RecursiveDerefZdd( dd, zPlus );
939  }
940 
941  if ( bF == bG && bVars != bVarsNew )
942  {
943  // if the functions are equal, so are their cofactors
944  // add those variables from V that are above F and G
945 
946  DdNode * bVarsExtra;
947 
948  assert( LevelFG > dd->perm[bVars->index] );
949 
950  // create the BDD of the extra variables
951  bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsNew );
952  if ( bVarsExtra == NULL )
953  {
954  Cudd_RecursiveDerefZdd( dd, zRes );
955  return NULL;
956  }
957  cuddRef( bVarsExtra );
958 
959  zPlus = extraZddGetSingletons( dd, bVarsExtra );
960  if ( zPlus == NULL )
961  {
962  Cudd_RecursiveDeref( dd, bVarsExtra );
963  Cudd_RecursiveDerefZdd( dd, zRes );
964  return NULL;
965  }
966  cuddRef( zPlus );
967  Cudd_RecursiveDeref( dd, bVarsExtra );
968 
969  // add these to the result
970  zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
971  if ( zRes == NULL )
972  {
973  Cudd_RecursiveDerefZdd( dd, zTemp );
974  Cudd_RecursiveDerefZdd( dd, zPlus );
975  return NULL;
976  }
977  cuddRef( zRes );
978  Cudd_RecursiveDerefZdd( dd, zTemp );
979  Cudd_RecursiveDerefZdd( dd, zPlus );
980  }
981  cuddDeref( zRes );
982 
983  cuddCacheInsert( dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars, zRes );
984  return zRes;
985  }
986 } /* end of extraZddGetSymmetricVars */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
DdNode * cuddCacheLookupZdd(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:435
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
#define z1
Definition: extraBdd.h:78
#define Cudd_Not(node)
Definition: cudd.h:367
#define b1
Definition: extraBdd.h:76
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode * extraZddGetSingletons(DdManager *dd, DdNode *bVars)
DdNode * extraZddGetSymmetricVars(DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
Definition: extraBddSymm.c:804
#define z0
Definition: extraBdd.h:77
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:642
#define cuddIsConstant(node)
Definition: cuddInt.h:620
static int size
Definition: cuddSign.c:86
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
#define DD_GET_SYMM_VARS_TAG
Definition: extraBddSymm.c:47
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:553
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
int * perm
Definition: cuddInt.h:386
DdNode* extraZddSelectOneSubset ( DdManager dd,
DdNode zS 
)

Function********************************************************************

Synopsis [Performs the recursive step of Extra_zddSelectOneSubset.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1419 of file extraBddSymm.c.

1424 {
1425  DdNode * zRes;
1426 
1427  if ( zS == z0 ) return z0;
1428  if ( zS == z1 ) return z1;
1429 
1430  // check cache
1431  if ( (zRes = cuddCacheLookup1Zdd( dd, extraZddSelectOneSubset, zS )) )
1432  return zRes;
1433  else
1434  {
1435  DdNode * zS0, * zS1, * zTemp;
1436 
1437  zS0 = cuddE(zS);
1438  zS1 = cuddT(zS);
1439 
1440  if ( zS0 != z0 )
1441  {
1442  zRes = extraZddSelectOneSubset( dd, zS0 );
1443  if ( zRes == NULL )
1444  return NULL;
1445  }
1446  else // if ( zS0 == z0 )
1447  {
1448  assert( zS1 != z0 );
1449  zRes = extraZddSelectOneSubset( dd, zS1 );
1450  if ( zRes == NULL )
1451  return NULL;
1452  cuddRef( zRes );
1453 
1454  zRes = cuddZddGetNode( dd, zS->index, zTemp = zRes, z0 );
1455  if ( zRes == NULL )
1456  {
1457  Cudd_RecursiveDerefZdd( dd, zTemp );
1458  return NULL;
1459  }
1460  cuddDeref( zTemp );
1461  }
1462 
1463  // insert the result into cache
1464  cuddCacheInsert1( dd, extraZddSelectOneSubset, zS, zRes );
1465  return zRes;
1466  }
1467 } /* end of extraZddSelectOneSubset */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
#define z1
Definition: extraBdd.h:78
#define z0
Definition: extraBdd.h:77
DdNode * extraZddSelectOneSubset(DdManager *dd, DdNode *zS)
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
DdNode * cuddCacheLookup1Zdd(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:664
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode* extraZddSymmPairsCompute ( DdManager dd,
DdNode bFunc,
DdNode bVars 
)

Function********************************************************************

Synopsis [Performs a recursive step of Extra_SymmPairsCompute.]

Description [Returns the set of symmetric variable pairs represented as a set of two-literal ZDD cubes. Both variables always appear in the positive polarity in the cubes. This function works without building new BDD nodes. Some relatively small number of ZDD nodes may be built to ensure proper bookkeeping of the symmetry information.]

SideEffects []

SeeAlso []

Definition at line 580 of file extraBddSymm.c.

584 {
585  DdNode * zRes;
586  DdNode * bFR = Cudd_Regular(bFunc);
587 
588  if ( cuddIsConstant(bFR) )
589  {
590  int nVars, i;
591 
592  // determine how many vars are in the bVars
593  nVars = Extra_bddSuppSize( dd, bVars );
594  if ( nVars < 2 )
595  return z0;
596  else
597  {
598  DdNode * bVarsK;
599 
600  // create the BDD bVarsK corresponding to K = 2;
601  bVarsK = bVars;
602  for ( i = 0; i < nVars-2; i++ )
603  bVarsK = cuddT( bVarsK );
604  return extraZddTuplesFromBdd( dd, bVarsK, bVars );
605  }
606  }
607  assert( bVars != b1 );
608 
609  if ( (zRes = cuddCacheLookup2Zdd(dd, extraZddSymmPairsCompute, bFunc, bVars)) )
610  return zRes;
611  else
612  {
613  DdNode * zRes0, * zRes1;
614  DdNode * zTemp, * zPlus, * zSymmVars;
615  DdNode * bF0, * bF1;
616  DdNode * bVarsNew;
617  int nVarsExtra;
618  int LevelF;
619 
620  // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
621  // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
622  // count how many extra vars are there in bVars
623  nVarsExtra = 0;
624  LevelF = dd->perm[bFR->index];
625  for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
626  nVarsExtra++;
627  // the indexes (level) of variables should be synchronized now
628  assert( bFR->index == bVarsNew->index );
629 
630  // cofactor the function
631  if ( bFR != bFunc ) // bFunc is complemented
632  {
633  bF0 = Cudd_Not( cuddE(bFR) );
634  bF1 = Cudd_Not( cuddT(bFR) );
635  }
636  else
637  {
638  bF0 = cuddE(bFR);
639  bF1 = cuddT(bFR);
640  }
641 
642  // solve subproblems
643  zRes0 = extraZddSymmPairsCompute( dd, bF0, cuddT(bVarsNew) );
644  if ( zRes0 == NULL )
645  return NULL;
646  cuddRef( zRes0 );
647 
648  // if there is no symmetries in the negative cofactor
649  // there is no need to test the positive cofactor
650  if ( zRes0 == z0 )
651  zRes = zRes0; // zRes takes reference
652  else
653  {
654  zRes1 = extraZddSymmPairsCompute( dd, bF1, cuddT(bVarsNew) );
655  if ( zRes1 == NULL )
656  {
657  Cudd_RecursiveDerefZdd( dd, zRes0 );
658  return NULL;
659  }
660  cuddRef( zRes1 );
661 
662  // only those variables are pair-wise symmetric
663  // that are pair-wise symmetric in both cofactors
664  // therefore, intersect the solutions
665  zRes = cuddZddIntersect( dd, zRes0, zRes1 );
666  if ( zRes == NULL )
667  {
668  Cudd_RecursiveDerefZdd( dd, zRes0 );
669  Cudd_RecursiveDerefZdd( dd, zRes1 );
670  return NULL;
671  }
672  cuddRef( zRes );
673  Cudd_RecursiveDerefZdd( dd, zRes0 );
674  Cudd_RecursiveDerefZdd( dd, zRes1 );
675  }
676 
677  // consider the current top-most variable and find all the vars
678  // that are pairwise symmetric with it
679  // these variables are returned as a set of ZDD singletons
680  zSymmVars = extraZddGetSymmetricVars( dd, bF1, bF0, cuddT(bVarsNew) );
681  if ( zSymmVars == NULL )
682  {
683  Cudd_RecursiveDerefZdd( dd, zRes );
684  return NULL;
685  }
686  cuddRef( zSymmVars );
687 
688  // attach the topmost variable to the set, to get the variable pairs
689  // use the positive polarity ZDD variable for the purpose
690 
691  // there is no need to do so, if zSymmVars is empty
692  if ( zSymmVars == z0 )
693  Cudd_RecursiveDerefZdd( dd, zSymmVars );
694  else
695  {
696  zPlus = cuddZddGetNode( dd, 2*bFR->index, zSymmVars, z0 );
697  if ( zPlus == NULL )
698  {
699  Cudd_RecursiveDerefZdd( dd, zRes );
700  Cudd_RecursiveDerefZdd( dd, zSymmVars );
701  return NULL;
702  }
703  cuddRef( zPlus );
704  cuddDeref( zSymmVars );
705 
706  // add these variable pairs to the result
707  zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
708  if ( zRes == NULL )
709  {
710  Cudd_RecursiveDerefZdd( dd, zTemp );
711  Cudd_RecursiveDerefZdd( dd, zPlus );
712  return NULL;
713  }
714  cuddRef( zRes );
715  Cudd_RecursiveDerefZdd( dd, zTemp );
716  Cudd_RecursiveDerefZdd( dd, zPlus );
717  }
718 
719  // only zRes is referenced at this point
720 
721  // if we skipped some variables, these variables cannot be symmetric with
722  // any variables that are currently in the support of bF, but they can be
723  // symmetric with the variables that are in bVars but not in the support of bF
724  if ( nVarsExtra )
725  {
726  // it is possible to improve this step:
727  // (1) there is no need to enter here, if nVarsExtra < 2
728 
729  // create the set of topmost nVarsExtra in bVars
730  DdNode * bVarsExtra;
731  int nVars;
732 
733  // remove from bVars all the variable that are in the support of bFunc
734  bVarsExtra = extraBddReduceVarSet( dd, bVars, bFunc );
735  if ( bVarsExtra == NULL )
736  {
737  Cudd_RecursiveDerefZdd( dd, zRes );
738  return NULL;
739  }
740  cuddRef( bVarsExtra );
741 
742  // determine how many vars are in the bVarsExtra
743  nVars = Extra_bddSuppSize( dd, bVarsExtra );
744  if ( nVars < 2 )
745  {
746  Cudd_RecursiveDeref( dd, bVarsExtra );
747  }
748  else
749  {
750  int i;
751  DdNode * bVarsK;
752 
753  // create the BDD bVarsK corresponding to K = 2;
754  bVarsK = bVarsExtra;
755  for ( i = 0; i < nVars-2; i++ )
756  bVarsK = cuddT( bVarsK );
757 
758  // create the 2 variable tuples
759  zPlus = extraZddTuplesFromBdd( dd, bVarsK, bVarsExtra );
760  if ( zPlus == NULL )
761  {
762  Cudd_RecursiveDeref( dd, bVarsExtra );
763  Cudd_RecursiveDerefZdd( dd, zRes );
764  return NULL;
765  }
766  cuddRef( zPlus );
767  Cudd_RecursiveDeref( dd, bVarsExtra );
768 
769  // add these to the result
770  zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
771  if ( zRes == NULL )
772  {
773  Cudd_RecursiveDerefZdd( dd, zTemp );
774  Cudd_RecursiveDerefZdd( dd, zPlus );
775  return NULL;
776  }
777  cuddRef( zRes );
778  Cudd_RecursiveDerefZdd( dd, zTemp );
779  Cudd_RecursiveDerefZdd( dd, zPlus );
780  }
781  }
782  cuddDeref( zRes );
783 
784 
785  /* insert the result into cache */
786  cuddCacheInsert2(dd, extraZddSymmPairsCompute, bFunc, bVars, zRes);
787  return zRes;
788  }
789 } /* end of extraZddSymmPairsCompute */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
DdNode * extraZddSymmPairsCompute(DdManager *dd, DdNode *bFunc, DdNode *bVars)
Definition: extraBddSymm.c:580
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
Definition: extraBddMisc.c:321
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define b1
Definition: extraBdd.h:76
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * extraBddReduceVarSet(DdManager *dd, DdNode *bVars, DdNode *bF)
DdNode * extraZddGetSymmetricVars(DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
Definition: extraBddSymm.c:804
#define z0
Definition: extraBdd.h:77
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:642
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:553
DdNode * extraZddTuplesFromBdd(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
int * perm
Definition: cuddInt.h:386
DdNode* extraZddTuplesFromBdd ( DdManager dd,
DdNode bVarsK,
DdNode bVarsN 
)

Function********************************************************************

Synopsis [Performs the reordering-sensitive step of Extra_zddTupleFromBdd().]

Description [Generates in a bottom-up fashion ZDD for all combinations composed of k variables out of variables belonging to Support.]

SideEffects []

SeeAlso []

Definition at line 1341 of file extraBddSymm.c.

1345 {
1346  DdNode *zRes, *zRes0, *zRes1;
1347  statLine(dd);
1348 
1349  /* terminal cases */
1350 /* if ( k < 0 || k > n )
1351  * return dd->zero;
1352  * if ( n == 0 )
1353  * return dd->one;
1354  */
1355  if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
1356  return z0;
1357  if ( bVarsN == b1 )
1358  return z1;
1359 
1360  /* check cache */
1361  zRes = cuddCacheLookup2Zdd(dd, extraZddTuplesFromBdd, bVarsK, bVarsN);
1362  if (zRes)
1363  return(zRes);
1364 
1365  /* ZDD in which this variable is 0 */
1366 /* zRes0 = extraZddTuplesFromBdd( dd, k, n-1 ); */
1367  zRes0 = extraZddTuplesFromBdd( dd, bVarsK, cuddT(bVarsN) );
1368  if ( zRes0 == NULL )
1369  return NULL;
1370  cuddRef( zRes0 );
1371 
1372  /* ZDD in which this variable is 1 */
1373 /* zRes1 = extraZddTuplesFromBdd( dd, k-1, n-1 ); */
1374  if ( bVarsK == b1 )
1375  {
1376  zRes1 = z0;
1377  cuddRef( zRes1 );
1378  }
1379  else
1380  {
1381  zRes1 = extraZddTuplesFromBdd( dd, cuddT(bVarsK), cuddT(bVarsN) );
1382  if ( zRes1 == NULL )
1383  {
1384  Cudd_RecursiveDerefZdd( dd, zRes0 );
1385  return NULL;
1386  }
1387  cuddRef( zRes1 );
1388  }
1389 
1390  /* compose Res0 and Res1 with the given ZDD variable */
1391  zRes = cuddZddGetNode( dd, 2*bVarsN->index, zRes1, zRes0 );
1392  if ( zRes == NULL )
1393  {
1394  Cudd_RecursiveDerefZdd( dd, zRes0 );
1395  Cudd_RecursiveDerefZdd( dd, zRes1 );
1396  return NULL;
1397  }
1398  cuddDeref( zRes0 );
1399  cuddDeref( zRes1 );
1400 
1401  /* insert the result into cache */
1402  cuddCacheInsert2(dd, extraZddTuplesFromBdd, bVarsK, bVarsN, zRes);
1403  return zRes;
1404 
1405 } /* end of extraZddTuplesFromBdd */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
#define z1
Definition: extraBdd.h:78
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define b1
Definition: extraBdd.h:76
#define statLine(dd)
Definition: cuddInt.h:1037
#define z0
Definition: extraBdd.h:77
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdNode * extraZddTuplesFromBdd(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
DdHalfWord index
Definition: cudd.h:279