00001
00019 #include "fraigInt.h"
00020 #include "math.h"
00021
00025
00026 static void Fraig_OrderVariables( Fraig_Man_t * pMan, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
00027 static void Fraig_SetupAdjacent( Fraig_Man_t * pMan, Msat_IntVec_t * vConeVars );
00028 static void Fraig_SetupAdjacentMark( Fraig_Man_t * pMan, Msat_IntVec_t * vConeVars );
00029 static void Fraig_PrepareCones( Fraig_Man_t * pMan, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
00030 static void Fraig_PrepareCones_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
00031
00032 static void Fraig_SupergateAddClauses( Fraig_Man_t * pMan, Fraig_Node_t * pNode, Fraig_NodeVec_t * vSuper );
00033 static void Fraig_SupergateAddClausesExor( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
00034 static void Fraig_SupergateAddClausesMux( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
00035
00036 static void Fraig_DetectFanoutFreeConeMux( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
00037 static void Fraig_SetActivity( Fraig_Man_t * pMan, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
00038
00039 extern void * Msat_ClauseVecReadEntry( void * p, int i );
00040
00041
00042
00043
00044
00045
00046 static int nMuxes;
00047
00051
00063 int Fraig_NodesAreEqual( Fraig_Man_t * p, Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int nBTLimit, int nTimeLimit )
00064 {
00065 if ( pNode1 == pNode2 )
00066 return 1;
00067 if ( pNode1 == Fraig_Not(pNode2) )
00068 return 0;
00069 return Fraig_NodeIsEquivalent( p, Fraig_Regular(pNode1), Fraig_Regular(pNode2), nBTLimit, nTimeLimit );
00070 }
00071
00083 void Fraig_ManProveMiter( Fraig_Man_t * p )
00084 {
00085 Fraig_Node_t * pNode;
00086 int i, clk;
00087
00088 if ( !p->fTryProve )
00089 return;
00090
00091 clk = clock();
00092
00093 for ( i = 0; i < p->vOutputs->nSize; i++ )
00094 {
00095 pNode = Fraig_Regular(p->vOutputs->pArray[i]);
00096
00097 if ( pNode == p->pConst1 )
00098 continue;
00099
00100 if ( !Fraig_CompareSimInfo( pNode, p->pConst1, p->nWordsRand, 1 ) )
00101 continue;
00102 if ( Fraig_NodeIsEquivalent( p, p->pConst1, pNode, -1, p->nSeconds ) )
00103 {
00104 if ( Fraig_IsComplement(p->vOutputs->pArray[i]) ^ Fraig_NodeComparePhase(p->pConst1, pNode) )
00105 p->vOutputs->pArray[i] = Fraig_Not(p->pConst1);
00106 else
00107 p->vOutputs->pArray[i] = p->pConst1;
00108 }
00109 }
00110 if ( p->fVerboseP )
00111 {
00112
00113 }
00114 }
00115
00127 int Fraig_ManCheckMiter( Fraig_Man_t * p )
00128 {
00129 Fraig_Node_t * pNode;
00130 int i;
00131 FREE( p->pModel );
00132 for ( i = 0; i < p->vOutputs->nSize; i++ )
00133 {
00134
00135 pNode = p->vOutputs->pArray[i];
00136
00137 if ( pNode == Fraig_Not(p->pConst1) )
00138 continue;
00139
00140 if ( pNode == p->pConst1 )
00141 {
00142
00143
00144 p->pModel = Fraig_ManAllocCounterExample( p );
00145 return 0;
00146 }
00147
00148 p->pModel = Fraig_ManSaveCounterExample( p, pNode );
00149
00150 if ( p->pModel == NULL )
00151 return -1;
00152 else
00153 return 0;
00154 }
00155 return 1;
00156 }
00157
00158
00170 int Fraig_MarkTfi_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00171 {
00172
00173 if ( pNode->TravId == pMan->nTravIds )
00174 return 0;
00175 pNode->TravId = pMan->nTravIds;
00176
00177 if ( pNode->NumPi >= 0 )
00178 return 1;
00179
00180 return Fraig_MarkTfi_rec( pMan, Fraig_Regular(pNode->p1) ) +
00181 Fraig_MarkTfi_rec( pMan, Fraig_Regular(pNode->p2) );
00182 }
00183
00195 int Fraig_MarkTfi2_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00196 {
00197
00198 if ( pNode->TravId == pMan->nTravIds )
00199 return 0;
00200
00201 if ( pNode->TravId == pMan->nTravIds-1 )
00202 {
00203 pNode->TravId = pMan->nTravIds;
00204 return 1;
00205 }
00206 pNode->TravId = pMan->nTravIds;
00207
00208 if ( pNode->NumPi >= 0 )
00209 return 1;
00210
00211 return Fraig_MarkTfi2_rec( pMan, Fraig_Regular(pNode->p1) ) +
00212 Fraig_MarkTfi2_rec( pMan, Fraig_Regular(pNode->p2) );
00213 }
00214
00226 int Fraig_MarkTfi3_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00227 {
00228
00229 if ( pNode->TravId == pMan->nTravIds )
00230 return 1;
00231
00232 if ( pNode->TravId == pMan->nTravIds-1 )
00233 {
00234 pNode->TravId = pMan->nTravIds;
00235 return 1;
00236 }
00237 pNode->TravId = pMan->nTravIds;
00238
00239 if ( pNode->NumPi >= 0 )
00240 return 0;
00241
00242 return Fraig_MarkTfi3_rec( pMan, Fraig_Regular(pNode->p1) ) *
00243 Fraig_MarkTfi3_rec( pMan, Fraig_Regular(pNode->p2) );
00244 }
00245
00257 void Fraig_VarsStudy( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
00258 {
00259 int NumPis, NumCut, fContain;
00260
00261
00262 p->nTravIds++;
00263 NumPis = Fraig_MarkTfi_rec( p, pNew );
00264 printf( "(%d)(%d,%d):", NumPis, pOld->Level, pNew->Level );
00265
00266
00267 if ( pOld->TravId == p->nTravIds )
00268 {
00269 printf( "* " );
00270 return;
00271 }
00272
00273
00274 p->nTravIds++;
00275 NumCut = Fraig_MarkTfi2_rec( p, pOld );
00276 printf( "%d", NumCut );
00277
00278
00279 p->nTravIds++;
00280 fContain = Fraig_MarkTfi3_rec( p, pNew );
00281 printf( "%c ", fContain? '+':'-' );
00282 }
00283
00284
00299 int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew, int nBTLimit, int nTimeLimit )
00300 {
00301 int RetValue, RetValue1, i, fComp, clk;
00302 int fVerbose = 0;
00303 int fSwitch = 0;
00304
00305
00306 assert( !Fraig_IsComplement(pNew) );
00307 assert( !Fraig_IsComplement(pOld) );
00308 assert( pNew != pOld );
00309
00310
00311
00312
00313 if ( nBTLimit > 0 && (pOld->fFailTfo || pNew->fFailTfo) )
00314 {
00315 p->nSatFails++;
00316
00317
00318
00319 if ( nBTLimit <= 10 )
00320 return 0;
00321 nBTLimit = (int)sqrt(nBTLimit);
00322
00323 }
00324
00325 p->nSatCalls++;
00326
00327
00328 if ( p->pSat == NULL )
00329 Fraig_ManCreateSolver( p );
00330
00331 for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
00332 Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 nMuxes = 0;
00345
00346
00347
00348 clk = clock();
00349
00350 Fraig_OrderVariables( p, pOld, pNew );
00351
00352 p->timeTrav += clock() - clk;
00353
00354
00355
00356
00357 if ( fVerbose )
00358 printf( "%d(%d) - ", Fraig_CountPis(p,p->vVarsInt), Msat_IntVecReadSize(p->vVarsInt) );
00359
00360
00361
00362 Fraig_SetActivity( p, pOld, pNew );
00363
00364
00365 fComp = Fraig_NodeComparePhase( pOld, pNew );
00366
00367
00369
00370
00371 Msat_SolverPrepare( p->pSat, p->vVarsInt );
00372
00373
00374
00375
00376
00377 Msat_IntVecClear( p->vProj );
00378 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 0) );
00379 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, !fComp) );
00380
00381
00382
00383
00384 clk = clock();
00385 RetValue1 = Msat_SolverSolve( p->pSat, p->vProj, nBTLimit, nTimeLimit );
00386 p->timeSat += clock() - clk;
00387
00388 if ( RetValue1 == MSAT_FALSE )
00389 {
00390
00391
00392 if ( fVerbose )
00393 {
00394 printf( "unsat %d ", Msat_SolverReadBackTracks(p->pSat) );
00395 PRT( "time", clock() - clk );
00396 }
00397
00398
00399 Msat_IntVecClear( p->vProj );
00400 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 1) );
00401 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, fComp) );
00402 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
00403 assert( RetValue );
00404
00405 }
00406 else if ( RetValue1 == MSAT_TRUE )
00407 {
00408
00409
00410 if ( fVerbose )
00411 {
00412 printf( "sat %d ", Msat_SolverReadBackTracks(p->pSat) );
00413 PRT( "time", clock() - clk );
00414 }
00415
00416
00417 Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
00418
00419
00420
00421
00422 if ( fSwitch )
00423 printf( "s(%d)", pNew->Level );
00424 p->nSatCounter++;
00425 return 0;
00426 }
00427 else
00428 {
00429 p->time3 += clock() - clk;
00430
00431
00432
00433
00434
00435
00436 if ( pOld != p->pConst1 )
00437 pOld->fFailTfo = 1;
00438 pNew->fFailTfo = 1;
00439
00440 if ( fSwitch )
00441 printf( "T(%d)", pNew->Level );
00442 p->nSatFailsReal++;
00443 return 0;
00444 }
00445
00446
00447 if ( pOld == p->pConst1 )
00448 return 1;
00449
00451
00452
00453 Msat_SolverPrepare( p->pSat, p->vVarsInt );
00454
00455
00456
00457 Msat_IntVecClear( p->vProj );
00458 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 1) );
00459 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, fComp) );
00460
00461 clk = clock();
00462 RetValue1 = Msat_SolverSolve( p->pSat, p->vProj, nBTLimit, nTimeLimit );
00463 p->timeSat += clock() - clk;
00464
00465 if ( RetValue1 == MSAT_FALSE )
00466 {
00467
00468
00469 if ( fVerbose )
00470 {
00471 printf( "unsat %d ", Msat_SolverReadBackTracks(p->pSat) );
00472 PRT( "time", clock() - clk );
00473 }
00474
00475
00476 Msat_IntVecClear( p->vProj );
00477 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 0) );
00478 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, !fComp) );
00479 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
00480 assert( RetValue );
00481
00482 }
00483 else if ( RetValue1 == MSAT_TRUE )
00484 {
00485
00486
00487 if ( fVerbose )
00488 {
00489 printf( "sat %d ", Msat_SolverReadBackTracks(p->pSat) );
00490 PRT( "time", clock() - clk );
00491 }
00492
00493
00494 Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
00495 p->nSatCounter++;
00496
00497
00498
00499
00500 if ( fSwitch )
00501 printf( "s(%d)", pNew->Level );
00502 return 0;
00503 }
00504 else
00505 {
00506 p->time3 += clock() - clk;
00507
00508
00509
00510
00511 if ( fSwitch )
00512 printf( "T(%d)", pNew->Level );
00513
00514
00515 pOld->fFailTfo = 1;
00516 pNew->fFailTfo = 1;
00517
00518 p->nSatFailsReal++;
00519 return 0;
00520 }
00521
00522
00523 p->nSatProof++;
00524
00525
00526
00527
00528
00529 if ( fSwitch )
00530 printf( "u(%d)", pNew->Level );
00531
00532 return 1;
00533 }
00534
00535
00547 int Fraig_NodeIsImplication( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew, int nBTLimit )
00548 {
00549 int RetValue, RetValue1, i, fComp, clk;
00550 int fVerbose = 0;
00551
00552
00553 assert( !Fraig_IsComplement(pNew) );
00554 assert( !Fraig_IsComplement(pOld) );
00555 assert( pNew != pOld );
00556
00557 p->nSatCallsImp++;
00558
00559
00560 if ( p->pSat == NULL )
00561 Fraig_ManCreateSolver( p );
00562
00563 for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
00564 Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
00565
00566
00567 clk = clock();
00568 Fraig_OrderVariables( p, pOld, pNew );
00569
00570 p->timeTrav += clock() - clk;
00571
00572 if ( fVerbose )
00573 printf( "%d(%d) - ", Fraig_CountPis(p,p->vVarsInt), Msat_IntVecReadSize(p->vVarsInt) );
00574
00575
00576
00577 fComp = Fraig_NodeComparePhase( pOld, pNew );
00578
00579
00581
00582
00583 Msat_SolverPrepare( p->pSat, p->vVarsInt );
00584
00585
00586
00587
00588 Msat_IntVecClear( p->vProj );
00589 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 0) );
00590 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, !fComp) );
00591
00592 clk = clock();
00593 RetValue1 = Msat_SolverSolve( p->pSat, p->vProj, nBTLimit, 1000000 );
00594 p->timeSat += clock() - clk;
00595
00596 if ( RetValue1 == MSAT_FALSE )
00597 {
00598
00599
00600 if ( fVerbose )
00601 {
00602 printf( "unsat %d ", Msat_SolverReadBackTracks(p->pSat) );
00603 PRT( "time", clock() - clk );
00604 }
00605
00606
00607 Msat_IntVecClear( p->vProj );
00608 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 1) );
00609 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, fComp) );
00610 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
00611 assert( RetValue );
00612
00613 return 1;
00614 }
00615 else if ( RetValue1 == MSAT_TRUE )
00616 {
00617
00618
00619 if ( fVerbose )
00620 {
00621 printf( "sat %d ", Msat_SolverReadBackTracks(p->pSat) );
00622 PRT( "time", clock() - clk );
00623 }
00624
00625 Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
00626 p->nSatCounterImp++;
00627 return 0;
00628 }
00629 else
00630 {
00631 p->time3 += clock() - clk;
00632 p->nSatFailsImp++;
00633 return 0;
00634 }
00635 }
00636
00648 int Fraig_ManCheckClauseUsingSat( Fraig_Man_t * p, Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int nBTLimit )
00649 {
00650 Fraig_Node_t * pNode1R, * pNode2R;
00651 int RetValue, RetValue1, i, clk;
00652 int fVerbose = 0;
00653
00654 pNode1R = Fraig_Regular(pNode1);
00655 pNode2R = Fraig_Regular(pNode2);
00656 assert( pNode1R != pNode2R );
00657
00658
00659 if ( p->pSat == NULL )
00660 Fraig_ManCreateSolver( p );
00661
00662 for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
00663 Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
00664
00665
00666 clk = clock();
00667 Fraig_OrderVariables( p, pNode1R, pNode2R );
00668
00669 p->timeTrav += clock() - clk;
00670
00672
00673
00674 Msat_SolverPrepare( p->pSat, p->vVarsInt );
00675
00676
00677
00678
00679 Msat_IntVecClear( p->vProj );
00680 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode1R->Num, !Fraig_IsComplement(pNode1)) );
00681 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode2R->Num, !Fraig_IsComplement(pNode2)) );
00682
00683 clk = clock();
00684 RetValue1 = Msat_SolverSolve( p->pSat, p->vProj, nBTLimit, 1000000 );
00685 p->timeSat += clock() - clk;
00686
00687 if ( RetValue1 == MSAT_FALSE )
00688 {
00689
00690
00691 if ( fVerbose )
00692 {
00693 printf( "unsat %d ", Msat_SolverReadBackTracks(p->pSat) );
00694 PRT( "time", clock() - clk );
00695 }
00696
00697
00698 Msat_IntVecClear( p->vProj );
00699 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode1R->Num, Fraig_IsComplement(pNode1)) );
00700 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode2R->Num, Fraig_IsComplement(pNode2)) );
00701 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
00702 assert( RetValue );
00703
00704 return 1;
00705 }
00706 else if ( RetValue1 == MSAT_TRUE )
00707 {
00708
00709
00710 if ( fVerbose )
00711 {
00712 printf( "sat %d ", Msat_SolverReadBackTracks(p->pSat) );
00713 PRT( "time", clock() - clk );
00714 }
00715
00716
00717 p->nSatCounterImp++;
00718 return 0;
00719 }
00720 else
00721 {
00722 p->time3 += clock() - clk;
00723 p->nSatFailsImp++;
00724 return 0;
00725 }
00726 }
00727
00728
00740 void Fraig_PrepareCones( Fraig_Man_t * pMan, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
00741 {
00742
00743
00744 int nVarsAlloc;
00745
00746 assert( pOld != pNew );
00747 assert( !Fraig_IsComplement(pOld) );
00748 assert( !Fraig_IsComplement(pNew) );
00749
00750 nVarsAlloc = Msat_IntVecReadSize(pMan->vVarsUsed);
00751 Msat_IntVecFill( pMan->vVarsUsed, nVarsAlloc, 0 );
00752 Msat_IntVecClear( pMan->vVarsInt );
00753
00754 pMan->nTravIds++;
00755 Fraig_PrepareCones_rec( pMan, pNew );
00756 Fraig_PrepareCones_rec( pMan, pOld );
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 }
00775
00787 void Fraig_PrepareCones_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
00788 {
00789 Fraig_Node_t * pFanin;
00790 Msat_IntVec_t * vAdjs;
00791 int fUseMuxes = 1, i;
00792 int fItIsTime;
00793
00794
00795 assert( !Fraig_IsComplement(pNode) );
00796 if ( pNode->TravId == pMan->nTravIds )
00797 return;
00798 pNode->TravId = pMan->nTravIds;
00799
00800
00801 Msat_IntVecPush( pMan->vVarsInt, pNode->Num );
00802 Msat_IntVecWriteEntry( pMan->vVarsUsed, pNode->Num, 1 );
00803 if ( !Fraig_NodeIsAnd( pNode ) )
00804 return;
00805
00806
00807 fItIsTime = 0;
00808 if ( pNode->vFanins == NULL )
00809 {
00810 fItIsTime = 1;
00811
00812 assert( pNode->fClauses == 0 );
00813 if ( fUseMuxes && Fraig_NodeIsMuxType(pNode) )
00814 {
00815 pNode->vFanins = Fraig_NodeVecAlloc( 4 );
00816 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p1)->p1) );
00817 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p1)->p2) );
00818 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p2)->p1) );
00819 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p2)->p2) );
00820 Fraig_SupergateAddClausesMux( pMan, pNode );
00821 }
00822 else
00823 {
00824 pNode->vFanins = Fraig_CollectSupergate( pNode, fUseMuxes );
00825 Fraig_SupergateAddClauses( pMan, pNode, pNode->vFanins );
00826 }
00827 assert( pNode->vFanins->nSize > 1 );
00828 pNode->fClauses = 1;
00829 pMan->nVarsClauses++;
00830
00831
00832 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pNode->Num );
00833 assert( Msat_IntVecReadSize( vAdjs ) == 0 );
00834 for ( i = 0; i < pNode->vFanins->nSize; i++ )
00835 {
00836 pFanin = Fraig_Regular(pNode->vFanins->pArray[i]);
00837 Msat_IntVecPush( vAdjs, pFanin->Num );
00838 }
00839 }
00840
00841
00842 for ( i = 0; i < pNode->vFanins->nSize; i++ )
00843 Fraig_PrepareCones_rec( pMan, Fraig_Regular(pNode->vFanins->pArray[i]) );
00844
00845 if ( fItIsTime )
00846 {
00847
00848 for ( i = 0; i < pNode->vFanins->nSize; i++ )
00849 {
00850 pFanin = Fraig_Regular(pNode->vFanins->pArray[i]);
00851 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pFanin->Num );
00852 Msat_IntVecPush( vAdjs, pNode->Num );
00853 }
00854 }
00855 }
00856
00869 void Fraig_OrderVariables( Fraig_Man_t * pMan, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
00870 {
00871 Fraig_Node_t * pNode, * pFanin;
00872 int i, k, Number, fUseMuxes = 1;
00873 int nVarsAlloc;
00874
00875 assert( pOld != pNew );
00876 assert( !Fraig_IsComplement(pOld) );
00877 assert( !Fraig_IsComplement(pNew) );
00878
00879 pMan->nTravIds++;
00880
00881
00882 nVarsAlloc = Msat_IntVecReadSize(pMan->vVarsUsed);
00883 Msat_IntVecFill( pMan->vVarsUsed, nVarsAlloc, 0 );
00884 Msat_IntVecClear( pMan->vVarsInt );
00885
00886
00887 Msat_IntVecPush( pMan->vVarsInt, pOld->Num );
00888 Msat_IntVecWriteEntry( pMan->vVarsUsed, pOld->Num, 1 );
00889 pOld->TravId = pMan->nTravIds;
00890
00891
00892 Msat_IntVecPush( pMan->vVarsInt, pNew->Num );
00893 Msat_IntVecWriteEntry( pMan->vVarsUsed, pNew->Num, 1 );
00894 pNew->TravId = pMan->nTravIds;
00895
00896
00897 for ( i = 0; i < Msat_IntVecReadSize(pMan->vVarsInt); i++ )
00898 {
00899
00900 Number = Msat_IntVecReadEntry(pMan->vVarsInt, i);
00901 pNode = pMan->vNodes->pArray[Number];
00902 if ( !Fraig_NodeIsAnd(pNode) )
00903 continue;
00904
00905
00906 if ( pNode->vFanins == NULL )
00907 {
00908
00909 assert( pNode->fClauses == 0 );
00910
00911
00912
00913 if ( fUseMuxes && Fraig_NodeIsMuxType(pNode) )
00914 {
00915 pNode->vFanins = Fraig_NodeVecAlloc( 4 );
00916 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p1)->p1) );
00917 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p1)->p2) );
00918 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p2)->p1) );
00919 Fraig_NodeVecPushUnique( pNode->vFanins, Fraig_Regular(Fraig_Regular(pNode->p2)->p2) );
00920 Fraig_SupergateAddClausesMux( pMan, pNode );
00921
00922
00923 nMuxes++;
00924 }
00925 else
00926 {
00927 pNode->vFanins = Fraig_CollectSupergate( pNode, fUseMuxes );
00928 Fraig_SupergateAddClauses( pMan, pNode, pNode->vFanins );
00929 }
00930 assert( pNode->vFanins->nSize > 1 );
00931 pNode->fClauses = 1;
00932 pMan->nVarsClauses++;
00933
00934 pNode->fMark2 = 1;
00935 }
00936
00937
00938 for ( k = 0; k < pNode->vFanins->nSize; k++ )
00939 {
00940 pFanin = Fraig_Regular(pNode->vFanins->pArray[k]);
00941 if ( pFanin->TravId == pMan->nTravIds )
00942 continue;
00943
00944 Msat_IntVecPush( pMan->vVarsInt, pFanin->Num );
00945 Msat_IntVecWriteEntry( pMan->vVarsUsed, pFanin->Num, 1 );
00946 pFanin->TravId = pMan->nTravIds;
00947 }
00948 }
00949
00950
00951
00952 Fraig_SetupAdjacentMark( pMan, pMan->vVarsInt );
00953 }
00954
00955
00956
00968 void Fraig_SetupAdjacent( Fraig_Man_t * pMan, Msat_IntVec_t * vConeVars )
00969 {
00970 Fraig_Node_t * pNode, * pFanin;
00971 Msat_IntVec_t * vAdjs;
00972 int * pVars, nVars, i, k;
00973
00974
00975 nVars = Msat_IntVecReadSize( vConeVars );
00976 pVars = Msat_IntVecReadArray( vConeVars );
00977 for ( i = 0; i < nVars; i++ )
00978 {
00979
00980 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pVars[i] );
00981 Msat_IntVecClear( vAdjs );
00982
00983 pNode = pMan->vNodes->pArray[pVars[i]];
00984 if ( !Fraig_NodeIsAnd(pNode) )
00985 continue;
00986
00987
00988 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pVars[i] );
00989 for ( k = 0; k < pNode->vFanins->nSize; k++ )
00990
00991 {
00992 pFanin = Fraig_Regular(pNode->vFanins->pArray[k]);
00993 Msat_IntVecPush( vAdjs, pFanin->Num );
00994
00995 }
00996 }
00997
00998 for ( i = 0; i < nVars; i++ )
00999 {
01000 pNode = pMan->vNodes->pArray[pVars[i]];
01001 if ( !Fraig_NodeIsAnd(pNode) )
01002 continue;
01003
01004
01005 for ( k = 0; k < pNode->vFanins->nSize; k++ )
01006
01007 {
01008 pFanin = Fraig_Regular(pNode->vFanins->pArray[k]);
01009 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pFanin->Num );
01010 Msat_IntVecPush( vAdjs, pNode->Num );
01011
01012 }
01013 }
01014 }
01015
01016
01028 void Fraig_SetupAdjacentMark( Fraig_Man_t * pMan, Msat_IntVec_t * vConeVars )
01029 {
01030 Fraig_Node_t * pNode, * pFanin;
01031 Msat_IntVec_t * vAdjs;
01032 int * pVars, nVars, i, k;
01033
01034
01035 nVars = Msat_IntVecReadSize( vConeVars );
01036 pVars = Msat_IntVecReadArray( vConeVars );
01037 for ( i = 0; i < nVars; i++ )
01038 {
01039 pNode = pMan->vNodes->pArray[pVars[i]];
01040 if ( pNode->fMark2 == 0 )
01041 continue;
01042
01043
01044
01045
01046
01047
01048 if ( !Fraig_NodeIsAnd(pNode) )
01049 continue;
01050
01051
01052 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pVars[i] );
01053 for ( k = 0; k < pNode->vFanins->nSize; k++ )
01054
01055 {
01056 pFanin = Fraig_Regular(pNode->vFanins->pArray[k]);
01057 Msat_IntVecPush( vAdjs, pFanin->Num );
01058
01059 }
01060 }
01061
01062 for ( i = 0; i < nVars; i++ )
01063 {
01064 pNode = pMan->vNodes->pArray[pVars[i]];
01065 if ( pNode->fMark2 == 0 )
01066 continue;
01067 pNode->fMark2 = 0;
01068
01069 if ( !Fraig_NodeIsAnd(pNode) )
01070 continue;
01071
01072
01073 for ( k = 0; k < pNode->vFanins->nSize; k++ )
01074
01075 {
01076 pFanin = Fraig_Regular(pNode->vFanins->pArray[k]);
01077 vAdjs = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( pMan->vAdjacents, pFanin->Num );
01078 Msat_IntVecPush( vAdjs, pNode->Num );
01079
01080 }
01081 }
01082 }
01083
01084
01085
01086
01098 void Fraig_SupergateAddClauses( Fraig_Man_t * p, Fraig_Node_t * pNode, Fraig_NodeVec_t * vSuper )
01099 {
01100 int fComp1, RetValue, nVars, Var, Var1, i;
01101
01102 assert( Fraig_NodeIsAnd( pNode ) );
01103 nVars = Msat_SolverReadVarNum(p->pSat);
01104
01105 Var = pNode->Num;
01106 assert( Var < nVars );
01107 for ( i = 0; i < vSuper->nSize; i++ )
01108 {
01109
01110
01111 fComp1 = Fraig_IsComplement(vSuper->pArray[i]);
01112
01113 Var1 = Fraig_Regular(vSuper->pArray[i])->Num;
01114
01115 assert( Var1 < nVars );
01116
01117
01118
01119
01120 Msat_IntVecClear( p->vProj );
01121 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(Var1, fComp1) );
01122 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(Var, 1) );
01123 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01124 assert( RetValue );
01125 }
01126
01127
01128
01129 Msat_IntVecClear( p->vProj );
01130 for ( i = 0; i < vSuper->nSize; i++ )
01131 {
01132
01133
01134 fComp1 = Fraig_IsComplement(vSuper->pArray[i]);
01135
01136 Var1 = Fraig_Regular(vSuper->pArray[i])->Num;
01137
01138
01139 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(Var1, !fComp1) );
01140 }
01141 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(Var, 0) );
01142 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01143 assert( RetValue );
01144 }
01145
01157 void Fraig_SupergateAddClausesExor( Fraig_Man_t * p, Fraig_Node_t * pNode )
01158 {
01159 Fraig_Node_t * pNode1, * pNode2;
01160 int fComp, RetValue;
01161
01162 assert( !Fraig_IsComplement( pNode ) );
01163 assert( Fraig_NodeIsExorType( pNode ) );
01164
01165 pNode1 = Fraig_Regular(Fraig_Regular(pNode->p1)->p1);
01166 pNode2 = Fraig_Regular(Fraig_Regular(pNode->p1)->p2);
01167
01168 fComp = Fraig_NodeIsExor( pNode );
01169
01170
01171 Msat_IntVecClear( p->vProj );
01172 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode->Num, fComp) );
01173 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode1->Num, fComp) );
01174 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode2->Num, fComp) );
01175 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01176 assert( RetValue );
01177 Msat_IntVecClear( p->vProj );
01178 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode->Num, fComp) );
01179 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode1->Num, !fComp) );
01180 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode2->Num, !fComp) );
01181 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01182 assert( RetValue );
01183 Msat_IntVecClear( p->vProj );
01184 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode->Num, !fComp) );
01185 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode1->Num, fComp) );
01186 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode2->Num, !fComp) );
01187 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01188 assert( RetValue );
01189 Msat_IntVecClear( p->vProj );
01190 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode->Num, !fComp) );
01191 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode1->Num, !fComp) );
01192 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNode2->Num, fComp) );
01193 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01194 assert( RetValue );
01195 }
01196
01208 void Fraig_SupergateAddClausesMux( Fraig_Man_t * p, Fraig_Node_t * pNode )
01209 {
01210 Fraig_Node_t * pNodeI, * pNodeT, * pNodeE;
01211 int RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
01212
01213 assert( !Fraig_IsComplement( pNode ) );
01214 assert( Fraig_NodeIsMuxType( pNode ) );
01215
01216 pNodeI = Fraig_NodeRecognizeMux( pNode, &pNodeT, &pNodeE );
01217
01218 VarF = pNode->Num;
01219 VarI = pNodeI->Num;
01220 VarT = Fraig_Regular(pNodeT)->Num;
01221 VarE = Fraig_Regular(pNodeE)->Num;
01222
01223 fCompT = Fraig_IsComplement(pNodeT);
01224 fCompE = Fraig_IsComplement(pNodeE);
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234 Msat_IntVecClear( p->vProj );
01235 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarI, 1) );
01236 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarT, 1^fCompT) );
01237 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarF, 0) );
01238 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01239 assert( RetValue );
01240 Msat_IntVecClear( p->vProj );
01241 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarI, 1) );
01242 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarT, 0^fCompT) );
01243 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarF, 1) );
01244 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01245 assert( RetValue );
01246 Msat_IntVecClear( p->vProj );
01247 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarI, 0) );
01248 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarE, 1^fCompE) );
01249 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarF, 0) );
01250 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01251 assert( RetValue );
01252 Msat_IntVecClear( p->vProj );
01253 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarI, 0) );
01254 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarE, 0^fCompE) );
01255 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarF, 1) );
01256 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01257 assert( RetValue );
01258
01259
01260
01261
01262
01263
01264
01265
01266 if ( VarT == VarE )
01267 {
01268
01269 return;
01270 }
01271
01272 Msat_IntVecClear( p->vProj );
01273 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarT, 0^fCompT) );
01274 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarE, 0^fCompE) );
01275 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarF, 1) );
01276 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01277 assert( RetValue );
01278 Msat_IntVecClear( p->vProj );
01279 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarT, 1^fCompT) );
01280 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarE, 1^fCompE) );
01281 Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(VarF, 0) );
01282 RetValue = Msat_SolverAddClause( p->pSat, p->vProj );
01283 assert( RetValue );
01284
01285 }
01286
01287
01288
01289
01290
01302 void Fraig_DetectFanoutFreeCone_rec( Fraig_Node_t * pNode, Fraig_NodeVec_t * vSuper, Fraig_NodeVec_t * vInside, int fFirst )
01303 {
01304
01305 pNode = Fraig_Regular(pNode);
01306
01307 if ( (!fFirst && pNode->nRefs > 1) || Fraig_NodeIsVar(pNode) )
01308 {
01309 Fraig_NodeVecPushUnique( vSuper, pNode );
01310 return;
01311 }
01312
01313 Fraig_DetectFanoutFreeCone_rec( pNode->p1, vSuper, vInside, 0 );
01314 Fraig_DetectFanoutFreeCone_rec( pNode->p2, vSuper, vInside, 0 );
01315
01316 Fraig_NodeVecPushUnique( vInside, pNode );
01317 }
01318
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01365 void Fraig_DetectFanoutFreeConeMux_rec( Fraig_Node_t * pNode, Fraig_NodeVec_t * vSuper, Fraig_NodeVec_t * vInside, int fFirst )
01366 {
01367
01368 pNode = Fraig_Regular(pNode);
01369
01370 if ( (!fFirst && pNode->nRefs > 1) || Fraig_NodeIsVar(pNode) || !Fraig_NodeIsMuxType(pNode) )
01371 {
01372 Fraig_NodeVecPushUnique( vSuper, pNode );
01373 return;
01374 }
01375
01376 Fraig_DetectFanoutFreeConeMux_rec( Fraig_Regular(pNode->p1)->p1, vSuper, vInside, 0 );
01377 Fraig_DetectFanoutFreeConeMux_rec( Fraig_Regular(pNode->p1)->p2, vSuper, vInside, 0 );
01378 Fraig_DetectFanoutFreeConeMux_rec( Fraig_Regular(pNode->p2)->p1, vSuper, vInside, 0 );
01379 Fraig_DetectFanoutFreeConeMux_rec( Fraig_Regular(pNode->p2)->p2, vSuper, vInside, 0 );
01380
01381 Fraig_NodeVecPushUnique( vInside, pNode );
01382 }
01383
01395 void Fraig_DetectFanoutFreeConeMux( Fraig_Man_t * pMan, Fraig_Node_t * pNode )
01396 {
01397 Fraig_NodeVec_t * vFanins;
01398 Fraig_NodeVec_t * vInside;
01399 int nCubes;
01400 extern int Fraig_CutSopCountCubes( Fraig_Man_t * pMan, Fraig_NodeVec_t * vFanins, Fraig_NodeVec_t * vInside );
01401
01402 vFanins = Fraig_NodeVecAlloc( 8 );
01403 vInside = Fraig_NodeVecAlloc( 8 );
01404
01405 Fraig_DetectFanoutFreeConeMux_rec( pNode, vFanins, vInside, 1 );
01406 assert( vInside->pArray[vInside->nSize-1] == pNode );
01407
01408
01409 nCubes = 0;
01410
01411 printf( "%d(%d)", vFanins->nSize, nCubes );
01412 Fraig_NodeVecFree( vFanins );
01413 Fraig_NodeVecFree( vInside );
01414 }
01415
01416
01417
01430 void Fraig_SetActivity( Fraig_Man_t * pMan, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
01431 {
01432 Fraig_Node_t * pNode;
01433 int i, Number, MaxLevel;
01434 float * pFactors = Msat_SolverReadFactors(pMan->pSat);
01435 if ( pFactors == NULL )
01436 return;
01437 MaxLevel = FRAIG_MAX( pOld->Level, pNew->Level );
01438
01439 for ( i = 0; i < Msat_IntVecReadSize(pMan->vVarsInt); i++ )
01440 {
01441
01442 Number = Msat_IntVecReadEntry(pMan->vVarsInt, i);
01443 pNode = pMan->vNodes->pArray[Number];
01444 pFactors[pNode->Num] = (float)pow( 0.97, MaxLevel - pNode->Level );
01445
01446
01447 }
01448
01449 }
01450
01454
01455