[8] | 1 | /**CFile*********************************************************************** |
---|
| 2 | |
---|
| 3 | FileName [calReduce.c] |
---|
| 4 | |
---|
| 5 | PackageName [cal] |
---|
| 6 | |
---|
| 7 | Synopsis [Routines for optimizing a BDD with respect to a don't |
---|
| 8 | care set (cofactor and restrict).] |
---|
| 9 | |
---|
| 10 | Description [] |
---|
| 11 | |
---|
| 12 | SeeAlso [None] |
---|
| 13 | |
---|
| 14 | Author [Rajeev K. Ranjan (rajeev@eecs.berkeley.edu) and |
---|
| 15 | Jagesh V. Sanghavi (sanghavi@eecs.berkeley.edu] |
---|
| 16 | |
---|
| 17 | Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. |
---|
| 18 | All rights reserved. |
---|
| 19 | |
---|
| 20 | Permission is hereby granted, without written agreement and without license |
---|
| 21 | or royalty fees, to use, copy, modify, and distribute this software and its |
---|
| 22 | documentation for any purpose, provided that the above copyright notice and |
---|
| 23 | the following two paragraphs appear in all copies of this software. |
---|
| 24 | |
---|
| 25 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
---|
| 26 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
---|
| 27 | OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
---|
| 28 | CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 29 | |
---|
| 30 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
---|
| 31 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
---|
| 32 | FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN |
---|
| 33 | "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE |
---|
| 34 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] |
---|
| 35 | |
---|
| 36 | Revision [$Id: calReduce.c,v 1.3 2002/09/21 20:39:25 fabio Exp $] |
---|
| 37 | |
---|
| 38 | ******************************************************************************/ |
---|
| 39 | |
---|
| 40 | #include "calInt.h" |
---|
| 41 | |
---|
| 42 | /*---------------------------------------------------------------------------*/ |
---|
| 43 | /* Constant declarations */ |
---|
| 44 | /*---------------------------------------------------------------------------*/ |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | /*---------------------------------------------------------------------------*/ |
---|
| 48 | /* Type declarations */ |
---|
| 49 | /*---------------------------------------------------------------------------*/ |
---|
| 50 | |
---|
| 51 | |
---|
| 52 | /*---------------------------------------------------------------------------*/ |
---|
| 53 | /* Stucture declarations */ |
---|
| 54 | /*---------------------------------------------------------------------------*/ |
---|
| 55 | |
---|
| 56 | |
---|
| 57 | /*---------------------------------------------------------------------------*/ |
---|
| 58 | /* Variable declarations */ |
---|
| 59 | /*---------------------------------------------------------------------------*/ |
---|
| 60 | |
---|
| 61 | |
---|
| 62 | /*---------------------------------------------------------------------------*/ |
---|
| 63 | /* Macro declarations */ |
---|
| 64 | /*---------------------------------------------------------------------------*/ |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | /**AutomaticStart*************************************************************/ |
---|
| 68 | |
---|
| 69 | /*---------------------------------------------------------------------------*/ |
---|
| 70 | /* Static function prototypes */ |
---|
| 71 | /*---------------------------------------------------------------------------*/ |
---|
| 72 | |
---|
| 73 | static Cal_Bdd_t BddReduceBF(Cal_BddManager_t * bddManager, CalOpProc_t calOpProc, Cal_Bdd_t f, Cal_Bdd_t c); |
---|
| 74 | static Cal_Bdd_t BddCofactorBF(Cal_BddManager_t * bddManager, CalOpProc_t calOpProc, Cal_Bdd_t f, Cal_Bdd_t c); |
---|
| 75 | static void HashTableReduceApply(Cal_BddManager_t * bddManager, CalHashTable_t * hashTable, CalHashTable_t ** reduceHashTableArray, CalHashTable_t ** orHashTableArray, CalOpProc_t calOpProc); |
---|
| 76 | static void HashTableCofactorApply(Cal_BddManager_t * bddManager, CalHashTable_t * hashTable, CalHashTable_t ** cofactorHashTableArray, CalOpProc_t calOpProc); |
---|
| 77 | static void HashTableCofactorReduce(Cal_BddManager_t * bddManager, CalHashTable_t * hashTable, CalHashTable_t * uniqueTableForId); |
---|
| 78 | |
---|
| 79 | /**AutomaticEnd***************************************************************/ |
---|
| 80 | |
---|
| 81 | |
---|
| 82 | /*---------------------------------------------------------------------------*/ |
---|
| 83 | /* Definition of exported functions */ |
---|
| 84 | /*---------------------------------------------------------------------------*/ |
---|
| 85 | /**Function******************************************************************** |
---|
| 86 | |
---|
| 87 | Synopsis [Returns the generalized cofactor of BDD f with respect |
---|
| 88 | to BDD c.] |
---|
| 89 | |
---|
| 90 | Description [Returns the generalized cofactor of BDD f with respect |
---|
| 91 | to BDD c. The constrain operator given by Coudert et al (ICCAD90) is |
---|
| 92 | used to find the generalized cofactor.] |
---|
| 93 | |
---|
| 94 | SideEffects [None.] |
---|
| 95 | |
---|
| 96 | SeeAlso [Cal_BddReduce] |
---|
| 97 | |
---|
| 98 | ******************************************************************************/ |
---|
| 99 | Cal_Bdd |
---|
| 100 | Cal_BddCofactor(Cal_BddManager bddManager, Cal_Bdd fUserBdd, |
---|
| 101 | Cal_Bdd cUserBdd) |
---|
| 102 | { |
---|
| 103 | Cal_Bdd_t result; |
---|
| 104 | Cal_Bdd userResult; |
---|
| 105 | if (CalBddPreProcessing(bddManager, 2, fUserBdd, cUserBdd)){ |
---|
| 106 | Cal_Bdd_t f = CalBddGetInternalBdd(bddManager, fUserBdd); |
---|
| 107 | Cal_Bdd_t c = CalBddGetInternalBdd(bddManager, cUserBdd); |
---|
| 108 | result = BddCofactorBF(bddManager, CalOpCofactor, f, c); |
---|
| 109 | userResult = CalBddGetExternalBdd(bddManager, result); |
---|
| 110 | if (CalBddPostProcessing(bddManager) == CAL_BDD_OVERFLOWED){ |
---|
| 111 | Cal_BddFree(bddManager, userResult); |
---|
| 112 | Cal_BddManagerGC(bddManager); |
---|
| 113 | return (Cal_Bdd) 0; |
---|
| 114 | } |
---|
| 115 | return userResult; |
---|
| 116 | } |
---|
| 117 | return (Cal_Bdd) 0; |
---|
| 118 | } |
---|
| 119 | |
---|
| 120 | |
---|
| 121 | /**Function******************************************************************** |
---|
| 122 | |
---|
| 123 | Synopsis [Returns a BDD which agrees with f for all valuations |
---|
| 124 | which satisfy c.] |
---|
| 125 | |
---|
| 126 | Description [Returns a BDD which agrees with f for all valuations |
---|
| 127 | which satisfy c. The result is usually smaller in terms of number of |
---|
| 128 | BDD nodes than f. This operation is typically used in state space |
---|
| 129 | searches to simplify the representation for the set of states wich |
---|
| 130 | will be expanded at each step.] |
---|
| 131 | |
---|
| 132 | SideEffects [None] |
---|
| 133 | |
---|
| 134 | SeeAlso [Cal_BddCofactor] |
---|
| 135 | |
---|
| 136 | ******************************************************************************/ |
---|
| 137 | Cal_Bdd |
---|
| 138 | Cal_BddReduce(Cal_BddManager bddManager, Cal_Bdd fUserBdd, |
---|
| 139 | Cal_Bdd cUserBdd) |
---|
| 140 | { |
---|
| 141 | if (CalBddPreProcessing(bddManager, 2, fUserBdd, cUserBdd)){ |
---|
| 142 | Cal_Bdd_t f = CalBddGetInternalBdd(bddManager, fUserBdd); |
---|
| 143 | Cal_Bdd_t c = CalBddGetInternalBdd(bddManager, cUserBdd); |
---|
| 144 | Cal_Bdd_t result; |
---|
| 145 | Cal_Bdd userResult; |
---|
| 146 | |
---|
| 147 | result = BddReduceBF(bddManager, CalOpCofactor, f, c); |
---|
| 148 | userResult = CalBddGetExternalBdd(bddManager, result); |
---|
| 149 | |
---|
| 150 | if (CalBddPostProcessing(bddManager) == CAL_BDD_OVERFLOWED){ |
---|
| 151 | Cal_BddFree(bddManager, userResult); |
---|
| 152 | Cal_BddManagerGC(bddManager); |
---|
| 153 | return (Cal_Bdd) 0; |
---|
| 154 | } |
---|
| 155 | if (Cal_BddSize(bddManager, userResult, 1) < |
---|
| 156 | Cal_BddSize(bddManager, fUserBdd, 1)){ |
---|
| 157 | return userResult; |
---|
| 158 | } |
---|
| 159 | else{ |
---|
| 160 | Cal_BddFree(bddManager, userResult); |
---|
| 161 | return Cal_BddIdentity(bddManager, fUserBdd); |
---|
| 162 | } |
---|
| 163 | } |
---|
| 164 | return (Cal_Bdd) 0; |
---|
| 165 | } |
---|
| 166 | |
---|
| 167 | |
---|
| 168 | /**Function******************************************************************** |
---|
| 169 | |
---|
| 170 | Synopsis [Returns a minimal BDD whose function contains fMin and is |
---|
| 171 | contained in fMax.] |
---|
| 172 | |
---|
| 173 | Description [Returns a minimal BDD f which is contains fMin and is |
---|
| 174 | contained in fMax ( fMin <= f <= fMax). |
---|
| 175 | This operation is typically used in state space searches to simplify |
---|
| 176 | the representation for the set of states wich will be expanded at |
---|
| 177 | each step (Rk Rk-1' <= f <= Rk).] |
---|
| 178 | |
---|
| 179 | SideEffects [None] |
---|
| 180 | |
---|
| 181 | SeeAlso [Cal_BddReduce] |
---|
| 182 | |
---|
| 183 | ******************************************************************************/ |
---|
| 184 | Cal_Bdd |
---|
| 185 | Cal_BddBetween(Cal_BddManager bddManager, Cal_Bdd fMinUserBdd, |
---|
| 186 | Cal_Bdd fMaxUserBdd) |
---|
| 187 | { |
---|
| 188 | if (CalBddPreProcessing(bddManager, 2, fMinUserBdd, fMaxUserBdd)){ |
---|
| 189 | Cal_Bdd_t fMin = CalBddGetInternalBdd(bddManager, fMinUserBdd); |
---|
| 190 | Cal_Bdd_t fMax = CalBddGetInternalBdd(bddManager, fMaxUserBdd); |
---|
| 191 | Cal_Bdd_t fMaxNot, careSet, result; |
---|
| 192 | Cal_Bdd resultUserBdd; |
---|
| 193 | long fMinSize, fMaxSize, resultSize; |
---|
| 194 | |
---|
| 195 | CalBddNot(fMax, fMaxNot); |
---|
| 196 | careSet = CalBddOpBF(bddManager, CalOpOr, fMin, fMaxNot); |
---|
| 197 | result = BddReduceBF(bddManager, CalOpCofactor, fMin, careSet); |
---|
| 198 | resultUserBdd = CalBddGetExternalBdd(bddManager, result); |
---|
| 199 | if (CalBddPostProcessing(bddManager) == CAL_BDD_OVERFLOWED){ |
---|
| 200 | Cal_BddFree(bddManager, resultUserBdd); |
---|
| 201 | Cal_BddManagerGC(bddManager); |
---|
| 202 | return (Cal_Bdd) 0; |
---|
| 203 | } |
---|
| 204 | fMinSize = Cal_BddSize(bddManager, fMinUserBdd, 1); |
---|
| 205 | fMaxSize = Cal_BddSize(bddManager, fMaxUserBdd, 1); |
---|
| 206 | resultSize = Cal_BddSize(bddManager, resultUserBdd, 1); |
---|
| 207 | if (resultSize < fMinSize){ |
---|
| 208 | if (resultSize < fMaxSize){ |
---|
| 209 | return resultUserBdd; |
---|
| 210 | } |
---|
| 211 | else { |
---|
| 212 | Cal_BddFree(bddManager, resultUserBdd); |
---|
| 213 | return Cal_BddIdentity(bddManager, fMaxUserBdd); |
---|
| 214 | } |
---|
| 215 | } |
---|
| 216 | Cal_BddFree(bddManager, resultUserBdd); |
---|
| 217 | if (fMinSize < fMaxSize){ |
---|
| 218 | return Cal_BddIdentity(bddManager, fMinUserBdd); |
---|
| 219 | } |
---|
| 220 | else{ |
---|
| 221 | return Cal_BddIdentity(bddManager, fMaxUserBdd); |
---|
| 222 | } |
---|
| 223 | } |
---|
| 224 | return (Cal_Bdd) 0; |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | |
---|
| 228 | /*---------------------------------------------------------------------------*/ |
---|
| 229 | /* Definition of internal functions */ |
---|
| 230 | /*---------------------------------------------------------------------------*/ |
---|
| 231 | /**Function******************************************************************** |
---|
| 232 | |
---|
| 233 | Synopsis [required] |
---|
| 234 | |
---|
| 235 | Description [optional] |
---|
| 236 | |
---|
| 237 | SideEffects [required] |
---|
| 238 | |
---|
| 239 | SeeAlso [optional] |
---|
| 240 | |
---|
| 241 | ******************************************************************************/ |
---|
| 242 | int |
---|
| 243 | CalOpCofactor( |
---|
| 244 | Cal_BddManager_t * bddManager, |
---|
| 245 | Cal_Bdd_t f, |
---|
| 246 | Cal_Bdd_t c, |
---|
| 247 | Cal_Bdd_t * resultBddPtr) |
---|
| 248 | { |
---|
| 249 | if (CalBddIsBddConst(c)){ |
---|
| 250 | if (CalBddIsBddZero(bddManager, c)){ |
---|
| 251 | *resultBddPtr = bddManager->bddNull; |
---|
| 252 | } |
---|
| 253 | else { |
---|
| 254 | *resultBddPtr = f; |
---|
| 255 | } |
---|
| 256 | return 1; |
---|
| 257 | } |
---|
| 258 | if (CalBddIsBddConst(f)){ |
---|
| 259 | *resultBddPtr = f; |
---|
| 260 | return 1; |
---|
| 261 | } |
---|
| 262 | return 0; |
---|
| 263 | } |
---|
| 264 | |
---|
| 265 | /*---------------------------------------------------------------------------*/ |
---|
| 266 | /* Definition of static functions */ |
---|
| 267 | /*---------------------------------------------------------------------------*/ |
---|
| 268 | /**Function******************************************************************** |
---|
| 269 | |
---|
| 270 | Synopsis [required] |
---|
| 271 | |
---|
| 272 | Description [optional] |
---|
| 273 | |
---|
| 274 | SideEffects [required] |
---|
| 275 | |
---|
| 276 | SeeAlso [optional] |
---|
| 277 | |
---|
| 278 | ******************************************************************************/ |
---|
| 279 | static Cal_Bdd_t |
---|
| 280 | BddReduceBF( |
---|
| 281 | Cal_BddManager_t * bddManager, |
---|
| 282 | CalOpProc_t calOpProc, |
---|
| 283 | Cal_Bdd_t f, |
---|
| 284 | Cal_Bdd_t c) |
---|
| 285 | { |
---|
| 286 | Cal_Bdd_t result; |
---|
| 287 | CalHashTable_t *hashTable; |
---|
| 288 | CalHashTable_t **orHashTableArray = bddManager->reqQue[0]; |
---|
| 289 | CalHashTable_t **reduceHashTableArray = bddManager->reqQue[1]; |
---|
| 290 | CalHashTable_t *uniqueTableForId; |
---|
| 291 | |
---|
| 292 | /*Cal_BddIndex_t minIndex;*/ |
---|
| 293 | int minIndex; |
---|
| 294 | int bddIndex; |
---|
| 295 | Cal_BddId_t bddId, minId; |
---|
| 296 | |
---|
| 297 | |
---|
| 298 | if ((*calOpProc)(bddManager, f, c, &result) == 1){ |
---|
| 299 | return result; |
---|
| 300 | } |
---|
| 301 | |
---|
| 302 | CalBddGetMinIdAndMinIndex(bddManager, f, c, minId, minIndex); |
---|
| 303 | CalHashTableFindOrAdd(reduceHashTableArray[minId], f, c, &result); |
---|
| 304 | for (bddIndex = minIndex; bddIndex < bddManager->numVars; bddIndex++){ |
---|
| 305 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 306 | hashTable = reduceHashTableArray[bddId]; |
---|
| 307 | if(hashTable->numEntries){ |
---|
| 308 | HashTableReduceApply(bddManager, hashTable, reduceHashTableArray, |
---|
| 309 | orHashTableArray, CalOpCofactor); |
---|
| 310 | } |
---|
| 311 | } |
---|
| 312 | for(bddIndex = bddManager->numVars - 1; bddIndex >= minIndex; bddIndex--){ |
---|
| 313 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 314 | uniqueTableForId = bddManager->uniqueTable[bddId]; |
---|
| 315 | hashTable = reduceHashTableArray[bddId]; |
---|
| 316 | if(hashTable->numEntries){ |
---|
| 317 | HashTableCofactorReduce(bddManager, hashTable, uniqueTableForId); |
---|
| 318 | } |
---|
| 319 | } |
---|
| 320 | CalRequestIsForwardedTo(result); |
---|
| 321 | for (bddIndex = minIndex; bddIndex < bddManager->numVars; bddIndex++){ |
---|
| 322 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 323 | CalHashTableCleanUp(reduceHashTableArray[bddId]); |
---|
| 324 | } |
---|
| 325 | return result; |
---|
| 326 | } |
---|
| 327 | |
---|
| 328 | /**Function******************************************************************** |
---|
| 329 | |
---|
| 330 | Synopsis [required] |
---|
| 331 | |
---|
| 332 | Description [optional] |
---|
| 333 | |
---|
| 334 | SideEffects [required] |
---|
| 335 | |
---|
| 336 | SeeAlso [optional] |
---|
| 337 | |
---|
| 338 | ******************************************************************************/ |
---|
| 339 | static Cal_Bdd_t |
---|
| 340 | BddCofactorBF(Cal_BddManager_t * bddManager, |
---|
| 341 | CalOpProc_t calOpProc, |
---|
| 342 | Cal_Bdd_t f, |
---|
| 343 | Cal_Bdd_t c) |
---|
| 344 | { |
---|
| 345 | Cal_Bdd_t result; |
---|
| 346 | CalHashTable_t *hashTable; |
---|
| 347 | CalHashTable_t **cofactorHashTableArray = bddManager->reqQue[0]; |
---|
| 348 | CalHashTable_t *uniqueTableForId; |
---|
| 349 | |
---|
| 350 | /*Cal_BddIndex_t minIndex;*/ |
---|
| 351 | int minIndex; |
---|
| 352 | int bddIndex; |
---|
| 353 | Cal_BddId_t bddId, minId; |
---|
| 354 | |
---|
| 355 | if (CalBddIsBddZero(bddManager, c)){ |
---|
| 356 | CalBddWarningMessage("Bdd Cofactor Called with zero care set"); |
---|
| 357 | return bddManager->bddOne; |
---|
| 358 | } |
---|
| 359 | |
---|
| 360 | if (calOpProc(bddManager, f, c, &result) == 1){ |
---|
| 361 | return result; |
---|
| 362 | } |
---|
| 363 | |
---|
| 364 | CalBddGetMinIdAndMinIndex(bddManager, f, c, minId, minIndex); |
---|
| 365 | CalHashTableFindOrAdd(cofactorHashTableArray[minId], f, c, &result); |
---|
| 366 | for (bddIndex = minIndex; bddIndex < bddManager->numVars; bddIndex++){ |
---|
| 367 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 368 | hashTable = cofactorHashTableArray[bddId]; |
---|
| 369 | if(hashTable->numEntries){ |
---|
| 370 | HashTableCofactorApply(bddManager, hashTable, cofactorHashTableArray, |
---|
| 371 | calOpProc); |
---|
| 372 | } |
---|
| 373 | } |
---|
| 374 | for(bddIndex = bddManager->numVars - 1; bddIndex >= minIndex; bddIndex--){ |
---|
| 375 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 376 | uniqueTableForId = bddManager->uniqueTable[bddId]; |
---|
| 377 | hashTable = cofactorHashTableArray[bddId]; |
---|
| 378 | if(hashTable->numEntries){ |
---|
| 379 | HashTableCofactorReduce(bddManager, hashTable, uniqueTableForId); |
---|
| 380 | } |
---|
| 381 | } |
---|
| 382 | CalRequestIsForwardedTo(result); |
---|
| 383 | for (bddIndex = minIndex; bddIndex < bddManager->numVars; bddIndex++){ |
---|
| 384 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 385 | CalHashTableCleanUp(cofactorHashTableArray[bddId]); |
---|
| 386 | } |
---|
| 387 | return result; |
---|
| 388 | } |
---|
| 389 | |
---|
| 390 | /**Function******************************************************************** |
---|
| 391 | |
---|
| 392 | Synopsis [required] |
---|
| 393 | |
---|
| 394 | Description [optional] |
---|
| 395 | |
---|
| 396 | SideEffects [required] |
---|
| 397 | |
---|
| 398 | SeeAlso [optional] |
---|
| 399 | |
---|
| 400 | ******************************************************************************/ |
---|
| 401 | static void |
---|
| 402 | HashTableReduceApply(Cal_BddManager_t * bddManager, |
---|
| 403 | CalHashTable_t * hashTable, |
---|
| 404 | CalHashTable_t ** reduceHashTableArray, |
---|
| 405 | CalHashTable_t ** orHashTableArray, |
---|
| 406 | CalOpProc_t calOpProc) |
---|
| 407 | { |
---|
| 408 | int i, numBins = hashTable->numBins; |
---|
| 409 | CalRequestNode_t *requestNode, *last, *nextRequestNode, *requestNodeList; |
---|
| 410 | Cal_Bdd_t f, c, fx, cx, fxbar, cxbar, result, orResult; |
---|
| 411 | Cal_BddId_t bddId, minId; |
---|
| 412 | /*Cal_BddIndex_t minIndex;*/ |
---|
| 413 | int minIndex; |
---|
| 414 | int bddIndex; |
---|
| 415 | CalHashTable_t *orHashTable; |
---|
| 416 | |
---|
| 417 | requestNodeList = Cal_Nil(CalRequestNode_t); |
---|
| 418 | for(i = 0; i < numBins; i++){ |
---|
| 419 | last = Cal_Nil(CalRequestNode_t); |
---|
| 420 | for (requestNode = hashTable->bins[i]; requestNode != |
---|
| 421 | Cal_Nil(CalRequestNode_t); |
---|
| 422 | requestNode = nextRequestNode){ |
---|
| 423 | nextRequestNode = CalRequestNodeGetNextRequestNode(requestNode); |
---|
| 424 | CalRequestNodeGetF(requestNode, f); |
---|
| 425 | CalRequestNodeGetG(requestNode, c); |
---|
| 426 | CalBddGetMinId2(bddManager, f, c, minId); |
---|
| 427 | CalBddGetCofactors(c, minId, cx, cxbar); |
---|
| 428 | if (CalBddGetBddId(f) != minId){ |
---|
| 429 | if (CalOpOr(bddManager, cx, cxbar, &orResult) == 0){ |
---|
| 430 | CalBddNormalize(cx, cxbar); |
---|
| 431 | CalBddGetMinId2(bddManager, cx, cxbar, minId); |
---|
| 432 | CalHashTableFindOrAdd(orHashTableArray[minId], cx, cxbar, &orResult); |
---|
| 433 | } |
---|
| 434 | CalRequestNodePutElseRequest(requestNode, orResult); |
---|
| 435 | if (last == Cal_Nil(CalRequestNode_t)){ |
---|
| 436 | hashTable->bins[i] = nextRequestNode; |
---|
| 437 | } |
---|
| 438 | else { |
---|
| 439 | CalRequestNodePutNextRequestNode(last, nextRequestNode); |
---|
| 440 | } |
---|
| 441 | CalRequestNodePutNextRequestNode(requestNode, requestNodeList); |
---|
| 442 | requestNodeList = requestNode; |
---|
| 443 | } |
---|
| 444 | else{ |
---|
| 445 | last = requestNode; |
---|
| 446 | CalBddGetCofactors(f, minId, fx, fxbar); |
---|
| 447 | if((*calOpProc)(bddManager, fx, cx, &result) == 0){ |
---|
| 448 | CalBddGetMinId2(bddManager, fx, cx, bddId); |
---|
| 449 | CalHashTableFindOrAdd(reduceHashTableArray[bddId], fx, cx, &result); |
---|
| 450 | } |
---|
| 451 | if (CalBddIsBddNull(bddManager, result) == 0){ |
---|
| 452 | CalBddIcrRefCount(result); |
---|
| 453 | } |
---|
| 454 | CalRequestNodePutThenRequest(requestNode, result); |
---|
| 455 | if((*calOpProc)(bddManager, fxbar, cxbar, &result) == 0){ |
---|
| 456 | CalBddGetMinId2(bddManager, fxbar, cxbar, bddId); |
---|
| 457 | CalHashTableFindOrAdd(reduceHashTableArray[bddId], fxbar, cxbar, |
---|
| 458 | &result); |
---|
| 459 | } |
---|
| 460 | if (CalBddIsBddNull(bddManager, result) == 0){ |
---|
| 461 | CalBddIcrRefCount(result); |
---|
| 462 | } |
---|
| 463 | CalRequestNodePutElseRequest(requestNode, result); |
---|
| 464 | } |
---|
| 465 | } |
---|
| 466 | } |
---|
| 467 | minIndex = bddManager->idToIndex[hashTable->bddId]; |
---|
| 468 | for (bddIndex = minIndex; bddIndex < bddManager->numVars; bddIndex++){ |
---|
| 469 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 470 | orHashTable = orHashTableArray[bddId]; |
---|
| 471 | if(orHashTable->numEntries){ |
---|
| 472 | CalHashTableApply(bddManager, orHashTable, orHashTableArray, CalOpOr); |
---|
| 473 | } |
---|
| 474 | } |
---|
| 475 | |
---|
| 476 | for(bddIndex = bddManager->numVars - 1; bddIndex >= minIndex; bddIndex--){ |
---|
| 477 | CalHashTable_t *uniqueTableForId; |
---|
| 478 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 479 | uniqueTableForId = bddManager->uniqueTable[bddId]; |
---|
| 480 | orHashTable = orHashTableArray[bddId]; |
---|
| 481 | if(orHashTable->numEntries){ |
---|
| 482 | CalHashTableReduce(bddManager, orHashTable, uniqueTableForId); |
---|
| 483 | } |
---|
| 484 | } |
---|
| 485 | for (requestNode = requestNodeList; requestNode; requestNode = |
---|
| 486 | nextRequestNode){ |
---|
| 487 | nextRequestNode = CalRequestNodeGetNextRequestNode(requestNode); |
---|
| 488 | CalRequestNodeGetElseRequest(requestNode, orResult); |
---|
| 489 | CalRequestIsForwardedTo(orResult); |
---|
| 490 | CalRequestNodeGetThenRequest(requestNode, f); |
---|
| 491 | CalBddGetMinId2(bddManager, f, orResult, minId); |
---|
| 492 | CalHashTableFindOrAdd(reduceHashTableArray[minId], f, orResult, |
---|
| 493 | &result); |
---|
| 494 | CalRequestNodePutThenRequest(requestNode, result); |
---|
| 495 | CalRequestNodePutElseRequest(requestNode, result); |
---|
| 496 | CalBddAddRefCount(result, 2); |
---|
| 497 | CalHashTableAddDirect(hashTable, requestNode); |
---|
| 498 | } |
---|
| 499 | |
---|
| 500 | /* Clean up the orHashTableArray */ |
---|
| 501 | for(bddIndex = bddManager->numVars - 1; bddIndex >= minIndex; bddIndex--){ |
---|
| 502 | bddId = bddManager->indexToId[bddIndex]; |
---|
| 503 | CalHashTableCleanUp(orHashTableArray[bddId]); |
---|
| 504 | } |
---|
| 505 | } |
---|
| 506 | |
---|
| 507 | /**Function******************************************************************** |
---|
| 508 | |
---|
| 509 | Synopsis [required] |
---|
| 510 | |
---|
| 511 | Description [optional] |
---|
| 512 | |
---|
| 513 | SideEffects [required] |
---|
| 514 | |
---|
| 515 | SeeAlso [optional] |
---|
| 516 | |
---|
| 517 | ******************************************************************************/ |
---|
| 518 | static void |
---|
| 519 | HashTableCofactorApply(Cal_BddManager_t * bddManager, |
---|
| 520 | CalHashTable_t * hashTable, |
---|
| 521 | CalHashTable_t ** cofactorHashTableArray, |
---|
| 522 | CalOpProc_t calOpProc) |
---|
| 523 | { |
---|
| 524 | int i, numBins = hashTable->numBins; |
---|
| 525 | CalBddNode_t **bins = hashTable->bins; |
---|
| 526 | CalRequestNode_t *requestNode; |
---|
| 527 | Cal_Bdd_t f, c, fx, cx, fxbar, cxbar, result; |
---|
| 528 | Cal_BddId_t bddId, minId; |
---|
| 529 | |
---|
| 530 | for(i = 0; i < numBins; i++){ |
---|
| 531 | for(requestNode = bins[i]; |
---|
| 532 | requestNode != Cal_Nil(CalRequestNode_t); |
---|
| 533 | requestNode = CalRequestNodeGetNextRequestNode(requestNode)){ |
---|
| 534 | CalRequestNodeGetF(requestNode, f); |
---|
| 535 | CalRequestNodeGetG(requestNode, c); |
---|
| 536 | CalBddGetMinId2(bddManager, f, c, minId); |
---|
| 537 | CalBddGetCofactors(f, minId, fx, fxbar); |
---|
| 538 | CalBddGetCofactors(c, minId, cx, cxbar); |
---|
| 539 | if((*calOpProc)(bddManager, fx, cx, &result) == 0){ |
---|
| 540 | CalBddGetMinId2(bddManager, fx, cx, bddId); |
---|
| 541 | CalHashTableFindOrAdd(cofactorHashTableArray[bddId], fx, cx, &result); |
---|
| 542 | } |
---|
| 543 | if (CalBddIsBddNull(bddManager, result) == 0){ |
---|
| 544 | CalBddIcrRefCount(result); |
---|
| 545 | } |
---|
| 546 | CalRequestNodePutThenRequest(requestNode, result); |
---|
| 547 | if((*calOpProc)(bddManager, fxbar, cxbar, &result) == 0){ |
---|
| 548 | CalBddGetMinId2(bddManager, fxbar, cxbar, bddId); |
---|
| 549 | CalHashTableFindOrAdd(cofactorHashTableArray[bddId], fxbar, cxbar, |
---|
| 550 | &result); |
---|
| 551 | } |
---|
| 552 | if (CalBddIsBddNull(bddManager, result) == 0){ |
---|
| 553 | CalBddIcrRefCount(result); |
---|
| 554 | } |
---|
| 555 | CalRequestNodePutElseRequest(requestNode, result); |
---|
| 556 | } |
---|
| 557 | } |
---|
| 558 | } |
---|
| 559 | |
---|
| 560 | /**Function******************************************************************** |
---|
| 561 | |
---|
| 562 | Synopsis [required] |
---|
| 563 | |
---|
| 564 | Description [optional] |
---|
| 565 | |
---|
| 566 | SideEffects [required] |
---|
| 567 | |
---|
| 568 | SeeAlso [optional] |
---|
| 569 | |
---|
| 570 | ******************************************************************************/ |
---|
| 571 | static void |
---|
| 572 | HashTableCofactorReduce(Cal_BddManager_t * bddManager, |
---|
| 573 | CalHashTable_t * hashTable, |
---|
| 574 | CalHashTable_t * uniqueTableForId) |
---|
| 575 | { |
---|
| 576 | int i, numBins = hashTable->numBins; |
---|
| 577 | CalBddNode_t **bins = hashTable->bins; |
---|
| 578 | Cal_BddId_t currentBddId = uniqueTableForId->bddId; |
---|
| 579 | CalNodeManager_t *nodeManager = uniqueTableForId->nodeManager; |
---|
| 580 | CalRequestNode_t *requestNode, *next, *endNode; |
---|
| 581 | CalBddNode_t *bddNode; |
---|
| 582 | Cal_Bdd_t thenBdd, elseBdd, result; |
---|
| 583 | Cal_BddRefCount_t refCount; |
---|
| 584 | |
---|
| 585 | endNode = hashTable->endNode; |
---|
| 586 | for(i = 0; i < numBins; i++){ |
---|
| 587 | for(requestNode = bins[i], bins[i] = Cal_Nil(CalRequestNode_t); |
---|
| 588 | requestNode != Cal_Nil(CalRequestNode_t); |
---|
| 589 | requestNode = next){ |
---|
| 590 | next = CalRequestNodeGetNextRequestNode(requestNode); |
---|
| 591 | /* Process the requestNode */ |
---|
| 592 | CalRequestNodeGetThenRequest(requestNode, thenBdd); |
---|
| 593 | CalRequestNodeGetElseRequest(requestNode, elseBdd); |
---|
| 594 | if (CalBddIsBddNull(bddManager, thenBdd)){ |
---|
| 595 | CalRequestIsForwardedTo(elseBdd); |
---|
| 596 | CalBddNodeGetRefCount(requestNode, refCount); |
---|
| 597 | CalBddAddRefCount(elseBdd, refCount - 1); |
---|
| 598 | CalRequestNodePutThenRequest(requestNode, elseBdd); |
---|
| 599 | CalRequestNodePutElseRequestNode(requestNode, FORWARD_FLAG); |
---|
| 600 | endNode->nextBddNode = requestNode; |
---|
| 601 | endNode = requestNode; |
---|
| 602 | continue; |
---|
| 603 | } |
---|
| 604 | else if (CalBddIsBddNull(bddManager, elseBdd)){ |
---|
| 605 | CalRequestIsForwardedTo(thenBdd); |
---|
| 606 | CalBddNodeGetRefCount(requestNode, refCount); |
---|
| 607 | CalBddAddRefCount(thenBdd, refCount - 1); |
---|
| 608 | CalRequestNodePutThenRequest(requestNode, thenBdd); |
---|
| 609 | CalRequestNodePutElseRequestNode(requestNode, FORWARD_FLAG); |
---|
| 610 | endNode->nextBddNode = requestNode; |
---|
| 611 | endNode = requestNode; |
---|
| 612 | continue; |
---|
| 613 | } |
---|
| 614 | CalRequestIsForwardedTo(thenBdd); |
---|
| 615 | CalRequestIsForwardedTo(elseBdd); |
---|
| 616 | if(CalBddIsEqual(thenBdd, elseBdd)){ |
---|
| 617 | CalBddNodeGetRefCount(requestNode, refCount); |
---|
| 618 | CalBddAddRefCount(thenBdd, refCount - 2); |
---|
| 619 | CalRequestNodePutThenRequest(requestNode, thenBdd); |
---|
| 620 | CalRequestNodePutElseRequestNode(requestNode, FORWARD_FLAG); |
---|
| 621 | endNode->nextBddNode = requestNode; |
---|
| 622 | endNode = requestNode; |
---|
| 623 | } |
---|
| 624 | else if(CalUniqueTableForIdLookup(bddManager, uniqueTableForId, |
---|
| 625 | thenBdd, elseBdd, &result) == 1){ |
---|
| 626 | CalBddDcrRefCount(thenBdd); |
---|
| 627 | CalBddDcrRefCount(elseBdd); |
---|
| 628 | CalBddNodeGetRefCount(requestNode, refCount); |
---|
| 629 | CalBddAddRefCount(result, refCount); |
---|
| 630 | CalRequestNodePutThenRequest(requestNode, result); |
---|
| 631 | CalRequestNodePutElseRequestNode(requestNode, FORWARD_FLAG); |
---|
| 632 | endNode->nextBddNode = requestNode; |
---|
| 633 | endNode = requestNode; |
---|
| 634 | } |
---|
| 635 | else if(CalBddIsOutPos(thenBdd)){ |
---|
| 636 | CalRequestNodePutThenRequest(requestNode, thenBdd); |
---|
| 637 | CalRequestNodePutElseRequest(requestNode, elseBdd); |
---|
| 638 | CalHashTableAddDirect(uniqueTableForId, requestNode); |
---|
| 639 | bddManager->numNodes++; |
---|
| 640 | bddManager->gcCheck--; |
---|
| 641 | } |
---|
| 642 | else{ |
---|
| 643 | CalNodeManagerAllocNode(nodeManager, bddNode); |
---|
| 644 | CalBddNodePutThenBddId(bddNode, CalBddGetBddId(thenBdd)); |
---|
| 645 | CalBddNodePutThenBddNode(bddNode, CalBddGetBddNodeNot(thenBdd)); |
---|
| 646 | CalBddNodePutElseBddId(bddNode, CalBddGetBddId(elseBdd)); |
---|
| 647 | CalBddNodePutElseBddNode(bddNode, CalBddGetBddNodeNot(elseBdd)); |
---|
| 648 | CalBddNodeGetRefCount(requestNode, refCount); |
---|
| 649 | CalBddNodePutRefCount(bddNode, refCount); |
---|
| 650 | CalHashTableAddDirect(uniqueTableForId, bddNode); |
---|
| 651 | bddManager->numNodes++; |
---|
| 652 | bddManager->gcCheck--; |
---|
| 653 | CalRequestNodePutThenRequestId(requestNode, currentBddId); |
---|
| 654 | CalRequestNodePutThenRequestNode(requestNode, CalBddNodeNot(bddNode)); |
---|
| 655 | CalRequestNodePutElseRequestNode(requestNode, FORWARD_FLAG); |
---|
| 656 | endNode->nextBddNode = requestNode; |
---|
| 657 | endNode = requestNode; |
---|
| 658 | } |
---|
| 659 | } |
---|
| 660 | } |
---|
| 661 | hashTable->endNode = endNode; |
---|
| 662 | } |
---|
| 663 | |
---|
| 664 | |
---|
| 665 | |
---|
| 666 | |
---|
| 667 | |
---|
| 668 | |
---|
| 669 | |
---|
| 670 | |
---|
| 671 | |
---|
| 672 | |
---|
| 673 | |
---|
| 674 | |
---|
| 675 | |
---|
| 676 | |
---|
| 677 | |
---|
| 678 | |
---|
| 679 | |
---|
| 680 | |
---|
| 681 | |
---|
| 682 | |
---|
| 683 | |
---|
| 684 | |
---|