00001
00019 #include "fraigInt.h"
00020
00024
00025 static int Fraig_FeedBackPrepare( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars );
00026 static int Fraig_FeedBackInsert( Fraig_Man_t * p, int nVarsPi );
00027 static void Fraig_FeedBackVerify( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
00028
00029 static void Fraig_FeedBackCovering( Fraig_Man_t * p, Msat_IntVec_t * vPats );
00030 static Fraig_NodeVec_t * Fraig_FeedBackCoveringStart( Fraig_Man_t * pMan );
00031 static int Fraig_GetSmallestColumn( int * pHits, int nHits );
00032 static int Fraig_GetHittingPattern( unsigned * pSims, int nWords );
00033 static void Fraig_CancelCoveredColumns( Fraig_NodeVec_t * vColumns, int * pHits, int iPat );
00034 static void Fraig_FeedBackCheckTable( Fraig_Man_t * p );
00035 static void Fraig_FeedBackCheckTableF0( Fraig_Man_t * p );
00036 static void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p );
00037
00038
00042
00054 void Fraig_FeedBackInit( Fraig_Man_t * p )
00055 {
00056 p->vCones = Fraig_NodeVecAlloc( 500 );
00057 p->vPatsReal = Msat_IntVecAlloc( 1000 );
00058 p->pSimsReal = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
00059 memset( p->pSimsReal, 0, sizeof(unsigned) * p->nWordsDyna );
00060 p->pSimsTemp = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
00061 p->pSimsDiff = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
00062 }
00063
00077 void Fraig_FeedBack( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
00078 {
00079 int nVarsPi, nWords;
00080 int i, clk = clock();
00081
00082
00083 nVarsPi = Fraig_FeedBackPrepare( p, pModel, vVars );
00084
00085
00086 nWords = Fraig_FeedBackInsert( p, nVarsPi );
00087 assert( p->iWordStart + nWords <= p->nWordsDyna );
00088
00089
00090 for ( i = 1; i < p->vNodes->nSize; i++ )
00091 if ( Fraig_NodeIsAnd(p->vNodes->pArray[i]) )
00092 Fraig_NodeSimulate( p->vNodes->pArray[i], p->iWordStart, p->iWordStart + nWords, 0 );
00093
00094 if ( p->fDoSparse )
00095 Fraig_TableRehashF0( p, 0 );
00096
00097 if ( !p->fChoicing )
00098 Fraig_FeedBackVerify( p, pOld, pNew );
00099
00100
00101 if ( p->iWordStart + nWords == p->nWordsDyna )
00102 p->iWordStart = Fraig_FeedBackCompress( p );
00103 else
00104 p->iWordStart += nWords;
00105
00106 p->timeFeed += clock() - clk;
00107 }
00108
00121 int Fraig_FeedBackPrepare( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars )
00122 {
00123 Fraig_Node_t * pNode;
00124 int i, nVars, nVarsPis, * pVars;
00125
00126
00127 for ( i = 0; i < p->vInputs->nSize; i++ )
00128 {
00129 pNode = p->vInputs->pArray[i];
00130 pNode->fFeedUse = 0;
00131 }
00132
00133
00134 nVars = Msat_IntVecReadSize(vVars);
00135 pVars = Msat_IntVecReadArray(vVars);
00136
00137
00138 nVarsPis = 0;
00139 for ( i = 0; i < nVars; i++ )
00140 {
00141 pNode = p->vNodes->pArray[ pVars[i] ];
00142 if ( !Fraig_NodeIsVar(pNode) )
00143 continue;
00144
00145 pNode->fFeedUse = 1;
00146 pNode->fFeedVal = !MSAT_LITSIGN(pModel[pVars[i]]);
00147 nVarsPis++;
00148 }
00149 return nVarsPis;
00150 }
00151
00163 int Fraig_FeedBackInsert( Fraig_Man_t * p, int nVarsPi )
00164 {
00165 Fraig_Node_t * pNode;
00166 int nWords, iPatFlip, nPatFlipLimit, i, w;
00167 int fUseNoPats = 0;
00168 int fUse2Pats = 0;
00169
00170
00171 if ( fUse2Pats )
00172 nWords = FRAIG_NUM_WORDS( 2 * nVarsPi + 1 );
00173 else if ( fUseNoPats )
00174 nWords = 1;
00175 else
00176 nWords = FRAIG_NUM_WORDS( nVarsPi + 1 );
00177
00178 if ( nWords > p->nWordsDyna - p->iWordStart )
00179 nWords = p->nWordsDyna - p->iWordStart;
00180
00181 nPatFlipLimit = nWords * 32 - 2;
00182
00183
00184 Msat_IntVecPush( p->vPatsReal, p->iWordStart * 32 );
00185
00186 Fraig_BitStringSetBit( p->pSimsReal, p->iWordStart * 32 );
00187
00188
00189 iPatFlip = 1;
00190 for ( i = 0; i < p->vInputs->nSize; i++ )
00191 {
00192 pNode = p->vInputs->pArray[i];
00193 for ( w = p->iWordStart; w < p->iWordStart + nWords; w++ )
00194 if ( !pNode->fFeedUse )
00195 pNode->puSimD[w] = FRAIG_RANDOM_UNSIGNED;
00196 else if ( pNode->fFeedVal )
00197 pNode->puSimD[w] = FRAIG_FULL;
00198 else
00199 pNode->puSimD[w] = 0;
00200
00201 if ( fUse2Pats )
00202 {
00203
00204 if ( pNode->fFeedUse && 2 * iPatFlip < nPatFlipLimit )
00205 {
00206 Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip - 1 );
00207 Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip );
00208 Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip + 1 );
00209 iPatFlip++;
00210 }
00211 }
00212 else if ( fUseNoPats )
00213 {
00214 }
00215 else
00216 {
00217
00218 if ( pNode->fFeedUse && iPatFlip < nPatFlipLimit )
00219 {
00220 Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, iPatFlip );
00221 iPatFlip++;
00222
00223 }
00224 }
00225
00226 pNode->fFeedUse = 0;
00227
00228
00229 for ( w = p->iWordStart; w < p->iWordStart + nWords; w++ )
00230 pNode->uHashD ^= pNode->puSimD[w] * s_FraigPrimes[w];
00231
00232 }
00233 return nWords;
00234 }
00235
00236
00248 void Fraig_FeedBackVerify( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
00249 {
00250 int fValue1, fValue2, iPat;
00251 iPat = Msat_IntVecReadEntry( p->vPatsReal, Msat_IntVecReadSize(p->vPatsReal)-1 );
00252 fValue1 = (Fraig_BitStringHasBit( pOld->puSimD, iPat ));
00253 fValue2 = (Fraig_BitStringHasBit( pNew->puSimD, iPat ));
00254
00255
00256
00257
00258
00259
00260
00261 }
00262
00274 int Fraig_FeedBackCompress( Fraig_Man_t * p )
00275 {
00276 unsigned * pSims;
00277 unsigned uHash;
00278 int i, w, t, nPats, * pPats;
00279 int fPerformChecks = (p->nBTLimit == -1);
00280
00281
00282 if ( fPerformChecks )
00283 {
00284 Fraig_FeedBackCheckTable( p );
00285 if ( p->fDoSparse )
00286 Fraig_FeedBackCheckTableF0( p );
00287 }
00288
00289
00290 Fraig_FeedBackCovering( p, p->vPatsReal );
00291
00292
00293
00294 nPats = Msat_IntVecReadSize( p->vPatsReal );
00295 pPats = Msat_IntVecReadArray( p->vPatsReal );
00296
00297 p->iWordStart = FRAIG_NUM_WORDS( p->iPatsPerm + nPats );
00298
00299
00300 for ( i = 0; i < p->vInputs->nSize; i++ )
00301 {
00302
00303 pSims = p->vInputs->pArray[i]->puSimD;
00304
00305 for ( w = p->iWordPerm; w < p->iWordStart; w++ )
00306 p->pSimsTemp[w] = 0;
00307
00308 for ( t = 0; t < nPats; t++ )
00309 if ( Fraig_BitStringHasBit( pSims, pPats[t] ) )
00310 {
00311
00312 if ( p->iPatsPerm + t < p->iWordPerm * 32 )
00313 Fraig_BitStringSetBit( pSims, p->iPatsPerm + t );
00314 else
00315 Fraig_BitStringSetBit( p->pSimsTemp, p->iPatsPerm + t );
00316 }
00317
00318 for ( w = p->iWordPerm; w < p->iWordStart; w++ )
00319 pSims[w] = p->pSimsTemp[w];
00320
00321 uHash = 0;
00322 for ( w = 0; w < p->iWordStart; w++ )
00323 uHash ^= pSims[w] * s_FraigPrimes[w];
00324 p->vInputs->pArray[i]->uHashD = uHash;
00325 }
00326
00327
00328 p->iWordPerm = p->iWordStart;
00329 p->iPatsPerm += nPats;
00330 assert( p->iWordPerm == FRAIG_NUM_WORDS( p->iPatsPerm ) );
00331
00332
00333 for ( i = 1; i < p->vNodes->nSize; i++ )
00334 if ( Fraig_NodeIsAnd(p->vNodes->pArray[i]) )
00335 {
00336 p->vNodes->pArray[i]->uHashD = 0;
00337 Fraig_NodeSimulate( p->vNodes->pArray[i], 0, p->iWordPerm, 0 );
00338 }
00339
00340
00341 if ( fPerformChecks )
00342 Fraig_FeedBackCheckTable( p );
00343
00344
00345 if ( p->fDoSparse )
00346 {
00347 Fraig_TableRehashF0( p, 0 );
00348 if ( fPerformChecks )
00349 Fraig_FeedBackCheckTableF0( p );
00350 }
00351
00352
00353
00354 if ( p->iWordPerm + FRAIG_WORDS_STORE > p->nWordsDyna )
00355 Fraig_ReallocateSimulationInfo( p );
00356
00357
00358 Msat_IntVecClear( p->vPatsReal );
00359 memset( p->pSimsReal, 0, sizeof(unsigned)*p->nWordsDyna );
00360 for ( w = 0; w < p->iWordPerm; w++ )
00361 p->pSimsReal[w] = FRAIG_FULL;
00362 if ( p->iPatsPerm % 32 > 0 )
00363 p->pSimsReal[p->iWordPerm-1] = FRAIG_MASK( p->iPatsPerm % 32 );
00364
00365 return p->iWordStart;
00366 }
00367
00368
00369
00370
00382 void Fraig_FeedBackCovering( Fraig_Man_t * p, Msat_IntVec_t * vPats )
00383 {
00384 Fraig_NodeVec_t * vColumns;
00385 unsigned * pSims;
00386 int * pHits, iPat, iCol, i;
00387 int nOnesTotal, nSolStarting;
00388 int fVeryVerbose = 0;
00389
00390
00391 vColumns = Fraig_FeedBackCoveringStart( p );
00392
00393 nOnesTotal = 0;
00394 pHits = ALLOC( int, vColumns->nSize );
00395 for ( i = 0; i < vColumns->nSize; i++ )
00396 {
00397 pSims = (unsigned *)vColumns->pArray[i];
00398 pHits[i] = Fraig_BitStringCountOnes( pSims, p->iWordStart );
00399 nOnesTotal += pHits[i];
00400
00401 }
00402
00403
00404 nSolStarting = Msat_IntVecReadSize(vPats);
00405 while ( (iCol = Fraig_GetSmallestColumn( pHits, vColumns->nSize )) != -1 )
00406 {
00407
00408 iPat = Fraig_GetHittingPattern( (unsigned *)vColumns->pArray[iCol], p->iWordStart );
00409
00410 Fraig_CancelCoveredColumns( vColumns, pHits, iPat );
00411
00412 Msat_IntVecPush( vPats, iPat );
00413 }
00414
00415
00416 for ( i = 0; i < vColumns->nSize; i++ )
00417 Fraig_MemFixedEntryRecycle( p->mmSims, (char *)vColumns->pArray[i] );
00418
00419
00420 if ( p->fVerbose && fVeryVerbose )
00421 {
00422 printf( "%3d\\%3d\\%3d ", p->nWordsRand, p->nWordsDyna, p->iWordPerm );
00423 printf( "Col (pairs) = %5d. ", vColumns->nSize );
00424 printf( "Row (pats) = %5d. ", p->iWordStart * 32 );
00425 printf( "Dns = %6.2f %%. ", vColumns->nSize==0? 0.0 : 100.0 * nOnesTotal / vColumns->nSize / p->iWordStart / 32 );
00426 printf( "Sol = %3d (%3d). ", Msat_IntVecReadSize(vPats), nSolStarting );
00427 printf( "\n" );
00428 }
00429 Fraig_NodeVecFree( vColumns );
00430 free( pHits );
00431 }
00432
00433
00445 Fraig_NodeVec_t * Fraig_FeedBackCoveringStart( Fraig_Man_t * p )
00446 {
00447 Fraig_NodeVec_t * vColumns;
00448 Fraig_HashTable_t * pT = p->pTableF;
00449 Fraig_Node_t * pEntF, * pEntD;
00450 unsigned * pSims;
00451 unsigned * pUnsigned1, * pUnsigned2;
00452 int i, k, m, w;
00453
00454
00455 vColumns = Fraig_NodeVecAlloc( 100 );
00456
00457
00458 for ( i = 0; i < pT->nBins; i++ )
00459 Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
00460 {
00461 p->vCones->nSize = 0;
00462 Fraig_TableBinForEachEntryD( pEntF, pEntD )
00463 Fraig_NodeVecPush( p->vCones, pEntD );
00464 if ( p->vCones->nSize == 1 )
00465 continue;
00467 if ( p->vCones->nSize > 20 )
00468 continue;
00470
00471 for ( k = 0; k < p->vCones->nSize; k++ )
00472 for ( m = k+1; m < p->vCones->nSize; m++ )
00473 {
00474 if ( !Fraig_CompareSimInfoUnderMask( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0, p->pSimsReal ) )
00475 continue;
00476
00477
00478
00479 pSims = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
00480
00481 pUnsigned1 = p->vCones->pArray[k]->puSimD;
00482 pUnsigned2 = p->vCones->pArray[m]->puSimD;
00483 for ( w = 0; w < p->iWordStart; w++ )
00484 pSims[w] = (pUnsigned1[w] ^ pUnsigned2[w]) & ~p->pSimsReal[w];
00485
00486 Fraig_NodeVecPush( vColumns, (Fraig_Node_t *)pSims );
00487
00488
00489 }
00490 }
00491
00492
00493 if ( !p->fDoSparse )
00494 return vColumns;
00495
00496
00497 pT = p->pTableF0;
00498 for ( i = 0; i < pT->nBins; i++ )
00499 Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
00500 {
00501 pSims = pEntF->puSimD;
00502 pEntF->uHashD = 0;
00503 for ( w = 0; w < p->iWordStart; w++ )
00504 pEntF->uHashD ^= (pSims[w] & p->pSimsReal[w]) * s_FraigPrimes[w];
00505 }
00506
00507
00508 Fraig_TableRehashF0( p, 1 );
00509
00510
00511 for ( i = 0; i < pT->nBins; i++ )
00512 Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
00513 {
00514 p->vCones->nSize = 0;
00515 Fraig_TableBinForEachEntryD( pEntF, pEntD )
00516 Fraig_NodeVecPush( p->vCones, pEntD );
00517 if ( p->vCones->nSize == 1 )
00518 continue;
00519
00520
00521 for ( k = 0; k < p->vCones->nSize; k++ )
00522 for ( m = k+1; m < p->vCones->nSize; m++ )
00523 {
00524
00525 pSims = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
00526
00527 pUnsigned1 = p->vCones->pArray[k]->puSimD;
00528 pUnsigned2 = p->vCones->pArray[m]->puSimD;
00529 for ( w = 0; w < p->iWordStart; w++ )
00530 pSims[w] = (pUnsigned1[w] ^ pUnsigned2[w]) & ~p->pSimsReal[w];
00531
00532 Fraig_NodeVecPush( vColumns, (Fraig_Node_t *)pSims );
00533
00534
00535 }
00536 }
00537 return vColumns;
00538 }
00539
00551 int Fraig_GetSmallestColumn( int * pHits, int nHits )
00552 {
00553 int i, iColMin = -1, nHitsMin = 1000000;
00554 for ( i = 0; i < nHits; i++ )
00555 {
00556
00557 if ( pHits[i] == 0 )
00558 continue;
00559
00560 if ( pHits[i] == 1 )
00561 return i;
00562
00563 if ( nHitsMin > pHits[i] )
00564 {
00565 nHitsMin = pHits[i];
00566 iColMin = i;
00567 }
00568 }
00569 return iColMin;
00570 }
00571
00583 int Fraig_GetHittingPattern( unsigned * pSims, int nWords )
00584 {
00585 int i, b;
00586 for ( i = 0; i < nWords; i++ )
00587 {
00588 if ( pSims[i] == 0 )
00589 continue;
00590 for ( b = 0; b < 32; b++ )
00591 if ( pSims[i] & (1 << b) )
00592 return i * 32 + b;
00593 }
00594 return -1;
00595 }
00596
00608 void Fraig_CancelCoveredColumns( Fraig_NodeVec_t * vColumns, int * pHits, int iPat )
00609 {
00610 unsigned * pSims;
00611 int i;
00612 for ( i = 0; i < vColumns->nSize; i++ )
00613 {
00614 pSims = (unsigned *)vColumns->pArray[i];
00615 if ( Fraig_BitStringHasBit( pSims, iPat ) )
00616 pHits[i] = 0;
00617 }
00618 }
00619
00620
00632 void Fraig_FeedBackCheckTable( Fraig_Man_t * p )
00633 {
00634 Fraig_HashTable_t * pT = p->pTableF;
00635 Fraig_Node_t * pEntF, * pEntD;
00636 int i, k, m, nPairs;
00637 int clk = clock();
00638
00639 nPairs = 0;
00640 for ( i = 0; i < pT->nBins; i++ )
00641 Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
00642 {
00643 p->vCones->nSize = 0;
00644 Fraig_TableBinForEachEntryD( pEntF, pEntD )
00645 Fraig_NodeVecPush( p->vCones, pEntD );
00646 if ( p->vCones->nSize == 1 )
00647 continue;
00648 for ( k = 0; k < p->vCones->nSize; k++ )
00649 for ( m = k+1; m < p->vCones->nSize; m++ )
00650 {
00651 if ( Fraig_CompareSimInfo( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0 ) )
00652 printf( "Nodes %d and %d have the same D simulation info.\n",
00653 p->vCones->pArray[k]->Num, p->vCones->pArray[m]->Num );
00654 nPairs++;
00655 }
00656 }
00657
00658 }
00659
00671 void Fraig_FeedBackCheckTableF0( Fraig_Man_t * p )
00672 {
00673 Fraig_HashTable_t * pT = p->pTableF0;
00674 Fraig_Node_t * pEntF;
00675 int i, k, m, nPairs;
00676
00677 nPairs = 0;
00678 for ( i = 0; i < pT->nBins; i++ )
00679 {
00680 p->vCones->nSize = 0;
00681 Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
00682 Fraig_NodeVecPush( p->vCones, pEntF );
00683 if ( p->vCones->nSize == 1 )
00684 continue;
00685 for ( k = 0; k < p->vCones->nSize; k++ )
00686 for ( m = k+1; m < p->vCones->nSize; m++ )
00687 {
00688 if ( Fraig_CompareSimInfo( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0 ) )
00689 printf( "Nodes %d and %d have the same D simulation info.\n",
00690 p->vCones->pArray[k]->Num, p->vCones->pArray[m]->Num );
00691 nPairs++;
00692 }
00693 }
00694
00695 }
00696
00708 void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p )
00709 {
00710 Fraig_MemFixed_t * mmSimsNew;
00711 Fraig_Node_t * pNode;
00712 unsigned * pSimsNew;
00713 unsigned uSignOld;
00714 int i;
00715
00716
00717 p->nWordsDyna *= 2;
00718 mmSimsNew = Fraig_MemFixedStart( sizeof(unsigned) * (p->nWordsRand + p->nWordsDyna) );
00719
00720
00721 pNode = p->pConst1;
00722 pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
00723 pNode->puSimD = pNode->puSimR + p->nWordsRand;
00724 memset( pNode->puSimR, 0, sizeof(unsigned) * p->nWordsRand );
00725 memset( pNode->puSimD, 0, sizeof(unsigned) * p->nWordsDyna );
00726
00727
00728 for ( i = 0; i < p->vInputs->nSize; i++ )
00729 {
00730 pNode = p->vInputs->pArray[i];
00731
00732 pSimsNew = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
00733 memmove( pSimsNew, pNode->puSimR, sizeof(unsigned) * (p->nWordsRand + p->iWordStart) );
00734
00735 pNode->puSimR = pSimsNew;
00736 pNode->puSimD = pNode->puSimR + p->nWordsRand;
00737
00738 }
00739
00740
00741 Fraig_MemFixedStop( p->mmSims, 0 );
00742 p->mmSims = mmSimsNew;
00743
00744
00745 for ( i = 1; i < p->vNodes->nSize; i++ )
00746 {
00747 pNode = p->vNodes->pArray[i];
00748 if ( !Fraig_NodeIsAnd(pNode) )
00749 continue;
00750
00751 pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
00752 pNode->puSimD = pNode->puSimR + p->nWordsRand;
00753
00754 uSignOld = pNode->uHashR;
00755 pNode->uHashR = 0;
00756 Fraig_NodeSimulate( pNode, 0, p->nWordsRand, 1 );
00757 assert( uSignOld == pNode->uHashR );
00758
00759 uSignOld = pNode->uHashD;
00760 pNode->uHashD = 0;
00761 Fraig_NodeSimulate( pNode, 0, p->iWordStart, 0 );
00762 assert( uSignOld == pNode->uHashD );
00763 }
00764
00765
00766 p->pSimsReal = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
00767 memset( p->pSimsReal, 0, sizeof(unsigned) * p->nWordsDyna );
00768 p->pSimsTemp = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
00769 p->pSimsDiff = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
00770 }
00771
00772
00784 int * Fraig_ManAllocCounterExample( Fraig_Man_t * p )
00785 {
00786 int * pModel;
00787 pModel = ALLOC( int, p->vInputs->nSize );
00788 memset( pModel, 0, sizeof(int) * p->vInputs->nSize );
00789 return pModel;
00790 }
00791
00792
00804 int Fraig_ManSimulateBitNode_rec( Fraig_Man_t * p, Fraig_Node_t * pNode )
00805 {
00806 int Value0, Value1;
00807 if ( Fraig_NodeIsTravIdCurrent( p, pNode ) )
00808 return pNode->fMark3;
00809 Fraig_NodeSetTravIdCurrent( p, pNode );
00810 Value0 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p1) );
00811 Value1 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p2) );
00812 Value0 ^= Fraig_IsComplement(pNode->p1);
00813 Value1 ^= Fraig_IsComplement(pNode->p2);
00814 pNode->fMark3 = Value0 & Value1;
00815 return pNode->fMark3;
00816 }
00817
00829 int Fraig_ManSimulateBitNode( Fraig_Man_t * p, Fraig_Node_t * pNode, int * pModel )
00830 {
00831 int fCompl, RetValue, i;
00832
00833 Fraig_ManIncrementTravId( p );
00834 for ( i = 0; i < p->vInputs->nSize; i++ )
00835 {
00836 Fraig_NodeSetTravIdCurrent( p, p->vInputs->pArray[i] );
00837 p->vInputs->pArray[i]->fMark3 = pModel[i];
00838 }
00839
00840 fCompl = Fraig_IsComplement(pNode);
00841 RetValue = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode) );
00842 return fCompl ^ RetValue;
00843 }
00844
00845
00857 int * Fraig_ManSaveCounterExample( Fraig_Man_t * p, Fraig_Node_t * pNode )
00858 {
00859 int * pModel;
00860 int iPattern;
00861 int i, fCompl;
00862
00863
00864 fCompl = Fraig_IsComplement(pNode);
00865
00866 fCompl = !fCompl;
00867
00868
00869 pModel = Fraig_ManAllocCounterExample( p );
00870 iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->nWordsRand, 1 );
00871 if ( iPattern >= 0 )
00872 {
00873 for ( i = 0; i < p->vInputs->nSize; i++ )
00874 if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimR, iPattern ) )
00875 pModel[i] = 1;
00876
00877
00878
00879
00880
00881
00882 assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) );
00883 return pModel;
00884 }
00885 iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->iWordStart, 0 );
00886 if ( iPattern >= 0 )
00887 {
00888 for ( i = 0; i < p->vInputs->nSize; i++ )
00889 if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimD, iPattern ) )
00890 pModel[i] = 1;
00891
00892
00893
00894
00895
00896
00897 assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) );
00898 return pModel;
00899 }
00900 FREE( pModel );
00901 return NULL;
00902 }
00903
00904
00908
00909