00001
00019 #include "dsdInt.h"
00020
00024
00028
00029 static DdNode * Extra_dsdRemap( DdManager * dd, DdNode * bFunc, st_table * pCache,
00030 int * pVar2Form, int * pForm2Var, DdNode * pbCube0[], DdNode * pbCube1[] );
00031 static DdNode * Extra_bddNodePointedByCube( DdManager * dd, DdNode * bF, DdNode * bC );
00032
00036
00051 DdNode * Dsd_TreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode )
00052 {
00053 int * pForm2Var;
00054 int * pVar2Form;
00055 int i, iVar, iLev, * pPermute;
00056 DdNode ** pbCube0, ** pbCube1;
00057 DdNode * bFunc, * bRes, * bTemp;
00058 st_table * pCache;
00059
00060 pPermute = ALLOC( int, dd->size );
00061 pVar2Form = ALLOC( int, dd->size );
00062 pForm2Var = ALLOC( int, dd->size );
00063
00064 pbCube0 = ALLOC( DdNode *, dd->size );
00065 pbCube1 = ALLOC( DdNode *, dd->size );
00066
00067
00068
00069 iLev = 0;
00070 for ( i = 0; i < pNode->nDecs; i++ )
00071 {
00072 pForm2Var[i] = dd->invperm[i];
00073 for ( bTemp = pNode->pDecs[i]->S; bTemp != b1; bTemp = cuddT(bTemp) )
00074 {
00075 iVar = dd->invperm[iLev];
00076 pPermute[bTemp->index] = iVar;
00077 pVar2Form[iVar] = i;
00078 iLev++;
00079 }
00080
00081
00082 pbCube0[i] = Extra_bddGetOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) );
00083 Cudd_Ref( pbCube0[i] );
00084 pbCube1[i] = Extra_bddGetOneCube( dd, pNode->pDecs[i]->G );
00085 Cudd_Ref( pbCube1[i] );
00086 }
00087
00088
00089 bFunc = Cudd_bddPermute( dd, pNode->G, pPermute ); Cudd_Ref( bFunc );
00090
00091 for ( i = 0; i < pNode->nDecs; i++ )
00092 {
00093 pbCube0[i] = Cudd_bddPermute( dd, bTemp = pbCube0[i], pPermute ); Cudd_Ref( pbCube0[i] );
00094 Cudd_RecursiveDeref( dd, bTemp );
00095 pbCube1[i] = Cudd_bddPermute( dd, bTemp = pbCube1[i], pPermute ); Cudd_Ref( pbCube1[i] );
00096 Cudd_RecursiveDeref( dd, bTemp );
00097 }
00098
00099
00100 pCache = st_init_table(st_ptrcmp,st_ptrhash);
00101 bRes = Extra_dsdRemap( dd, bFunc, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes );
00102 st_free_table( pCache );
00103
00104 Cudd_RecursiveDeref( dd, bFunc );
00105 for ( i = 0; i < pNode->nDecs; i++ )
00106 {
00107 Cudd_RecursiveDeref( dd, pbCube0[i] );
00108 Cudd_RecursiveDeref( dd, pbCube1[i] );
00109 }
00110
00112
00113
00114
00115
00116
00117
00118
00119
00121
00122 FREE(pPermute);
00123 FREE(pVar2Form);
00124 FREE(pForm2Var);
00125 FREE(pbCube0);
00126 FREE(pbCube1);
00127
00128 Cudd_Deref( bRes );
00129 return bRes;
00130 }
00131
00143 DdNode * Extra_dsdRemap( DdManager * dd, DdNode * bF, st_table * pCache,
00144 int * pVar2Form, int * pForm2Var, DdNode * pbCube0[], DdNode * pbCube1[] )
00145 {
00146 DdNode * bFR, * bF0, * bF1;
00147 DdNode * bRes0, * bRes1, * bRes;
00148 int iForm;
00149
00150 bFR = Cudd_Regular(bF);
00151 if ( cuddIsConstant(bFR) )
00152 return bF;
00153
00154
00155 if ( bFR->ref != 1 )
00156 {
00157 if ( st_lookup( pCache, (char *)bF, (char **)&bRes ) )
00158 return bRes;
00159 }
00160
00161
00162 iForm = pVar2Form[bFR->index];
00163
00164
00165 bF0 = Extra_bddNodePointedByCube( dd, bF, pbCube0[iForm] );
00166 bF1 = Extra_bddNodePointedByCube( dd, bF, pbCube1[iForm] );
00167
00168
00169 bRes0 = Extra_dsdRemap( dd, bF0, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes0 );
00170 bRes1 = Extra_dsdRemap( dd, bF1, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes1 );
00171
00172
00173 bRes = Cudd_bddIte( dd, dd->vars[ pForm2Var[iForm] ], bRes1, bRes0 ); Cudd_Ref( bRes );
00174 Cudd_RecursiveDeref( dd, bRes0 );
00175 Cudd_RecursiveDeref( dd, bRes1 );
00176
00177
00178 if ( bFR->ref != 1 )
00179 st_insert( pCache, (char *)bF, (char *)bRes );
00180 Cudd_Deref( bRes );
00181 return bRes;
00182 }
00183
00195 DdNode * Extra_bddNodePointedByCube( DdManager * dd, DdNode * bF, DdNode * bC )
00196 {
00197 DdNode * bFR, * bCR;
00198 DdNode * bF0, * bF1;
00199 DdNode * bC0, * bC1;
00200 int LevelF, LevelC;
00201
00202 assert( bC != b0 );
00203 if ( bC == b1 )
00204 return bF;
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 bFR = Cudd_Regular( bF );
00215 bCR = Cudd_Regular( bC );
00216 assert( !cuddIsConstant( bFR ) );
00217
00218 LevelF = dd->perm[bFR->index];
00219 LevelC = dd->perm[bCR->index];
00220
00221 if ( LevelF <= LevelC )
00222 {
00223 if ( bFR != bF )
00224 {
00225 bF0 = Cudd_Not( cuddE(bFR) );
00226 bF1 = Cudd_Not( cuddT(bFR) );
00227 }
00228 else
00229 {
00230 bF0 = cuddE(bFR);
00231 bF1 = cuddT(bFR);
00232 }
00233 }
00234 else
00235 {
00236 bF0 = bF1 = bF;
00237 }
00238
00239 if ( LevelC <= LevelF )
00240 {
00241 if ( bCR != bC )
00242 {
00243 bC0 = Cudd_Not( cuddE(bCR) );
00244 bC1 = Cudd_Not( cuddT(bCR) );
00245 }
00246 else
00247 {
00248 bC0 = cuddE(bCR);
00249 bC1 = cuddT(bCR);
00250 }
00251 }
00252 else
00253 {
00254 bC0 = bC1 = bC;
00255 }
00256
00257 assert( bC0 == b0 || bC1 == b0 );
00258 if ( bC0 == b0 )
00259 return Extra_bddNodePointedByCube( dd, bF1, bC1 );
00260 return Extra_bddNodePointedByCube( dd, bF0, bC0 );
00261 }
00262
00263 #if 0
00264
00276 DdNode * dsdTreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode, int fRemap )
00277 {
00278 DdNode * bCof0, * bCof1, * bCube0, * bCube1, * bNewFunc, * bTemp;
00279 int i;
00280 int fAllBuffs = 1;
00281 static int Permute[MAXINPUTS];
00282
00283 assert( pNode );
00284 assert( !Dsd_IsComplement( pNode ) );
00285 assert( pNode->Type == DT_PRIME );
00286
00287
00288
00289
00290
00291
00292
00293
00294 bNewFunc = pNode->G; Cudd_Ref( bNewFunc );
00295
00296 for ( i = 0; i < pNode->nDecs; i++ )
00297 if ( pNode->pDecs[i]->Type != DT_BUF )
00298 {
00299 bCube0 = Extra_bddFindOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) ); Cudd_Ref( bCube0 );
00300 bCof0 = Cudd_Cofactor( dd, bNewFunc, bCube0 ); Cudd_Ref( bCof0 );
00301 Cudd_RecursiveDeref( dd, bCube0 );
00302
00303 bCube1 = Extra_bddFindOneCube( dd, pNode->pDecs[i]->G ); Cudd_Ref( bCube1 );
00304 bCof1 = Cudd_Cofactor( dd, bNewFunc, bCube1 ); Cudd_Ref( bCof1 );
00305 Cudd_RecursiveDeref( dd, bCube1 );
00306
00307 Cudd_RecursiveDeref( dd, bNewFunc );
00308
00309
00310
00311
00312 bNewFunc = Cudd_bddIte( dd, dd->vars[pNode->pDecs[i]->S->index],bCof1,bCof0 ); Cudd_Ref( bNewFunc );
00313 Cudd_RecursiveDeref( dd, bCof0 );
00314 Cudd_RecursiveDeref( dd, bCof1 );
00315 }
00316
00317 if ( fRemap )
00318 {
00319
00320
00321 for ( i = 0; i < pNode->nDecs; i++ )
00322
00323 Permute[ pNode->pDecs[i]->S->index ] = i;
00324
00325 bNewFunc = Cudd_bddPermute( dd, bTemp = bNewFunc, Permute ); Cudd_Ref( bNewFunc );
00326 Cudd_RecursiveDeref( dd, bTemp );
00327 }
00328
00329 Cudd_Deref( bNewFunc );
00330 return bNewFunc;
00331 }
00332
00333 #endif
00334