| #include <stdio.h> |
| #include "base/main/main.h" |
| #include "aig/aig/aig.h" |
| #include "aig/saig/saig.h" |
| #include <string.h> |
| #include "base/main/mainInt.h" |
| #include "proof/pdr/pdr.h" |
| #include <time.h> |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| long countCombination(long n, long k) |
| { |
| assert( n >= k ); |
| if( n == k ) return 1; |
| if( k == 1 ) return n; |
| return countCombination( n-1, k-1 ) + countCombination( n-1, k ); |
| } |
| |
| void listCombination(int n, int t) |
| { |
| Vec_Int_t *vC; |
| int i, j, combCounter = 0; |
| |
| //Initialization |
| vC = Vec_IntAlloc(t+3); |
| for(i=-1; i<t; i++) |
| Vec_IntPush( vC, i ); |
| Vec_IntPush( vC, n ); |
| Vec_IntPush( vC, 0 ); |
| |
| while(1) |
| { |
| //visit combination |
| printf("Comb-%3d : ", ++combCounter); |
| for( i=t; i>0; i--) |
| printf("vC[%d] = %d ", i, Vec_IntEntry(vC, i)); |
| printf("\n"); |
| |
| j = 1; |
| while( Vec_IntEntry( vC, j ) + 1 == Vec_IntEntry( vC, j+1 ) ) |
| { |
| //printf("\nGochon = %d, %d\n", Vec_IntEntry( vC, j ) + 1, Vec_IntEntry( vC, j+1 )); |
| Vec_IntWriteEntry( vC, j, j-1 ); |
| j = j + 1; |
| } |
| if( j > t ) break; |
| Vec_IntWriteEntry( vC, j, Vec_IntEntry( vC, j ) + 1 ); |
| } |
| |
| Vec_IntFree(vC); |
| } |
| |
| int generateCombinatorialStabil( Aig_Man_t *pAigNew, Aig_Man_t *pAigOld, |
| Vec_Int_t *vCandidateMonotoneSignals_, |
| Vec_Ptr_t *vDisj_nCk_, |
| int combN, int combK ) |
| { |
| Aig_Obj_t *pObjMonoCand, *pObj; |
| int targetPoIndex; |
| |
| //Knuth's Data Strcuture |
| int totalCombination_KNUTH = 0; |
| Vec_Int_t *vC_KNUTH; |
| int i_KNUTH, j_KNUTH; |
| |
| //Knuth's Data Structure Initialization |
| vC_KNUTH = Vec_IntAlloc(combK+3); |
| for(i_KNUTH=-1; i_KNUTH<combK; i_KNUTH++) |
| Vec_IntPush( vC_KNUTH, i_KNUTH ); |
| Vec_IntPush( vC_KNUTH, combN ); |
| Vec_IntPush( vC_KNUTH, 0 ); |
| |
| while(1) |
| { |
| totalCombination_KNUTH++; |
| pObjMonoCand = Aig_Not(Aig_ManConst1(pAigNew)); |
| for( i_KNUTH=combK; i_KNUTH>0; i_KNUTH--) |
| { |
| targetPoIndex = Vec_IntEntry( vCandidateMonotoneSignals_, Vec_IntEntry(vC_KNUTH, i_KNUTH)); |
| pObj = Aig_ObjChild0Copy(Aig_ManCo( pAigOld, targetPoIndex )); |
| pObjMonoCand = Aig_Or( pAigNew, pObj, pObjMonoCand ); |
| } |
| Vec_PtrPush(vDisj_nCk_, pObjMonoCand ); |
| |
| j_KNUTH = 1; |
| while( Vec_IntEntry( vC_KNUTH, j_KNUTH ) + 1 == Vec_IntEntry( vC_KNUTH, j_KNUTH+1 ) ) |
| { |
| Vec_IntWriteEntry( vC_KNUTH, j_KNUTH, j_KNUTH-1 ); |
| j_KNUTH = j_KNUTH + 1; |
| } |
| if( j_KNUTH > combK ) break; |
| Vec_IntWriteEntry( vC_KNUTH, j_KNUTH, Vec_IntEntry( vC_KNUTH, j_KNUTH ) + 1 ); |
| } |
| |
| Vec_IntFree(vC_KNUTH); |
| |
| return totalCombination_KNUTH; |
| } |
| |
| int generateCombinatorialStabilExhaust( Aig_Man_t *pAigNew, Aig_Man_t *pAigOld, |
| Vec_Ptr_t *vDisj_nCk_, |
| int combN, int combK ) |
| { |
| Aig_Obj_t *pObjMonoCand, *pObj; |
| int targetPoIndex; |
| |
| //Knuth's Data Strcuture |
| int totalCombination_KNUTH = 0; |
| Vec_Int_t *vC_KNUTH; |
| int i_KNUTH, j_KNUTH; |
| |
| //Knuth's Data Structure Initialization |
| vC_KNUTH = Vec_IntAlloc(combK+3); |
| for(i_KNUTH=-1; i_KNUTH<combK; i_KNUTH++) |
| Vec_IntPush( vC_KNUTH, i_KNUTH ); |
| Vec_IntPush( vC_KNUTH, combN ); |
| Vec_IntPush( vC_KNUTH, 0 ); |
| |
| while(1) |
| { |
| totalCombination_KNUTH++; |
| pObjMonoCand = Aig_Not(Aig_ManConst1(pAigNew)); |
| for( i_KNUTH=combK; i_KNUTH>0; i_KNUTH--) |
| { |
| //targetPoIndex = Vec_IntEntry( vCandidateMonotoneSignals_, Vec_IntEntry(vC_KNUTH, i_KNUTH)); |
| targetPoIndex = Vec_IntEntry(vC_KNUTH, i_KNUTH); |
| pObj = (Aig_Obj_t *)(Aig_ManLo( pAigOld, targetPoIndex )->pData); |
| pObjMonoCand = Aig_Or( pAigNew, pObj, pObjMonoCand ); |
| } |
| Vec_PtrPush(vDisj_nCk_, pObjMonoCand ); |
| |
| j_KNUTH = 1; |
| while( Vec_IntEntry( vC_KNUTH, j_KNUTH ) + 1 == Vec_IntEntry( vC_KNUTH, j_KNUTH+1 ) ) |
| { |
| Vec_IntWriteEntry( vC_KNUTH, j_KNUTH, j_KNUTH-1 ); |
| j_KNUTH = j_KNUTH + 1; |
| } |
| if( j_KNUTH > combK ) break; |
| Vec_IntWriteEntry( vC_KNUTH, j_KNUTH, Vec_IntEntry( vC_KNUTH, j_KNUTH ) + 1 ); |
| } |
| |
| Vec_IntFree(vC_KNUTH); |
| |
| return totalCombination_KNUTH; |
| } |
| |
| Aig_Man_t *generateDisjunctiveTester( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, int combN, int combK ) |
| { |
| //AIG creation related data structure |
| Aig_Man_t *pNewAig; |
| int piCopied = 0, loCopied = 0, loCreated = 0, liCopied = 0, liCreated = 0, poCopied = 0; |
| //int i, iElem, nRegCount, hintSingalBeginningMarker, hintSingalEndMarker; |
| int i, nRegCount, hintSingalBeginningMarker, hintSingalEndMarker; |
| int combN_internal, combK_internal; //, targetPoIndex; |
| long longI, lCombinationCount; |
| //Aig_Obj_t *pObj, *pObjMonoCand, *pObjLO_nCk, *pObjDisj_nCk; |
| Aig_Obj_t *pObj, *pObjLO_nCk, *pObjDisj_nCk; |
| Vec_Ptr_t *vLO_nCk, *vPODriver_nCk, *vDisj_nCk; |
| Vec_Int_t *vCandidateMonotoneSignals; |
| |
| extern Vec_Int_t *findHintOutputs(Abc_Ntk_t *pNtk); |
| |
| //Knuth's Data Strcuture |
| //Vec_Int_t *vC_KNUTH; |
| //int i_KNUTH, j_KNUTH, combCounter_KNUTH = 0; |
| |
| //Collecting target HINT signals |
| vCandidateMonotoneSignals = findHintOutputs(pNtk); |
| if( vCandidateMonotoneSignals == NULL ) |
| { |
| printf("\nTraget Signal Set is Empty: Duplicating given AIG\n"); |
| combN_internal = 0; |
| } |
| else |
| { |
| //Vec_IntForEachEntry( vCandidateMonotoneSignals, iElem, i ) |
| // printf("Po[%d] = %s\n", iElem, Abc_ObjName( Abc_NtkPo(pNtk, iElem) ) ); |
| hintSingalBeginningMarker = Vec_IntEntry( vCandidateMonotoneSignals, 0 ); |
| hintSingalEndMarker = Vec_IntEntry( vCandidateMonotoneSignals, Vec_IntSize(vCandidateMonotoneSignals) - 1 ); |
| combN_internal = hintSingalEndMarker - hintSingalBeginningMarker + 1; |
| } |
| |
| //combK_internal = combK; |
| |
| //Knuth's Data Structure Initialization |
| //vC_KNUTH = Vec_IntAlloc(combK_internal+3); |
| //for(i_KNUTH=-1; i_KNUTH<combK_internal; i_KNUTH++) |
| // Vec_IntPush( vC_KNUTH, i_KNUTH ); |
| //Vec_IntPush( vC_KNUTH, combN_internal ); |
| //Vec_IntPush( vC_KNUTH, 0 ); |
| |
| //Standard AIG duplication begins |
| //Standard AIG Manager Creation |
| pNewAig = Aig_ManStart( Aig_ManObjNumMax(pAig) ); |
| pNewAig->pName = (char *)malloc( strlen( pAig->pName ) + strlen("_nCk") + 1 ); |
| sprintf(pNewAig->pName, "%s_%s", pAig->pName, "nCk"); |
| pNewAig->pSpec = NULL; |
| |
| //Standard Mapping of Constant Nodes |
| pObj = Aig_ManConst1( pAig ); |
| pObj->pData = Aig_ManConst1( pNewAig ); |
| |
| //Standard AIG PI duplication |
| Saig_ManForEachPi( pAig, pObj, i ) |
| { |
| piCopied++; |
| pObj->pData = Aig_ObjCreateCi(pNewAig); |
| } |
| |
| //Standard AIG LO duplication |
| Saig_ManForEachLo( pAig, pObj, i ) |
| { |
| loCopied++; |
| pObj->pData = Aig_ObjCreateCi(pNewAig); |
| } |
| |
| //nCk LO creation |
| lCombinationCount = 0; |
| for(combK_internal=1; combK_internal<=combK; combK_internal++) |
| lCombinationCount += countCombination( combN_internal, combK_internal ); |
| assert( lCombinationCount > 0 ); |
| vLO_nCk = Vec_PtrAlloc(lCombinationCount); |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| loCreated++; |
| pObj = Aig_ObjCreateCi(pNewAig); |
| Vec_PtrPush( vLO_nCk, pObj ); |
| } |
| |
| //Standard Node duplication |
| Aig_ManForEachNode( pAig, pObj, i ) |
| { |
| pObj->pData = Aig_And( pNewAig, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); |
| } |
| |
| //nCk specific logic creation (i.e. nCk number of OR gates) |
| vDisj_nCk = Vec_PtrAlloc(lCombinationCount); |
| |
| |
| |
| //while(1) |
| //{ |
| // //visit combination |
| // //printf("Comb-%3d : ", ++combCounter_KNUTH); |
| // pObjMonoCand = Aig_Not(Aig_ManConst1(pNewAig)); |
| // for( i_KNUTH=combK_internal; i_KNUTH>0; i_KNUTH--) |
| // { |
| // //printf("vC[%d] = %d ", i_KNUTH, Vec_IntEntry(vC_KNUTH, i_KNUTH)); |
| // targetPoIndex = Vec_IntEntry( vCandidateMonotoneSignals, Vec_IntEntry(vC_KNUTH, i_KNUTH)); |
| // pObj = Aig_ObjChild0Copy(Aig_ManCo( pAig, targetPoIndex )); |
| // pObjMonoCand = Aig_Or( pNewAig, pObj, pObjMonoCand ); |
| // } |
| // Vec_PtrPush(vDisj_nCk, pObjMonoCand ); |
| // //printf("\n"); |
| |
| // j_KNUTH = 1; |
| // while( Vec_IntEntry( vC_KNUTH, j_KNUTH ) + 1 == Vec_IntEntry( vC_KNUTH, j_KNUTH+1 ) ) |
| // { |
| // Vec_IntWriteEntry( vC_KNUTH, j_KNUTH, j_KNUTH-1 ); |
| // j_KNUTH = j_KNUTH + 1; |
| // } |
| // if( j_KNUTH > combK_internal ) break; |
| // Vec_IntWriteEntry( vC_KNUTH, j_KNUTH, Vec_IntEntry( vC_KNUTH, j_KNUTH ) + 1 ); |
| //} |
| for( combK_internal=1; combK_internal<=combK; combK_internal++ ) |
| generateCombinatorialStabil( pNewAig, pAig, vCandidateMonotoneSignals, |
| vDisj_nCk, combN_internal, combK_internal ); |
| |
| |
| //creation of implication logic |
| vPODriver_nCk = Vec_PtrAlloc(lCombinationCount); |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| pObjLO_nCk = (Aig_Obj_t *)(Vec_PtrEntry( vLO_nCk, longI )); |
| pObjDisj_nCk = (Aig_Obj_t *)(Vec_PtrEntry( vDisj_nCk, longI )); |
| |
| pObj = Aig_Or( pNewAig, Aig_Not(pObjDisj_nCk), pObjLO_nCk); |
| Vec_PtrPush(vPODriver_nCk, pObj); |
| } |
| |
| //Standard PO duplication |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| poCopied++; |
| pObj->pData = Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) ); |
| } |
| |
| //nCk specific PO creation |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| Aig_ObjCreateCo( pNewAig, (Aig_Obj_t *)(Vec_PtrEntry( vPODriver_nCk, longI )) ); |
| } |
| |
| //Standard LI duplication |
| Saig_ManForEachLi( pAig, pObj, i ) |
| { |
| liCopied++; |
| Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) ); |
| } |
| |
| //nCk specific LI creation |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| liCreated++; |
| Aig_ObjCreateCo( pNewAig, (Aig_Obj_t *)(Vec_PtrEntry( vPODriver_nCk, longI )) ); |
| } |
| |
| //clean-up, book-keeping |
| assert( liCopied + liCreated == loCopied + loCreated ); |
| nRegCount = loCopied + loCreated; |
| |
| Aig_ManSetRegNum( pNewAig, nRegCount ); |
| Aig_ManCleanup( pNewAig ); |
| assert( Aig_ManCheck( pNewAig ) ); |
| |
| //Vec_IntFree(vC_KNUTH); |
| return pNewAig; |
| } |
| |
| Aig_Man_t *generateGeneralDisjunctiveTester( Abc_Ntk_t *pNtk, Aig_Man_t *pAig, int combK ) |
| { |
| //AIG creation related data structure |
| Aig_Man_t *pNewAig; |
| int piCopied = 0, loCopied = 0, loCreated = 0, liCopied = 0, liCreated = 0, poCopied = 0; |
| //int i, iElem, nRegCount, hintSingalBeginningMarker, hintSingalEndMarker; |
| int i, nRegCount; |
| int combN_internal, combK_internal; //, targetPoIndex; |
| long longI, lCombinationCount; |
| //Aig_Obj_t *pObj, *pObjMonoCand, *pObjLO_nCk, *pObjDisj_nCk; |
| Aig_Obj_t *pObj, *pObjLO_nCk, *pObjDisj_nCk; |
| Vec_Ptr_t *vLO_nCk, *vPODriver_nCk, *vDisj_nCk; |
| |
| extern Vec_Int_t *findHintOutputs(Abc_Ntk_t *pNtk); |
| |
| //Knuth's Data Strcuture |
| //Vec_Int_t *vC_KNUTH; |
| //int i_KNUTH, j_KNUTH, combCounter_KNUTH = 0; |
| |
| //Collecting target HINT signals |
| //vCandidateMonotoneSignals = findHintOutputs(pNtk); |
| //if( vCandidateMonotoneSignals == NULL ) |
| //{ |
| // printf("\nTraget Signal Set is Empty: Duplicating given AIG\n"); |
| // combN_internal = 0; |
| //} |
| //else |
| //{ |
| //Vec_IntForEachEntry( vCandidateMonotoneSignals, iElem, i ) |
| // printf("Po[%d] = %s\n", iElem, Abc_ObjName( Abc_NtkPo(pNtk, iElem) ) ); |
| // hintSingalBeginningMarker = Vec_IntEntry( vCandidateMonotoneSignals, 0 ); |
| // hintSingalEndMarker = Vec_IntEntry( vCandidateMonotoneSignals, Vec_IntSize(vCandidateMonotoneSignals) - 1 ); |
| // combN_internal = hintSingalEndMarker - hintSingalBeginningMarker + 1; |
| //} |
| |
| combN_internal = Aig_ManRegNum(pAig); |
| |
| pNewAig = Aig_ManStart( Aig_ManObjNumMax(pAig) ); |
| pNewAig->pName = (char *)malloc( strlen( pAig->pName ) + strlen("_nCk") + 1 ); |
| sprintf(pNewAig->pName, "%s_%s", pAig->pName, "nCk"); |
| pNewAig->pSpec = NULL; |
| |
| //Standard Mapping of Constant Nodes |
| pObj = Aig_ManConst1( pAig ); |
| pObj->pData = Aig_ManConst1( pNewAig ); |
| |
| //Standard AIG PI duplication |
| Saig_ManForEachPi( pAig, pObj, i ) |
| { |
| piCopied++; |
| pObj->pData = Aig_ObjCreateCi(pNewAig); |
| } |
| |
| //Standard AIG LO duplication |
| Saig_ManForEachLo( pAig, pObj, i ) |
| { |
| loCopied++; |
| pObj->pData = Aig_ObjCreateCi(pNewAig); |
| } |
| |
| //nCk LO creation |
| lCombinationCount = 0; |
| for(combK_internal=1; combK_internal<=combK; combK_internal++) |
| lCombinationCount += countCombination( combN_internal, combK_internal ); |
| assert( lCombinationCount > 0 ); |
| vLO_nCk = Vec_PtrAlloc(lCombinationCount); |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| loCreated++; |
| pObj = Aig_ObjCreateCi(pNewAig); |
| Vec_PtrPush( vLO_nCk, pObj ); |
| } |
| |
| //Standard Node duplication |
| Aig_ManForEachNode( pAig, pObj, i ) |
| { |
| pObj->pData = Aig_And( pNewAig, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); |
| } |
| |
| //nCk specific logic creation (i.e. nCk number of OR gates) |
| vDisj_nCk = Vec_PtrAlloc(lCombinationCount); |
| |
| for( combK_internal=1; combK_internal<=combK; combK_internal++ ) |
| { |
| generateCombinatorialStabilExhaust( pNewAig, pAig, |
| vDisj_nCk, combN_internal, combK_internal ); |
| } |
| |
| |
| //creation of implication logic |
| vPODriver_nCk = Vec_PtrAlloc(lCombinationCount); |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| pObjLO_nCk = (Aig_Obj_t *)(Vec_PtrEntry( vLO_nCk, longI )); |
| pObjDisj_nCk = (Aig_Obj_t *)(Vec_PtrEntry( vDisj_nCk, longI )); |
| |
| pObj = Aig_Or( pNewAig, Aig_Not(pObjDisj_nCk), pObjLO_nCk); |
| Vec_PtrPush(vPODriver_nCk, pObj); |
| } |
| |
| //Standard PO duplication |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| poCopied++; |
| pObj->pData = Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) ); |
| } |
| |
| //nCk specific PO creation |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| Aig_ObjCreateCo( pNewAig, (Aig_Obj_t *)(Vec_PtrEntry( vPODriver_nCk, longI )) ); |
| } |
| |
| //Standard LI duplication |
| Saig_ManForEachLi( pAig, pObj, i ) |
| { |
| liCopied++; |
| Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) ); |
| } |
| |
| //nCk specific LI creation |
| for( longI = 0; longI < lCombinationCount; longI++ ) |
| { |
| liCreated++; |
| Aig_ObjCreateCo( pNewAig, (Aig_Obj_t *)(Vec_PtrEntry( vPODriver_nCk, longI )) ); |
| } |
| |
| //clean-up, book-keeping |
| assert( liCopied + liCreated == loCopied + loCreated ); |
| nRegCount = loCopied + loCreated; |
| |
| Aig_ManSetRegNum( pNewAig, nRegCount ); |
| Aig_ManCleanup( pNewAig ); |
| assert( Aig_ManCheck( pNewAig ) ); |
| |
| Vec_PtrFree(vLO_nCk); |
| Vec_PtrFree(vPODriver_nCk); |
| Vec_PtrFree(vDisj_nCk); |
| //Vec_IntFree(vC_KNUTH); |
| return pNewAig; |
| } |
| |
| ABC_NAMESPACE_IMPL_END |