| /**CFile**************************************************************** |
| |
| FileName [luckySimple.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Semi-canonical form computation package.] |
| |
| Synopsis [Truth table minimization procedures.] |
| |
| Author [Jake] |
| |
| Date [Started - August 2012] |
| |
| ***********************************************************************/ |
| |
| #include "luckyInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| static swapInfo* setSwapInfoPtr(int varsN) |
| { |
| int i; |
| swapInfo* x = (swapInfo*) malloc(sizeof(swapInfo)); |
| x->posArray = (varInfo*) malloc (sizeof(varInfo)*(varsN+2)); |
| x->realArray = (int*) malloc (sizeof(int)*(varsN+2)); |
| x->varN = varsN; |
| x->realArray[0]=varsN+100; |
| for(i=1;i<=varsN;i++) |
| { |
| x->posArray[i].position=i; |
| x->posArray[i].direction=-1; |
| x->realArray[i]=i; |
| } |
| x->realArray[varsN+1]=varsN+10; |
| return x; |
| } |
| |
| |
| static void freeSwapInfoPtr(swapInfo* x) |
| { |
| free(x->posArray); |
| free(x->realArray); |
| free(x); |
| } |
| |
| int nextSwap(swapInfo* x) |
| { |
| int i,j,temp; |
| for(i=x->varN;i>1;i--) |
| { |
| if( i > x->realArray[x->posArray[i].position + x->posArray[i].direction] ) |
| { |
| x->posArray[i].position = x->posArray[i].position + x->posArray[i].direction; |
| temp = x->realArray[x->posArray[i].position]; |
| x->realArray[x->posArray[i].position] = i; |
| x->realArray[x->posArray[i].position - x->posArray[i].direction] = temp; |
| x->posArray[temp].position = x->posArray[i].position - x->posArray[i].direction; |
| for(j=x->varN;j>i;j--) |
| { |
| x->posArray[j].direction = x->posArray[j].direction * -1; |
| } |
| x->positionToSwap1 = x->posArray[temp].position - 1; |
| x->positionToSwap2 = x->posArray[i].position - 1; |
| return 1; |
| } |
| |
| } |
| return 0; |
| } |
| |
| void fillInSwapArray(permInfo* pi) |
| { |
| int counter=pi->totalSwaps-1; |
| swapInfo* x= setSwapInfoPtr(pi->varN); |
| while(nextSwap(x)==1) |
| { |
| if(x->positionToSwap1<x->positionToSwap2) |
| pi->swapArray[counter--]=x->positionToSwap1; |
| else |
| pi->swapArray[counter--]=x->positionToSwap2; |
| } |
| |
| freeSwapInfoPtr(x); |
| } |
| int oneBitPosition(int x, int size) |
| { |
| int i; |
| for(i=0;i<size;i++) |
| if((x>>i)&1) |
| return i; |
| return -1; |
| } |
| void fillInFlipArray(permInfo* pi) |
| { |
| int i, temp=0, grayNumber; |
| for(i=1;i<=pi->totalFlips;i++) |
| { |
| grayNumber = i^(i>>1); |
| pi->flipArray[pi->totalFlips-i]=oneBitPosition(temp^grayNumber, pi->varN); |
| temp = grayNumber; |
| } |
| |
| |
| } |
| static inline int factorial(int n) |
| { |
| return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n; |
| } |
| permInfo* setPermInfoPtr(int var) |
| { |
| permInfo* x; |
| x = (permInfo*) malloc(sizeof(permInfo)); |
| x->flipCtr=0; |
| x->varN = var; |
| x->totalFlips=(1<<var)-1; |
| x->swapCtr=0; |
| x->totalSwaps=factorial(var)-1; |
| x->flipArray = (int*) malloc(sizeof(int)*x->totalFlips); |
| x->swapArray = (int*) malloc(sizeof(int)*x->totalSwaps); |
| fillInSwapArray(x); |
| fillInFlipArray(x); |
| return x; |
| } |
| |
| void freePermInfoPtr(permInfo* x) |
| { |
| free(x->flipArray); |
| free(x->swapArray); |
| free(x); |
| } |
| static inline void minWord(word* a, word* b, word* minimal, int nVars) |
| { |
| if(memCompare(a, b, nVars) == -1) |
| Kit_TruthCopy_64bit( minimal, a, nVars ); |
| else |
| Kit_TruthCopy_64bit( minimal, b, nVars ); |
| } |
| static inline void minWord3(word* a, word* b, word* minimal, int nVars) |
| { |
| if (memCompare(a, b, nVars) <= 0) |
| { |
| if (memCompare(a, minimal, nVars) < 0) |
| Kit_TruthCopy_64bit( minimal, a, nVars ); |
| else |
| return ; |
| } |
| if (memCompare(b, minimal, nVars) <= 0) |
| Kit_TruthCopy_64bit( minimal, b, nVars ); |
| } |
| static inline void minWord1(word* a, word* minimal, int nVars) |
| { |
| if (memCompare(a, minimal, nVars) <= 0) |
| Kit_TruthCopy_64bit( minimal, a, nVars ); |
| } |
| void simpleMinimal(word* x, word* pAux,word* minimal, permInfo* pi, int nVars) |
| { |
| int i,j=0; |
| Kit_TruthCopy_64bit( pAux, x, nVars ); |
| Kit_TruthNot_64bit( x, nVars ); |
| |
| minWord(x, pAux, minimal, nVars); |
| |
| for(i=pi->totalSwaps-1;i>=0;i--) |
| { |
| Kit_TruthSwapAdjacentVars_64bit(x, nVars, pi->swapArray[i]); |
| Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, pi->swapArray[i]); |
| minWord3(x, pAux, minimal, nVars); |
| } |
| for(j=pi->totalFlips-1;j>=0;j--) |
| { |
| Kit_TruthSwapAdjacentVars_64bit(x, nVars, 0); |
| Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, 0); |
| Kit_TruthChangePhase_64bit(x, nVars, pi->flipArray[j]); |
| Kit_TruthChangePhase_64bit(pAux, nVars, pi->flipArray[j]); |
| minWord3(x, pAux, minimal, nVars); |
| for(i=pi->totalSwaps-1;i>=0;i--) |
| { |
| Kit_TruthSwapAdjacentVars_64bit(x, nVars, pi->swapArray[i]); |
| Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, pi->swapArray[i]); |
| minWord3(x, pAux, minimal, nVars); |
| } |
| } |
| Kit_TruthCopy_64bit( x, minimal, nVars ); |
| } |
| |
| /** |
| * pGroups: we assume that the variables are merged into adjacent groups, |
| * the size of each group is stored in pGroups |
| * nGroups: the number of groups |
| * |
| * pis: we compute all permInfos from 0 to nVars (incl.) |
| */ |
| void simpleMinimalGroups(word* x, word* pAux, word* minimal, int* pGroups, int nGroups, permInfo** pis, int nVars, int fFlipOutput, int fFlipInput) |
| { |
| /* variables */ |
| int i, j, o, nn; |
| permInfo* pi; |
| int * a, * c, * m; |
| |
| /* reorder groups and calculate group offsets */ |
| int * offset = ABC_ALLOC( int, nGroups ); |
| o = 0; |
| j = 0; |
| |
| for ( i = 0; i < nGroups; ++i ) |
| { |
| offset[j] = o; |
| o += pGroups[j]; |
| ++j; |
| } |
| |
| if ( fFlipOutput ) |
| { |
| /* keep regular and inverted version of x */ |
| Kit_TruthCopy_64bit( pAux, x, nVars ); |
| Kit_TruthNot_64bit( x, nVars ); |
| |
| minWord(x, pAux, minimal, nVars); |
| } |
| else |
| { |
| Kit_TruthCopy_64bit( minimal, x, nVars ); |
| } |
| |
| /* iterate through all combinations of pGroups using mixed radix enumeration */ |
| nn = ( nGroups << 1 ) + 1; |
| a = ABC_ALLOC( int, nn ); |
| c = ABC_ALLOC( int, nn ); |
| m = ABC_ALLOC( int, nn ); |
| |
| /* fill a and m arrays */ |
| m[0] = 2; |
| for ( i = 1; i <= nGroups; ++i ) { m[i] = pis[pGroups[i - 1]]->totalFlips + 1; } |
| for ( i = 1; i <= nGroups; ++i ) { m[nGroups + i] = pis[pGroups[i - 1]]->totalSwaps + 1; } |
| for ( i = 0; i < nn; ++i ) { a[i] = c[i] = 0; } |
| |
| while ( 1 ) |
| { |
| /* consider all flips */ |
| for ( i = 1; i <= nGroups; ++i ) |
| { |
| if ( !c[i] ) { continue; } |
| if ( !fFlipInput && pGroups[i - 1] == 1 ) { continue; } |
| |
| pi = pis[pGroups[i - 1]]; |
| j = a[i] == 0 ? 0 : pi->totalFlips - a[i]; |
| |
| Kit_TruthChangePhase_64bit(x, nVars, offset[i - 1] + pi->flipArray[j]); |
| if ( fFlipOutput ) |
| { |
| Kit_TruthChangePhase_64bit(pAux, nVars, offset[i - 1] + pi->flipArray[j]); |
| minWord3(x, pAux, minimal, nVars); |
| } |
| else |
| { |
| minWord1(x, minimal, nVars); |
| } |
| } |
| |
| /* consider all swaps */ |
| for ( i = 1; i <= nGroups; ++i ) |
| { |
| if ( !c[nGroups + i] ) { continue; } |
| if ( pGroups[i - 1] == 1 ) { continue; } |
| |
| pi = pis[pGroups[i - 1]]; |
| if ( a[nGroups + i] == pi->totalSwaps ) |
| { |
| j = 0; |
| } |
| else |
| { |
| j = pi->swapArray[pi->totalSwaps - a[nGroups + i] - 1]; |
| } |
| Kit_TruthSwapAdjacentVars_64bit(x, nVars, offset[i - 1] + j); |
| if ( fFlipOutput ) |
| { |
| Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, offset[i - 1] + j); |
| minWord3(x, pAux, minimal, nVars); |
| } |
| else |
| { |
| minWord1(x, minimal, nVars); |
| } |
| } |
| |
| /* update a's */ |
| memset(c, 0, sizeof(int) * nn); |
| j = nn - 1; |
| while ( a[j] == m[j] - 1 ) { c[j] = 1; a[j--] = 0; } |
| |
| /* done? */ |
| if ( j == 0 ) { break; } |
| |
| c[j] = 1; |
| a[j]++; |
| } |
| ABC_FREE( offset ); |
| ABC_FREE( a ); |
| ABC_FREE( c ); |
| ABC_FREE( m ); |
| |
| Kit_TruthCopy_64bit( x, minimal, nVars ); |
| } |
| |
| ABC_NAMESPACE_IMPL_END |