00001 
00039 #include "calInt.h"
00040 
00041 
00042 
00043 
00044 
00045 #define CAL_MODULUS1 2147483563
00046 #define CAL_LEQA1 40014
00047 #define CAL_LEQQ1 53668
00048 #define CAL_LEQR1 12211
00049 #define CAL_MODULUS2 2147483399
00050 #define CAL_LEQA2 40692
00051 #define CAL_LEQQ2 52774
00052 #define CAL_LEQR2 3791
00053 #define CAL_STAB_SIZE 64
00054 #define CAL_STAB_DIV (1 + (CAL_MODULUS1 - 1) / CAL_STAB_SIZE)
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 static long utilRand = 0;
00069 static long utilRand2;
00070 static long shuffleSelect;
00071 static long shuffleTable[CAL_STAB_SIZE];
00072 
00073 
00074 
00075 
00076 
00077 
00080 
00081 
00082 
00083 
00084 
00087 
00088 
00089 
00090 void
00091 Cal_ImageDump(Cal_BddManager_t *bddManager, FILE *fp)
00092 {
00093 
00094   CalPageManager_t *pageManager;
00095   int i, j;
00096   char *segment, c;
00097   int count = NUM_PAGES_PER_SEGMENT * PAGE_SIZE;
00098 
00099   pageManager = bddManager->pageManager1;
00100   for(i = 0; i < pageManager->numSegments; i++){
00101     segment = (char *) pageManager->pageSegmentArray[i];
00102     for(j = 1; j <= count; j++){
00103       c = segment[j];
00104       fprintf(fp, "%c", j%64?c:'\n');
00105     }
00106   }
00107   pageManager = bddManager->pageManager2;
00108   for(i = 0; i < pageManager->numSegments; i++){
00109     segment = (char *) pageManager->pageSegmentArray[i];
00110     for(j = 1; j <= count; j++){
00111       c = segment[j];
00112       fprintf(fp, "%c", j%64?c:'\n');
00113     }
00114   }
00115 }
00116 
00117 
00127 void
00128 Cal_BddFunctionPrint(Cal_BddManager bddManager, Cal_Bdd  userBdd,
00129                      char *name)
00130 {
00131   Cal_Bdd_t calBdd;
00132   calBdd = CalBddGetInternalBdd(bddManager, userBdd);
00133   CalBddFunctionPrint(bddManager, calBdd, name);
00134 }
00135 
00136 
00137 
00138 
00150 void
00151 CalUniqueTablePrint(Cal_BddManager_t *bddManager)
00152 {
00153   int i;
00154   for(i = 0; i <= bddManager->numVars; i++){
00155     CalHashTablePrint(bddManager->uniqueTable[i]);
00156   }
00157 }
00158 
00168 void
00169 CalBddFunctionPrint(Cal_BddManager_t * bddManager,
00170                     Cal_Bdd_t  calBdd,
00171                     char * name)
00172 {
00173   Cal_Bdd_t T,E;
00174   Cal_BddId_t id;
00175   char c;
00176   static int level;
00177 
00178   if(level == 0)printf("%s = ",name);
00179   level++;
00180   printf("( ");
00181   if(CalBddIsBddZero(bddManager, calBdd)){
00182     printf("0 ");
00183   }
00184   else if(CalBddIsBddOne(bddManager, calBdd)){
00185     printf("1 ");
00186   }
00187   else{
00188     id = CalBddGetBddId(calBdd);
00189     c = (char)((int)'a' + id - 1);
00190     printf("%c ", c);
00191     CalBddGetCofactors(calBdd, id, T, E);
00192     CalBddFunctionPrint(bddManager, T, " ");
00193     printf("+ %c' ", c);
00194     CalBddFunctionPrint(bddManager, E, " ");
00195   }
00196   level--;
00197   printf(") ");
00198   if(level == 0)printf("\n");
00199 }
00200 
00212 #if HAVE_STDARG_H
00213 int
00214 CalBddPreProcessing(Cal_BddManager_t *bddManager, int count, ...)
00215 {
00216   int allValid;
00217   va_list ap;
00218   Cal_Bdd fUserBdd;
00219   Cal_Bdd_t f;
00220   
00221   va_start(ap, count);
00222 #else
00223 #  if HAVE_VARARGS_H
00224 int
00225 CalBddPreProcessing(va_alist)
00226 va_dcl
00227 {
00228   int allValid;
00229   va_list ap;
00230   Cal_Bdd *fUserBdd;
00231   int count;
00232   Cal_BddManager_t *bddManager;
00233   Cal_Bdd_t f;
00234   
00235   va_start(ap);
00236   bddManager = va_arg(ap, Cal_BddManager_t *);
00237   count = va_arg(ap, int);
00238 #  endif
00239 #endif  
00240 
00241   allValid=1;
00242   while (count){
00243     fUserBdd = va_arg(ap, Cal_Bdd);
00244         if (fUserBdd == 0){
00245           allValid=0;
00246     }
00247         else {
00248       f = CalBddGetInternalBdd(bddManager, fUserBdd);
00249       if (CalBddIsRefCountZero(f)){
00250         CalBddFatalMessage("Bdd With Zero Reference Count Used.");
00251       }
00252     }
00253     --count;
00254   }
00255   if (allValid) {
00256     CalBddPostProcessing(bddManager);
00257   }
00258   va_end(ap);
00259   return (allValid);
00260 }
00261 
00262 
00274 int
00275 CalBddPostProcessing(Cal_BddManager_t *bddManager)
00276 {
00277   if (bddManager->gcCheck > 0) return CAL_BDD_OK;
00278   bddManager->gcCheck = CAL_GC_CHECK;
00279   if(bddManager->numNodes > bddManager->uniqueTableGCLimit){
00280     long origNodes = bddManager->numNodes;
00281     Cal_BddManagerGC(bddManager);
00282     if ((bddManager->numNodes > bddManager->reorderingThreshold) &&
00283         (3*bddManager->numNodes > 2* bddManager->uniqueTableGCLimit) &&
00284         (bddManager->dynamicReorderingEnableFlag) &&
00285         (bddManager->reorderTechnique != CAL_REORDER_NONE)){
00286       CalCacheTableTwoFlush(bddManager->cacheTable);
00287       if (bddManager->reorderMethod == CAL_REORDER_METHOD_BF){
00288         CalBddReorderAuxBF(bddManager);
00289       }
00290       else{
00291         CalBddReorderAuxDF(bddManager);
00292       }
00293     }
00294     else {
00295       
00296       Cal_Assert(CalCheckAllValidity(bddManager));
00297       if (bddManager->numNodes <
00298           bddManager->repackAfterGCThreshold*origNodes){
00299         CalRepackNodesAfterGC(bddManager);
00300       }
00301       Cal_Assert(CalCheckAllValidity(bddManager));
00302     }
00303     Cal_BddManagerSetGCLimit(bddManager);
00304     if (bddManager->nodeLimit && (bddManager->numNodes >
00305                                   bddManager->nodeLimit)){ 
00306       CalBddWarningMessage("Overflow: Node Limit Exceeded");
00307       bddManager->overflow = 1;
00308       return CAL_BDD_OVERFLOWED;
00309     }
00310     
00311 
00312 
00313     CalCacheTableRehash(bddManager);
00314   }
00315   return CAL_BDD_OK;
00316 }
00317 
00329 int
00330 CalBddArrayPreProcessing(Cal_BddManager_t *bddManager, Cal_Bdd *userBddArray) 
00331 {
00332   int i = 0;
00333   Cal_Bdd userBdd;
00334   while ((userBdd = userBddArray[i++])){
00335     if (CalBddPreProcessing(bddManager, 1, userBdd) == 0){
00336       return 0;
00337     }
00338   }
00339   return 1;
00340 }
00341     
00342                        
00356 Cal_Bdd_t
00357 CalBddGetInternalBdd(Cal_BddManager bddManager, Cal_Bdd userBdd)
00358 {
00359   Cal_Bdd_t resultBdd;
00360   if (CalBddNodeIsOutPos(userBdd)){
00361     CalBddNodeGetThenBdd(userBdd, resultBdd);
00362   }
00363   else {
00364     Cal_Bdd userBddNot = CalBddNodeNot(userBdd);
00365     Cal_Bdd_t internalBdd;
00366         CalBddNodeGetThenBdd(userBddNot,internalBdd);
00367     CalBddNot(internalBdd, resultBdd);
00368   }
00369   return resultBdd;
00370 }
00371 
00385 Cal_Bdd
00386 CalBddGetExternalBdd(Cal_BddManager_t *bddManager, Cal_Bdd_t internalBdd)
00387 {
00388   CalHashTable_t *hashTableForUserBdd = bddManager->uniqueTable[0];
00389   Cal_Bdd_t resultBdd;
00390   int found;
00391   
00392   if(CalBddIsOutPos(internalBdd)){
00393     found = CalHashTableFindOrAdd(hashTableForUserBdd, internalBdd,
00394                           bddManager->bddOne, &resultBdd);
00395   }
00396   else {
00397     Cal_Bdd_t internalBddNot;
00398     CalBddNot(internalBdd, internalBddNot);
00399     found = CalHashTableFindOrAdd(hashTableForUserBdd, internalBddNot,
00400                           bddManager->bddOne, &resultBdd);
00401     CalBddNot(resultBdd, resultBdd);
00402   }
00403   if (found == 0){
00404     CalBddIcrRefCount(internalBdd);
00405   }
00406   CalBddIcrRefCount(resultBdd);
00407   return CalBddGetBddNode(resultBdd);
00408 }
00409 
00410 
00424 void
00425 CalBddFatalMessage(char *string)
00426 {
00427   (void) fprintf(stderr,"Fatal: %s\n", string);
00428   exit(-1);
00429 }
00443 void
00444 CalBddWarningMessage(char *string)
00445 {
00446   (void) fprintf(stderr,"Warning: %s\n", string);
00447 }
00448 
00460 void
00461 CalBddNodePrint(CalBddNode_t *bddNode)
00462 {
00463   int refCount;
00464   CalBddNodeGetRefCount(bddNode, refCount);
00465   printf("Node (%lx) thenBdd(%2d %lx)  elseBdd(%2d %lx) ref_count (%d) next (%lx)\n",
00466          (CalAddress_t)bddNode,
00467          CalBddNodeGetThenBddId(bddNode),
00468          (CalAddress_t) CalBddNodeGetThenBddNode(bddNode), 
00469          CalBddNodeGetElseBddId(bddNode),
00470          (CalAddress_t) CalBddNodeGetElseBddNode(bddNode),
00471          refCount, (CalAddress_t)bddNode->nextBddNode);
00472 }
00473 
00486 void
00487 CalBddPrint(Cal_Bdd_t calBdd)
00488 {
00489   printf("Id(%2d) node(%lx) ",
00490       CalBddGetBddId(calBdd), (CalAddress_t) CalBddGetBddNode(calBdd));
00491   printf("thenBdd(%2d %lx)  elseBdd(%2d %lx)\n",
00492          CalBddGetThenBddId(calBdd),
00493          (CalAddress_t) CalBddGetThenBddNode(calBdd), 
00494          CalBddGetElseBddId(calBdd),
00495          (CalAddress_t) CalBddGetElseBddNode(calBdd));
00496 }
00497 
00498 #ifdef TEST_CALBDDNODE
00499 main(int argc, char **argv)
00500 {
00501   CalBddNode_t *bddNode, *thenBddNode, *elseBddNode;
00502 
00503   bddNode = Cal_MemAlloc(CalBddNode_t, 1);
00504   thenBddNode = Cal_MemAlloc(CalBddNode_t, 1);
00505   elseBddNode = Cal_MemAlloc(CalBddNode_t, 1);
00506 
00507   CalBddNodePutThenBddId(bddNode, 1);
00508   CalBddNodePutThenBddNode(bddNode, thenBddNode);
00509   CalBddNodePutElseBddId(bddNode, 2);
00510   CalBddNodePutElseBddNode(bddNode, elseBddNode);
00511 
00512   printf("then( 1 %x) else( 2 %x)\n", thenBddNode, elseBddNode);
00513   CalBddNodePrint(bddNode);
00514 }
00515 #endif
00516 
00517 
00529 void
00530 CalHashTablePrint(CalHashTable_t *hashTable)
00531 {
00532   int i;
00533   CalBddNode_t *ptr;
00534   Cal_Bdd_t calBdd, T, E;
00535   int refCount, firstFlag;
00536 
00537   printf("HashTable bddId(%d) entries(%ld) bins(%ld) capacity(%ld)\n",
00538          hashTable->bddId, hashTable->numEntries, hashTable->numBins,
00539          hashTable->maxCapacity);
00540   for(i = 0; i < hashTable->numBins; i++){
00541     ptr = hashTable->bins[i];
00542     firstFlag = 1;
00543     while(ptr != Cal_Nil(CalBddNode_t)){
00544       CalBddPutBddNode(calBdd, ptr);
00545       CalBddNodeGetThenBdd(ptr, T);
00546       CalBddNodeGetElseBdd(ptr, E);
00547       if (firstFlag){
00548         printf("\tbin = (%d) ", i);
00549         firstFlag = 0;
00550       }
00551       printf("\t\tbddNode(%lx) ", (CalAddress_t)ptr);
00552       printf("thenId(%d) ", CalBddGetBddId(T)); 
00553       printf("thenBddNode(%lx) ", (CalAddress_t) CalBddGetBddNode(T));
00554       printf("elseId(%d) ", CalBddGetBddId(E)); 
00555       printf("elseBddNode(%lx) ", (unsigned long)CalBddGetBddNode(E));
00556       CalBddGetRefCount(calBdd, refCount);
00557       printf("refCount(%d)\n", refCount);
00558       ptr = CalBddNodeGetNextBddNode(ptr);
00559     }
00560   }
00561 }
00562 
00574 void
00575 CalHashTableOnePrint(CalHashTable_t *hashTable, int flag)
00576 {
00577   int i;
00578   CalBddNode_t *ptr, *node;
00579   Cal_Bdd_t keyBdd;
00580 
00581   printf("*************************************************\n");
00582   for(i = 0; i < hashTable->numBins; i++){
00583     ptr = hashTable->bins[i];
00584     while(ptr != Cal_Nil(CalBddNode_t)){
00585       CalBddNodeGetThenBdd(ptr, keyBdd);
00586       node = CalBddNodeGetElseBddNode(ptr);
00587       if(flag == 1){
00588         printf("Key(%d %lx) Value(%f)\n", 
00589             CalBddGetBddId(keyBdd), (CalAddress_t)CalBddGetBddNode(keyBdd), *(double *)node); 
00590       }
00591       else{
00592         printf("Key(%d %lx) Value(%d)\n",
00593             CalBddGetBddId(keyBdd), (CalAddress_t)CalBddGetBddNode(keyBdd),  *(int *)node); 
00594       }
00595       ptr = CalBddNodeGetNextBddNode(ptr);
00596     }
00597   }
00598 }
00599 
00616 void
00617 CalUtilSRandom(long seed)
00618 {
00619     int i;
00620 
00621     if (seed < 0)       utilRand = -seed;
00622     else if (seed == 0) utilRand = 1;
00623     else                utilRand = seed;
00624     utilRand2 = utilRand;
00625     
00626     for (i = 0; i < CAL_STAB_SIZE + 11; i++) {
00627         long int w;
00628         w = utilRand / CAL_LEQQ1;
00629         utilRand = CAL_LEQA1 * (utilRand - w * CAL_LEQQ1) - w * CAL_LEQR1;
00630         utilRand += (utilRand < 0) * CAL_MODULUS1;
00631         shuffleTable[i % CAL_STAB_SIZE] = utilRand;
00632     }
00633     shuffleSelect = shuffleTable[1 % CAL_STAB_SIZE];
00634 } 
00635 
00653 long
00654 CalUtilRandom(void)
00655 {
00656     int i;      
00657     long int w; 
00658 
00659     
00660     if (utilRand == 0) CalUtilSRandom((long)1);
00661 
00662     
00663 
00664 
00665     w          = utilRand / CAL_LEQQ1;
00666     utilRand   = CAL_LEQA1 * (utilRand - w * CAL_LEQQ1) - w * CAL_LEQR1;
00667     utilRand  += (utilRand < 0) * CAL_MODULUS1;
00668 
00669     
00670 
00671 
00672     w          = utilRand2 / CAL_LEQQ2;
00673     utilRand2  = CAL_LEQA2 * (utilRand2 - w * CAL_LEQQ2) - w * CAL_LEQR2;
00674     utilRand2 += (utilRand2 < 0) * CAL_MODULUS2;
00675 
00676     
00677 
00678 
00679 
00680     
00681 
00682 
00683     i = shuffleSelect / CAL_STAB_DIV;
00684     
00685 
00686 
00687 
00688     shuffleSelect   = shuffleTable[i] - utilRand2;
00689     shuffleTable[i] = utilRand;
00690     shuffleSelect  += (shuffleSelect < 1) * (CAL_MODULUS1 - 1);
00691     
00692 
00693 
00694     return(shuffleSelect - 1);
00695 
00696 } 
00697 
00698