29# define __builtin_popcount __popcnt
38static word s_CMasks6[5] = {
145static inline int Abc_TtCheckEqual2VarCofs(
word * pTruth,
int nWords,
int iVar,
int Num1,
int Num2 )
147 assert( Num1 < Num2 && Num2 < 4 );
149 return ((pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar]) == ((pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar]);
152 int w, shift = (1 << iVar);
153 for ( w = 0; w <
nWords; w++ )
154 if ( ((pTruth[w] >> Num2 * shift) & s_CMasks6[iVar]) != ((pTruth[w] >> Num1 * shift) & s_CMasks6[iVar]) )
160 unsigned * pTruthU = (
unsigned *)pTruth;
161 unsigned * pLimitU = (
unsigned *)(pTruth +
nWords);
163 for ( ; pTruthU < pLimitU; pTruthU += 4 )
164 if ( pTruthU[Num2] != pTruthU[Num1] )
171 int i, iStep = Abc_TtWordNum(iVar);
173 for ( ; pTruth < pLimit; pTruth += 4*iStep )
174 for ( i = 0; i < iStep; i++ )
175 if ( pTruth[i+Num2*iStep] != pTruth[i+Num1*iStep] )
192static inline int Abc_TtCompare2VarCofs(
word * pTruth,
int nWords,
int iVar,
int Num1,
int Num2 )
194 assert( Num1 < Num2 && Num2 < 4 );
197 word Cof1 = (pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar];
198 word Cof2 = (pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar];
200 return Cof1 < Cof2 ? -1 : 1;
206 int w, shift = (1 << iVar);
207 for ( w = 0; w <
nWords; w++ )
209 Cof1 = (pTruth[w] >> Num1 * shift) & s_CMasks6[iVar];
210 Cof2 = (pTruth[w] >> Num2 * shift) & s_CMasks6[iVar];
212 return Cof1 < Cof2 ? -1 : 1;
218 unsigned * pTruthU = (
unsigned *)pTruth;
219 unsigned * pLimitU = (
unsigned *)(pTruth +
nWords);
221 for ( ; pTruthU < pLimitU; pTruthU += 4 )
222 if ( pTruthU[Num1] != pTruthU[Num2] )
223 return pTruthU[Num1] < pTruthU[Num2] ? -1 : 1;
229 int i, iStep = Abc_TtWordNum(iVar);
230 int Offset1 = Num1*iStep;
231 int Offset2 = Num2*iStep;
233 for ( ; pTruth < pLimit; pTruth += 4*iStep )
234 for ( i = 0; i < iStep; i++ )
235 if ( pTruth[i + Offset1] != pTruth[i + Offset2] )
236 return pTruth[i + Offset1] < pTruth[i + Offset2] ? -1 : 1;
240static inline int Abc_TtCompare2VarCofsRev(
word * pTruth,
int nWords,
int iVar,
int Num1,
int Num2 )
242 assert( Num1 < Num2 && Num2 < 4 );
245 word Cof1 = (pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar];
246 word Cof2 = (pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar];
248 return Cof1 < Cof2 ? -1 : 1;
254 int w, shift = (1 << iVar);
255 for ( w =
nWords - 1; w >= 0; w-- )
257 Cof1 = (pTruth[w] >> Num1 * shift) & s_CMasks6[iVar];
258 Cof2 = (pTruth[w] >> Num2 * shift) & s_CMasks6[iVar];
260 return Cof1 < Cof2 ? -1 : 1;
266 unsigned * pTruthU = (
unsigned *)pTruth;
267 unsigned * pLimitU = (
unsigned *)(pTruth +
nWords);
269 for ( pLimitU -= 4; pLimitU >= pTruthU; pLimitU -= 4 )
270 if ( pLimitU[Num1] != pLimitU[Num2] )
271 return pLimitU[Num1] < pLimitU[Num2] ? -1 : 1;
277 int i, iStep = Abc_TtWordNum(iVar);
278 int Offset1 = Num1*iStep;
279 int Offset2 = Num2*iStep;
281 for ( pLimit -= 4*iStep; pLimit >= pTruth; pLimit -= 4*iStep )
282 for ( i = iStep - 1; i >= 0; i-- )
283 if ( pLimit[i + Offset1] != pLimit[i + Offset2] )
284 return pLimit[i + Offset1] < pLimit[i + Offset2] ? -1 : 1;
303 int shift, bits = (1 << nVars);
304 word base = *pTruth = *pTruth & ((((
word)1) << bits) - 1);
305 for (shift = bits; shift < 64; shift += bits)
306 *pTruth |= base << shift;
310static inline void Abc_TtVerifySmallTruth(
word * pTruth,
int nVars)
314 word nTruth = *pTruth;
316 assert(*pTruth == nTruth);
321static inline int Abc_TtCountOnesInTruth(
word * pTruth,
int nVars )
323 int nWords = Abc_TtWordNum( nVars );
325 Abc_TtVerifySmallTruth(pTruth, nVars);
326 for ( k = 0; k <
nWords; k++ )
328 Counter += Abc_TtCountOnes( pTruth[k] );
331static inline void Abc_TtCountOnesInCofs(
word * pTruth,
int nVars,
int * pStore )
334 int i, k, Counter,
nWords;
337 Abc_TtVerifySmallTruth(pTruth, nVars);
338 for ( i = 0; i < nVars; i++ )
339 pStore[i] = Abc_TtCountOnes( pTruth[0] & s_Truths6Neg[i] );
343 nWords = Abc_TtWordNum( nVars );
344 memset( pStore, 0,
sizeof(
int) * nVars );
345 for ( k = 0; k <
nWords; k++ )
348 for ( i = 0; i < 6; i++ )
349 if ( (Temp = (pTruth[k] & s_Truths6Neg[i]) | ((pTruth[k+1] & s_Truths6Neg[i]) << (1 << i))) )
350 pStore[i] += Abc_TtCountOnes( Temp );
354 Counter = Abc_TtCountOnes( pTruth[k] );
355 for ( i = 6; i < nVars; i++ )
356 if ( (k & (1 << (i-6))) == 0 )
357 pStore[i] += Counter;
363 Counter = Abc_TtCountOnes( pTruth[k] );
364 for ( i = 6; i < nVars; i++ )
365 if ( (k & (1 << (i-6))) == 0 )
366 pStore[i] += Counter;
372 Abc_TtCountOnesInCofs( pTruth, nVars, pStore );
373 return Abc_TtCountOnesInTruth( pTruth, nVars );
377static inline int shiftFunc(
int ci)
381static int Abc_TtScc6(
word wTruth,
int ck)
385 if (!wTruth)
return 0;
386 for (i = 0; i < 64; i++)
387 if (wTruth & (
word)1 << i) {
388 int ci = __builtin_popcount( i & 0xff ) + ck;
389 sum += shiftFunc(ci);
395 int k,
nWords = Abc_TtWordNum(nVars);
398 for (k = 0; k <
nWords; k++)
399 sum += Abc_TtScc6(pTruth[k], Abc_TtBitCount16(k));
402static inline void Abc_TtSccInCofs6(
word wTruth,
int nVars,
int ck,
int * pStore)
406 for (v = 0; v < nVars; v++)
409 for (i = j = 0; j < 64; j++)
410 if (s_Truths6Neg[v] & (
word)1 << j)
412 if (wTruth & (
word)1 << j)
414 int ci = __builtin_popcount( i & 0xff ) + ck;
415 sum += shiftFunc(ci);
422static inline void Abc_TtSccInCofs(
word * pTruth,
int nVars,
int * pStore)
426 memset(pStore, 0,
sizeof(
int) * nVars);
430 Abc_TtSccInCofs6(pTruth[0], nVars, 0, pStore);
434 nWords = Abc_TtWordNum(nVars);
435 for (k = 0; k <
nWords; k++)
438 Abc_TtSccInCofs6(pTruth[k], 6, Abc_TtBitCount16(k), pStore);
441 for (v = 6; v < nVars; v++)
442 if ((k & (1 << (v - 6))) == 0)
444 pStore[v] += Abc_TtScc6(pTruth[k], Abc_TtBitCount16(kv[v - 6]));
461static inline void Abc_TtCountOnesInCofsSlow(
word * pTruth,
int nVars,
int * pStore )
463 static int bit_count[256] = {
464 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
465 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
466 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
467 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
468 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
469 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
470 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
471 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
474 unsigned char * pTruthC = (
unsigned char *)pTruth;
475 nBytes = 8 * Abc_TtWordNum( nVars );
476 memset( pStore, 0,
sizeof(
int) * nVars );
477 for ( k = 0; k < nBytes; k++ )
479 pStore[0] += bit_count[ pTruthC[k] & 0x55 ];
480 pStore[1] += bit_count[ pTruthC[k] & 0x33 ];
481 pStore[2] += bit_count[ pTruthC[k] & 0x0F ];
482 for ( i = 3; i < nVars; i++ )
483 if ( (k & (1 << (i-3))) == 0 )
484 pStore[i] += bit_count[pTruthC[k]];
501 static int bit_count[256] = {
502 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
503 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
504 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
505 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
506 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
507 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
508 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
509 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
511 int nMints0, nMints1;
517 for ( i = 0; i <= iVar; i++ )
518 pStore[i] += nBytes * 4;
524 pStore[0] += bit_count[ Truth & 0x55 ];
525 pStore[1] += bit_count[ Truth & 0x33 ];
526 pStore[2] += bit_count[ Truth & 0x0F ];
527 return bit_count[ Truth & 0xFF ];
531 pStore[iVar] += nMints0;
532 return nMints0 + nMints1;
537 int nMints0, nMints1;
547 if ( Abc_TtIsConst1( pTruth,
nWords ) )
550 for ( i = 0; i <= iVar; i++ )
557 if ( Abc_TtIsConst0( pTruth,
nWords ) )
562 pStore[iVar] += nMints0;
563 return nMints0 + nMints1;
567 memset( pStore, 0,
sizeof(
int) * nVars );
587static inline unsigned Abc_TtSemiCanonicize(
word * pTruth,
int nVars,
char * pCanonPerm,
int * pStoreOut,
int fOnlySwap )
592 int * pStore = pStoreOut ? pStoreOut : pStoreIn;
593 int i, nOnes,
nWords = Abc_TtWordNum( nVars );
594 unsigned uCanonPhase = 0;
596 for ( i = 0; i < nVars; i++ )
602 nOnes = Abc_TtCountOnesInTruth( pTruth, nVars );
603 if ( nOnes >
nWords * 32 && !fOnlySwap )
605 Abc_TtNot( pTruth,
nWords );
606 nOnes =
nWords*64 - nOnes;
607 uCanonPhase |= (1 << nVars);
610 Abc_TtCountOnesInCofs( pTruth, nVars, pStore );
611 pStore[nVars] = nOnes;
612 for ( i = 0; i < nVars; i++ )
614 if ( pStore[i] >= nOnes - pStore[i] || fOnlySwap )
616 Abc_TtFlip( pTruth,
nWords, i );
617 uCanonPhase |= (1 << i);
618 pStore[i] = nOnes - pStore[i];
625 if ( nOnes >
nWords * 32 && !fOnlySwap )
627 for ( i = 0; i < nVars; i++ )
628 pStore[i] =
nWords * 32 - pStore[i];
629 Abc_TtNot( pTruth,
nWords );
630 nOnes =
nWords*64 - nOnes;
631 uCanonPhase |= (1 << nVars);
634 pStore[nVars] = nOnes;
635 for ( i = 0; i < nVars; i++ )
637 if ( pStore[i] >= nOnes - pStore[i] || fOnlySwap )
639 Abc_TtFlip( pTruth,
nWords, i );
640 uCanonPhase |= (1 << i);
641 pStore[i] = nOnes - pStore[i];
651 for ( i = 0; i < nVars-1; i++ )
653 if ( pStore[i] <= pStore[i+1] )
656 ABC_SWAP(
int, pCanonPerm[i], pCanonPerm[i+1] );
657 ABC_SWAP(
int, pStore[i], pStore[i+1] );
658 if ( ((uCanonPhase >> i) & 1) != ((uCanonPhase >> (i+1)) & 1) )
660 uCanonPhase ^= (1 << i);
661 uCanonPhase ^= (1 << (i+1));
663 Abc_TtSwapAdjacent( pTruth,
nWords, i );
673 for ( i = 0; i < nVars - 1; i++ )
676 for ( k = i + 2; k < nVars; k++ )
677 if ( pStore[BestK] > pStore[k] )
680 if ( pStore[i] <= pStore[BestK] )
683 ABC_SWAP(
int, pCanonPerm[i], pCanonPerm[BestK] );
684 ABC_SWAP(
int, pStore[i], pStore[BestK] );
685 if ( ((uCanonPhase >> i) & 1) != ((uCanonPhase >> BestK) & 1) )
687 uCanonPhase ^= (1 << i);
688 uCanonPhase ^= (1 << BestK);
690 Abc_TtSwapVars( pTruth, nVars, i, BestK );
712 static word pCopy1[1024];
713 static word pCopy2[1024];
714 int nWords = Abc_TtWordNum( nVars );
716 for ( i = 0; i < nVars - 1; i++ )
719 Abc_TtCopy( pCopy1, pTruth,
nWords, 0 );
720 Abc_TtSwapAdjacent( pCopy1,
nWords, i );
722 Abc_TtCopy( pCopy2, pTruth,
nWords, 0 );
723 Abc_TtSwapVars( pCopy2, nVars, i, i+1 );
744 word Copy = Abc_Tt6SwapAdjacent( pTruth[0], i );
745 if ( pTruth[0] > Copy )
753 word Copy = pTruth[0];
754 word Best = pTruth[0];
758 Copy = Abc_Tt6Flip( Copy, i );
760 Best = Copy, Config = 1;
763 Copy = Abc_Tt6Flip( Copy, i+1 );
765 Best = Copy, Config = 3;
768 Copy = Abc_Tt6Flip( Copy, i );
770 Best = Copy, Config = 2;
773 Copy = Abc_Tt6SwapAdjacent( Copy, i );
775 Best = Copy, Config = 6;
778 Copy = Abc_Tt6Flip( Copy, i+1 );
780 Best = Copy, Config = 7;
783 Copy = Abc_Tt6Flip( Copy, i );
785 Best = Copy, Config = 5;
788 Copy = Abc_Tt6Flip( Copy, i+1 );
790 Best = Copy, Config = 4;
793 Copy = Abc_Tt6SwapAdjacent( Copy, i );
794 assert( Copy == pTruth[0] );
795 assert( Best <= pTruth[0] );
804 static word pCopy[1024];
805 Abc_TtCopy( pCopy, pTruth,
nWords, 0 );
806 Abc_TtSwapAdjacent( pCopy,
nWords, i );
807 if ( Abc_TtCompareRev(pTruth, pCopy,
nWords) == 1 )
809 Abc_TtCopy( pTruth, pCopy,
nWords, 0 );
815 static word pCopy[1024];
816 static word pBest[1024];
819 Abc_TtCopy( pCopy, pTruth,
nWords, 0 );
820 Abc_TtCopy( pBest, pTruth,
nWords, 0 );
823 Abc_TtFlip( pCopy,
nWords, i );
824 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
825 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 1;
828 Abc_TtFlip( pCopy,
nWords, i+1 );
829 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
830 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 3;
833 Abc_TtFlip( pCopy,
nWords, i );
834 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
835 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 2;
838 Abc_TtSwapAdjacent( pCopy,
nWords, i );
839 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
840 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 6;
843 Abc_TtFlip( pCopy,
nWords, i+1 );
844 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
845 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 7;
848 Abc_TtFlip( pCopy,
nWords, i );
849 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
850 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 5;
853 Abc_TtFlip( pCopy,
nWords, i+1 );
854 if ( Abc_TtCompareRev(pBest, pCopy,
nWords) == 1 )
855 Abc_TtCopy( pBest, pCopy,
nWords, 0 ), Config = 4;
858 Abc_TtSwapAdjacent( pCopy,
nWords, i );
863 Abc_TtCopy( pTruth, pBest,
nWords, 0 );
888 if ( Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 1, 2 ) < 0 )
890 Abc_TtSwapAdjacent( pTruth,
nWords, i );
896 int fComp01, fComp02, fComp03, fComp12, fComp13, fComp23, Config = 0;
897 fComp01 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 0, 1 );
898 fComp23 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 2, 3 );
903 fComp13 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 1, 3 );
905 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 2;
906 else if ( fComp13 == 0 )
908 fComp02 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 0, 2 );
910 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 2;
916 fComp03 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 0, 3 );
919 Abc_TtFlip( pTruth,
nWords, i );
920 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 3;
925 Abc_TtFlip( pTruth,
nWords, i ), Config = 1;
933 fComp12 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 1, 2 );
935 Abc_TtFlip( pTruth,
nWords, i ), Config = 1;
936 else if ( fComp12 == 0 )
938 Abc_TtFlip( pTruth,
nWords, i );
939 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 3;
943 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 2;
945 Abc_TtFlip( pTruth,
nWords, i ), Config ^= 1;
950 fComp02 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 0, 2 );
953 Abc_TtFlip( pTruth,
nWords, i );
954 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 3;
956 else if ( fComp02 == 0 )
958 fComp13 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 1, 3 );
960 Abc_TtFlip( pTruth,
nWords, i ), Config = 1;
963 Abc_TtFlip( pTruth,
nWords, i );
964 Abc_TtFlip( pTruth,
nWords, i + 1 ), Config = 3;
968 Abc_TtFlip( pTruth,
nWords, i ), Config = 1;
972 fComp12 = Abc_TtCompare2VarCofsRev( pTruth,
nWords, i, 1, 2 );
974 Abc_TtSwapAdjacent( pTruth,
nWords, i ), Config ^= 4;
985 if ( ((*puCanonPhase >> i) & 1) != ((*puCanonPhase >> (i+1)) & 1) )
987 *puCanonPhase ^= (1 << i);
988 *puCanonPhase ^= (1 << (i+1));
990 ABC_SWAP(
int, pCanonPerm[i], pCanonPerm[i+1] );
995 static word pCopy1[1024];
997 Abc_TtCopy( pCopy1, pTruth,
nWords, 0 );
1001 if ( Abc_TtCompareRev(pTruth, pCopy1,
nWords) == 1 )
1003 Abc_TtCopy( pTruth, pCopy1,
nWords, 0 );
1008 *puCanonPhase ^= (1 << i);
1010 *puCanonPhase ^= (1 << (i+1));
1013 if ( ((*puCanonPhase >> i) & 1) != ((*puCanonPhase >> (i+1)) & 1) )
1015 *puCanonPhase ^= (1 << i);
1016 *puCanonPhase ^= (1 << (i+1));
1018 ABC_SWAP(
int, pCanonPerm[i], pCanonPerm[i+1] );
1039 unsigned uCanonPhase;
1040 int i, k,
nWords = Abc_TtWordNum( nVars );
1044 char pCanonPermCopy[16];
1045 static word pCopy1[1024];
1046 static word pCopy2[1024];
1047 Abc_TtCopy( pCopy1, pTruth,
nWords, 0 );
1050 uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn, 0 );
1051 for ( k = 0; k < 5; k++ )
1054 for ( i = nVars - 2; i >= 0; i-- )
1055 if ( pStoreIn[i] == pStoreIn[i+1] )
1056 fChanges |=
Abc_TtCofactorPerm( pTruth, i,
nWords, pStoreIn[i] != pStoreIn[nVars]/2, pCanonPerm, &uCanonPhase, fNaive );
1060 for ( i = 1; i < nVars - 1; i++ )
1061 if ( pStoreIn[i] == pStoreIn[i+1] )
1062 fChanges |=
Abc_TtCofactorPerm( pTruth, i,
nWords, pStoreIn[i] != pStoreIn[nVars]/2, pCanonPerm, &uCanonPhase, fNaive );
1068 Abc_TtCopy( pCopy2, pTruth,
nWords, 0 );
1069 memcpy( pCanonPermCopy, pCanonPerm,
sizeof(
char) * nVars );
1070 Abc_TtImplementNpnConfig( pCopy2, nVars, pCanonPermCopy, uCanonPhase );
1071 if ( !Abc_TtEqual( pCopy1, pCopy2,
nWords ) )
1072 printf(
"Canonical form verification failed!\n" );
1088 unsigned uCanonPhase;
1089 int i, k,
nWords = Abc_TtWordNum( nVars );
1093 char pCanonPermCopy[16];
1094 static word pCopy1[1024];
1095 static word pCopy2[1024];
1096 Abc_TtCopy( pCopy1, pTruth,
nWords, 0 );
1100 for ( i = 0; i < nVars; i++ )
1103 uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn, 1 );
1104 for ( k = 0; k < 5; k++ )
1107 for ( i = nVars - 2; i >= 0; i-- )
1108 if ( pStoreIn[i] == pStoreIn[i+1] )
1113 for ( i = 1; i < nVars - 1; i++ )
1114 if ( pStoreIn[i] == pStoreIn[i+1] )
1121 Abc_TtCopy( pCopy2, pTruth,
nWords, 0 );
1122 memcpy( pCanonPermCopy, pCanonPerm,
sizeof(
char) * nVars );
1123 Abc_TtImplementNpnConfig( pCopy2, nVars, pCanonPermCopy, uCanonPhase );
1124 if ( !Abc_TtEqual( pCopy1, pCopy2,
nWords ) )
1125 printf(
"Canonical form verification failed!\n" );
1128 assert( uCanonPhase == 0 );
1143static inline int Abc_TtCanonicizePhaseVar6(
word * pTruth,
int nVars,
int v )
1145 int w,
nWords = Abc_TtWordNum( nVars );
1146 int s, nStep = 1 << (v-6);
1150 if ( pTruth[w-nStep] == pTruth[w] )
1152 if ( w == s ) { w = s - nStep; s = w - nStep; }
1155 if ( pTruth[w-nStep] > pTruth[w] )
1157 for ( ; w > 0; w-- )
1160 if ( w == s ) { w = s - nStep; s = w - nStep; }
1167static inline int Abc_TtCanonicizePhaseVar5(
word * pTruth,
int nVars,
int v )
1169 int w,
nWords = Abc_TtWordNum( nVars );
1171 word Mask = s_Truths6[v];
1173 for ( w =
nWords - 1; w >= 0; w-- )
1175 if ( ((pTruth[w] << Shift) & Mask) == (pTruth[w] & Mask) )
1177 if ( ((pTruth[w] << Shift) & Mask) > (pTruth[w] & Mask) )
1180 for ( ; w >= 0; w-- )
1181 pTruth[w] = ((pTruth[w] << Shift) & Mask) | ((pTruth[w] & Mask) >> Shift);
1189 unsigned uCanonPhase = 0;
1190 int v,
nWords = Abc_TtWordNum( nVars );
1195 static word pCopy1[1024];
1196 static word pCopy2[1024];
1197 Abc_TtCopy( pCopy1, pTruth,
nWords, 0 );
1200 if ( (pTruth[
nWords-1] >> 63) & 1 )
1202 Abc_TtNot( pTruth,
nWords );
1203 uCanonPhase ^= (1 << nVars);
1209 for ( v = nVars - 1; v >= 6; v-- )
1210 if ( Abc_TtCanonicizePhaseVar6( pTruth, nVars, v ) == 1 )
1211 uCanonPhase ^= 1 << v;
1212 for ( ; v >= 0; v-- )
1213 if ( Abc_TtCanonicizePhaseVar5( pTruth, nVars, v ) == 1 )
1214 uCanonPhase ^= 1 << v;
1223 Abc_TtCopy( pCopy2, pTruth,
nWords, 0 );
1224 Abc_TtImplementNpnConfig( pCopy2, nVars, NULL, uCanonPhase );
1225 if ( !Abc_TtEqual( pCopy1, pCopy2,
nWords ) )
1226 printf(
"Canonical form verification failed!\n" );
1243#define TT_MAX_LEVELS 5
1261 p->nLastLevel = nLevels - 1;
1262 p->nWords = Abc_TtWordNum(nVars);
1263 for (i = 0; i < nLevels; i++)
1265 p->vTtMem[i] = Vec_MemAlloc(
p->nWords, 12);
1266 Vec_MemHashAlloc(
p->vTtMem[i], 10000);
1267 p->vRepres[i] = Vec_IntAlloc(1);
1269 p->vPhase = Vec_IntAlloc(2500);
1276 for (i = 0; i <=
p->nLastLevel; i++)
1278 Vec_MemHashFree(
p->vTtMem[i]);
1279 Vec_MemFreeP(&
p->vTtMem[i]);
1280 Vec_IntFree(
p->vRepres[i]);
1282 Vec_IntFree(
p->vPhase );
1288 int i, iSpot, truthId;
1291 if (level < 0) level +=
p->nLastLevel + 1;
1292 if (level < 0 || level >
p->nLastLevel)
return -1;
1293 iSpot = *Vec_MemHashLookup(
p->vTtMem[level], pTruth);
1295 p->vTruthId[level] = Vec_MemHashInsert(
p->vTtMem[level], pTruth);
1296 if (level < p->nLastLevel)
return 0;
1297 iSpot =
p->vTruthId[level];
1300 if (level < p->nLastLevel)
1301 truthId = Vec_IntEntry(
p->vRepres[level], iSpot);
1304 for (i = 0; i < level; i++)
1305 Vec_IntSetEntry(
p->vRepres[i],
p->vTruthId[i], truthId);
1307 pRepTruth = Vec_MemReadEntry(
p->vTtMem[
p->nLastLevel], truthId);
1308 if (level < p->nLastLevel) {
1309 Abc_TtCopy(pResult, pRepTruth,
p->nWords, 0);
1312 assert(Abc_TtEqual(pTruth, pRepTruth,
p->nWords));
1313 if (pTruth != pResult)
1314 Abc_TtCopy(pResult, pRepTruth,
p->nWords, 0);
1323 word * pTruth = pTruthInit;
1324 unsigned uCanonPhase = 0;
1325 int nOnes,
nWords = Abc_TtWordNum( nVars );
1332 Abc_TtClear( pTruthInit,
nWords );
1338 for ( i = 0; i < nVars; i++ )
1342 nOnes = Abc_TtCountOnesInTruth( pTruth, nVars );
1343 if ( nOnes >
nWords * 32 )
1345 Abc_TtNot( pTruth,
nWords );
1346 nOnes =
nWords*64 - nOnes;
1347 uCanonPhase |= (1 << nVars);
1353 Abc_TtCountOnesInCofs( pTruth, nVars, pStore );
1354 pStore[nVars] = nOnes;
1355 for ( i = 0; i < nVars; i++ )
1357 if ( pStore[i] >= nOnes - pStore[i] )
1359 Abc_TtFlip( pTruth,
nWords, i );
1360 uCanonPhase |= (1 << i);
1361 pStore[i] = nOnes - pStore[i];
1369 for ( i = 0; i < nVars - 1; i++ )
1372 for ( k = i + 2; k < nVars; k++ )
1373 if ( pStore[BestK] > pStore[k] )
1375 if ( pStore[i] <= pStore[BestK] )
1377 ABC_SWAP(
int, pCanonPerm[i], pCanonPerm[BestK] );
1378 ABC_SWAP(
int, pStore[i], pStore[BestK] );
1379 if ( ((uCanonPhase >> i) & 1) != ((uCanonPhase >> BestK) & 1) )
1381 uCanonPhase ^= (1 << i);
1382 uCanonPhase ^= (1 << BestK);
1384 Abc_TtSwapVars( pTruth, nVars, i, BestK );
1391 for ( k = 0; k < 5; k++ )
1394 for ( i = nVars - 2; i >= 0; i-- )
1395 if ( pStore[i] == pStore[i+1] )
1396 fChanges |=
Abc_TtCofactorPerm( pTruth, i,
nWords, pStore[i] != pStore[nVars]/2, pCanonPerm, &uCanonPhase, fNaive );
1400 for ( i = 1; i < nVars - 1; i++ )
1401 if ( pStore[i] == pStore[i+1] )
1402 fChanges |=
Abc_TtCofactorPerm( pTruth, i,
nWords, pStore[i] != pStore[nVars]/2, pCanonPerm, &uCanonPhase, fNaive );
1412 word pAuxWord[1024], pAuxWord1[1024];
1418 for (i = 0; i < nVars - 1; i++) {
1419 if (pStore[i] == pStore[i + 1]) {
1424 pGroups[nGroups] = 0;
1431 for (i = 0; i <= nVars; i++) {
1436 if (nOnes ==
nWords * 32)
1438 else if (pStore[0] != pStore[1] && pStore[0] == (nOnes - pStore[0]))
1444 for (i = 0; i <= nVars; i++) {
1494#if !defined(NDEBUG) && !defined(CANON_VERIFY)
1510static int Abc_NextPermSwapC(
char * pData,
signed char * pDir,
int size)
1513 for (i = 0; i < size; i++)
1516 if (j >= 0 && j < size && pData[i] > pData[j] && (k < 0 || pData[i] > pData[k]))
1521 for (i = 0; i < size; i++)
1522 if (pData[i] > pData[k])
1526 return j < k ? j : k;
1532 int nWords = Abc_TtWordNum(nVars);
1533 unsigned uCanonPhase1, uCanonPhase2;
1534 char pCanonPerm2[16];
1535 static word pTruth2[1024];
1538 if (Abc_TtCountOnesInTruth(pTruth, nVars) !=
nWords * 32)
1539 return func(
p, pTruth, nVars, pCanonPerm, flag);
1540 Abc_TtCopy(pTruth2, pTruth,
nWords, 1);
1541 uCanonPhase1 = func(
p, pTruth, nVars, pCanonPerm, flag);
1542 uCanonPhase2 = func(
p, pTruth2, nVars, pCanonPerm2, flag);
1543 if (Abc_TtCompareRev(pTruth, pTruth2,
nWords) <= 0)
1544 return uCanonPhase1;
1545 Abc_TtCopy(pTruth, pTruth2,
nWords, 0);
1546 memcpy(pCanonPerm, pCanonPerm2, nVars);
1547 return uCanonPhase2;
1551static int Abc_TtCannonVerify(
word* pTruth,
int nVars,
char * pCanonPerm,
unsigned uCanonPhase)
1554 int nWords = Abc_TtWordNum(nVars);
1555 char pCanonPermCopy[16];
1556 static word pCopy2[1024];
1557 Abc_TtVerifySmallTruth(pTruth, nVars);
1558 Abc_TtCopy(pCopy2, pTruth,
nWords, 0);
1559 memcpy(pCanonPermCopy, pCanonPerm,
sizeof(
char) * nVars);
1560 Abc_TtImplementNpnConfig(pCopy2, nVars, pCanonPermCopy, uCanonPhase);
1589 for (i = 0; i < nVars; i++)
1600 Vec_IntClear(vPhase);
1606 int nGVars = pGrp->
nGVars;
1608 int iGrp = pGrp - pMan->
pGroup;
1611 for (i = 1; i < nGVars; i++)
1613 int a = pCoef[i];
char aa = pVars[i];
1614 for (j = i; j > 0 && pCoef[j - 1] > a; j--)
1615 pCoef[j] = pCoef[j - 1], pVars[j] = pVars[j - 1];
1616 pCoef[j] = a; pVars[j] = aa;
1618 for (i = 1; i < nGVars; i++)
1619 if (pCoef[i] != pCoef[i - 1]) n++;
1620 if (n == 0)
return 0;
1623 for (i = j = 1; i < nGVars; i++)
1625 if (pCoef[i] == pCoef[i - 1])
continue;
1638 Abc_TtCopy(pDstTruth, pSrc->
pTruth, Abc_TtWordNum(pSrc->
nVars), 0);
1639 pDst->
pTruth = pDstTruth;
1642static inline int Abc_TgCannonVerify(
Abc_TgMan_t* pMan)
1655 for (i = 0; i < pMan->
nVars; i++)
1660 assert(Abc_TgCannonVerify(pMan));
1676static inline void Abc_TgFlipVar(
Abc_TgMan_t* pMan,
int iVar)
1681 pMan->
uPhase ^= 1 << ivp;
1684static inline void Abc_TgFlipSymGroupByVar(
Abc_TgMan_t* pMan,
int iVar)
1686 for (; iVar >= 0; iVar = pMan->
symLink[iVar])
1688 Abc_TgFlipVar(pMan, iVar);
1691static inline void Abc_TgFlipSymGroup(
Abc_TgMan_t* pMan,
int idx)
1693 Abc_TgFlipSymGroupByVar(pMan, pMan->
pPerm[idx]);
1696static inline void Abc_TgClearSymGroupPhase(
Abc_TgMan_t* pMan,
int iVar)
1698 for (; iVar >= 0; iVar = pMan->
symLink[iVar])
1702static void Abc_TgImplementPerm(
Abc_TgMan_t* pMan,
const char *pPermDest)
1704 int i, nVars = pMan->
nVars;
1705 char *pPerm = pMan->
pPermT;
1707 unsigned uPhase = pMan->
uPhase & (1 << nVars);
1709 for (i = 0; i < nVars; i++)
1710 pRev[(
int)pPerm[i]] = i;
1711 for (i = 0; i < nVars; i++)
1712 pPerm[i] = pRev[(
int)pPermDest[i]];
1713 for (i = 0; i < nVars; i++)
1714 pRev[(
int)pPerm[i]] = i;
1716 Abc_TtImplementNpnConfig(pMan->
pTruth, nVars, pRev, 0);
1719 for (i = 0; i < nVars; i++)
1721 if (pMan->
uPhase & (1 << pPerm[i]))
1723 pPerm[i] = pPermDest[i];
1724 pRev[(int)pPerm[i]] = i;
1729static void Abc_TgSwapAdjacentSymGroups(
Abc_TgMan_t* pMan,
int idx)
1733 assert(idx < pMan->nGVars - 1);
1734 iVar = pMan->
pPerm[idx];
1735 jVar = pMan->
pPerm[idx + 1];
1736 pMan->
pPerm[idx] = jVar;
1737 pMan->
pPerm[idx + 1] = iVar;
1742 Abc_TgImplementPerm(pMan, pPermNew);
1748 Abc_TtSwapAdjacent(pMan->
pTruth, Abc_TtWordNum(pMan->
nVars), ix);
1750 pMan->
pPermT[ix + 1] = iVar;
1753 if (((pMan->
uPhase >> ix) & 1) != ((pMan->
uPhase >> (ix + 1)) & 1))
1754 pMan->
uPhase ^= 1 << ix | 1 << (ix + 1);
1755 assert(Abc_TgCannonVerify(pMan));
1770static word pSymCopy[1024];
1772static int Abc_TtIsSymmetric(
word * pTruth,
int nVars,
int iVar,
int jVar,
int fPhase)
1775 int nWords = Abc_TtWordNum(nVars);
1776 Abc_TtCopy(pSymCopy, pTruth,
nWords, 0);
1777 Abc_TtSwapVars(pSymCopy, nVars, iVar, jVar);
1778 rv = Abc_TtEqual(pTruth, pSymCopy,
nWords) * 2;
1779 if (!fPhase)
return rv;
1780 Abc_TtFlip(pSymCopy,
nWords, iVar);
1781 Abc_TtFlip(pSymCopy,
nWords, jVar);
1782 return rv + Abc_TtEqual(pTruth, pSymCopy,
nWords);
1785static int Abc_TtIsSymmetricHigh(
Abc_TgMan_t * pMan,
int iVar,
int jVar,
int fPhase)
1790 for (n = 0, iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->
symLink[iv], jv = pMan->
symLink[jv], n++)
1791 Abc_TtSwapVars(pSymCopy, pMan->
nVars, iv, jv);
1792 assert(iv < 0 && jv < 0);
1794 if (!fPhase)
return rv;
1795 for (iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->
symLink[iv], jv = pMan->
symLink[jv])
1800 return rv + Abc_TtEqual(pMan->
pTruth, pSymCopy,
nWords);
1821 int nVars = pMan->
nVars,
nWords = Abc_TtWordNum(nVars);
1825 nOnes = Abc_TtCountOnesInTruth(pMan->
pTruth, nVars);
1829 nOnes =
nWords * 64 - nOnes;
1830 pMan->
uPhase |= (1 << nVars);
1833 Abc_TtCountOnesInCofs(pMan->
pTruth, nVars, pStore);
1834 pStore[nVars] = nOnes;
1835 for (i = 0; i < nVars; i++)
1837 if (pStore[i] >= nOnes - pStore[i])
1840 pMan->
uPhase |= (1 << i);
1841 pStore[i] = nOnes - pStore[i];
1844 Abc_TgSplitGroup(pMan, pMan->
pGroup, pStore);
1845 pMan->
fPhased = pStore[0] * 2 != nOnes;
1862 int i, j, iVar, jVar, nsym = 0;
1863 int fDone[16], scnt[16], stype[16];
1864 signed char *symLink = pMan->
symLink;
1866 int nGVars = pGrp->
nGVars;
1871 for (i = 0; i < nGVars; i++)
1872 fDone[i] = 0, scnt[i] = 1;
1876 for (i = 0; i < nGVars - 1; i++)
1879 if (iVar < 0 || fDone[i])
continue;
1882 for (j = i + 1; j < nGVars; j++)
1885 if (jVar < 0 || scnt[j] != scnt[i])
1887 else if (scnt[j] == 1)
1888 stype[j] = Abc_TtIsSymmetric(pMan->
pTruth, pMan->
nVars, iVar, jVar, fPhase);
1890 stype[j] = Abc_TtIsSymmetricHigh(pMan, iVar, jVar, fPhase);
1894 for (j = i + 1; j < nGVars; j++)
1901 Abc_TgFlipSymGroupByVar(pMan, jVar);
1907 Abc_TgClearSymGroupPhase(pMan, jVar);
1913 for (ii = iVar; symLink[ii] >= 0; ii = symLink[ii])
1924 }
while (fHigh && modified);
1929static void Abc_TgPurgeSymmetry(
Abc_TgMan_t * pMan,
int fHigh)
1931 int i, j, k, sum = 0, nVars = pMan->
nVars;
1932 signed char *symLink = pMan->
symLink;
1933 char gcnt[16] = { 0 };
1934 char * pPerm = pMan->
pPerm;
1939 int iVar = pMan->
nVars;
1942 int jVar = pPerm[j];
1944 if (!Abc_TtHasVar(pMan->
pTruth, nVars, jVar))
1946 symLink[jVar] = symLink[iVar];
1947 symLink[iVar] = jVar;
1954 for (k = 0; k < pMan->
nGroups; k++)
1955 gcnt[k] += Abc_TgGroupSymmetry(pMan, pMan->
pGroup + k, fHigh);
1957 for (i = 0; i < nVars && pPerm[i] >= 0; i++)
1959 for (j = i + 1; ; i++, j++)
1961 while (j < nVars && pPerm[j] < 0) j++;
1962 if (j >= nVars)
break;
1963 pPerm[i] = pPerm[j];
1965 for (k = 0; k < pMan->
nGroups; k++)
1983 char * pPerm = pMan->
pPerm;
1984 for (j = 0; j < pMan->
nGVars; j++)
1985 for (k = pPerm[j]; k >= 0; k = pMan->
symLink[k])
1997 char * pPerm = pMan->
pPerm;
1999 int nGVars = pMan->
nGVars;
2000 for (i = 1; i < nGVars; i++)
2003 for (j = i; j > 0 && pPerm[j - 1] > t; j--)
2004 pPerm[j] = pPerm[j - 1];
2008 Abc_TgImplementPerm(pMan, pPermNew);
2012 Vec_IntClear(pMan->
vPhase);
2020 for (i = 1; i < nSVars; i++)
2022 char t = pPermNew[i];
2023 for (j = i; j > 0 && pPermNew[j - 1] > t; j--)
2024 pPermNew[j] = pPermNew[j - 1];
2027 Abc_TgImplementPerm(pMan, pPermNew);
2031 for (i = 0; i < pMan->
nVars; i++)
2033 pMan->
pPerm[i] = pPermNew[i];
2037 Vec_IntClear(pMan->
vPhase);
2051static int Abc_TgSymGroupPerm(
Abc_TgMan_t* pMan,
int idx,
int fSwapOnly)
2054 static word pCopy[1024];
2055 static word pBest[1024];
2063 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2064 Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx);
2065 CheckConfig(&tgManCopy);
2066 if (Abc_TtCompareRev(pTruth, pCopy,
nWords) < 0)
2068 Abc_TgManCopy(pMan, pTruth, &tgManCopy);
2075 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2076 Abc_TgManCopy(&tgManBest, pBest, pMan);
2079 Abc_TgFlipSymGroup(&tgManCopy, idx);
2080 CheckConfig(&tgManCopy);
2081 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2082 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 1;
2085 Abc_TgFlipSymGroup(&tgManCopy, idx + 1);
2086 CheckConfig(&tgManCopy);
2087 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2088 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 3;
2091 Abc_TgFlipSymGroup(&tgManCopy, idx);
2092 CheckConfig(&tgManCopy);
2093 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2094 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 2;
2097 Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx);
2098 CheckConfig(&tgManCopy);
2099 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2100 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 6;
2103 Abc_TgFlipSymGroup(&tgManCopy, idx + 1);
2104 CheckConfig(&tgManCopy);
2105 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2106 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 7;
2109 Abc_TgFlipSymGroup(&tgManCopy, idx);
2110 CheckConfig(&tgManCopy);
2111 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2112 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 5;
2115 Abc_TgFlipSymGroup(&tgManCopy, idx + 1);
2116 CheckConfig(&tgManCopy);
2117 if (Abc_TtCompareRev(pBest, pCopy,
nWords) == 1)
2118 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 4;
2121 Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx);
2122 CheckConfig(&tgManCopy);
2127 Abc_TgManCopy(pMan, pTruth, &tgManBest);
2131static int Abc_TgPermPhase(
Abc_TgMan_t* pMan,
int iVar)
2133 static word pCopy[1024];
2137 Abc_TtFlip(pCopy,
nWords, ivp);
2138 if (Abc_TtCompareRev(pMan->
pTruth, pCopy,
nWords) == 1)
2141 pMan->
uPhase ^= 1 << ivp;
2147static void Abc_TgSimpleEnumeration(
Abc_TgMan_t * pMan)
2152 for (k = j = 0; j < pMan->
nGroups; j++)
2157 for (k = 0; k < 5; k++)
2160 for (i = pMan->
nGVars - 2; i >= 0; i--)
2161 if (pGid[i] == pGid[i + 1])
2162 fChanges |= Abc_TgSymGroupPerm(pMan, i, pGid[i] > 0 || pMan->
fPhased);
2163 for (i = 1; i < pMan->
nGVars - 1; i++)
2164 if (pGid[i] == pGid[i + 1])
2165 fChanges |= Abc_TgSymGroupPerm(pMan, i, pGid[i] > 0 || pMan->
fPhased);
2167 for (i = pMan->
nVars - 1; i >= 0; i--)
2169 fChanges |= Abc_TgPermPhase(pMan, i);
2170 for (i = 1; i < pMan->
nVars; i++)
2172 fChanges |= Abc_TgPermPhase(pMan, i);
2173 if (!fChanges)
break;
2175 assert(Abc_TgCannonVerify(pMan));
2190static int Abc_TgIsInitPerm(
char * pData,
signed char * pDir,
int size)
2193 if (pDir[0] != -1)
return 0;
2194 for (i = 1; i <
size; i++)
2195 if (pDir[i] != -1 || pData[i] < pData[i - 1])
2200static void Abc_TgFirstPermutation(
Abc_TgMan_t * pMan)
2203 for (i = 0; i < pMan->
nGVars; i++)
2206 for (i = 0; i < pMan->
nGroups; i++)
2209 int nGvars = pGrp->
nGVars;
2212 assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars));
2217static int Abc_TgNextPermutation(
Abc_TgMan_t * pMan)
2222 signed char * pDirs;
2223 for (i = 0; i < pMan->
nGroups; i++)
2227 if (nGvars == 1)
continue;
2230 j = Abc_NextPermSwapC(pVars, pDirs, nGvars);
2233 Abc_TgSwapAdjacentSymGroups(pMan, j + pGrp->
iStart);
2236 Abc_TgSwapAdjacentSymGroups(pMan, pGrp->
iStart);
2237 assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars));
2242static inline unsigned grayCode(
unsigned a) {
return a ^ (a >> 1); }
2244static int grayFlip(
unsigned a)
2247 for (i = 0, a++; ; i++)
2248 if (a & (1 << i))
return i;
2253 if (Abc_TtCompareRev(pBest->
pTruth, pMan->
pTruth, Abc_TtWordNum(pMan->
nVars)) == 1)
2254 Abc_TgManCopy(pBest, pBest->
pTruth, pMan);
2262 Abc_TgSaveBest(pMan, pBest);
2266 for (i = 0; i < n; i++)
2268 char iv = pMan->
pPerm[i];
2269 for (j = i; j > 0 && pMan->
symPhase[(int)pFGrps[j-1]] > pMan->
symPhase[(int)iv]; j--)
2270 pFGrps[j] = pFGrps[j - 1];
2274 for (i = 0; i < (1 << n) - 1; i++)
2276 Abc_TgFlipSymGroupByVar(pMan, pFGrps[grayFlip(i)]);
2277 Abc_TgSaveBest(pMan, pBest);
2292static void Abc_TgCalcScc(
Abc_TgMan_t * pMan,
int * pOut,
int fSort)
2299 for (i = j = 0; j < pMan->
nGVars; j++)
2310 for (pGrp = pMan->
pGroup; pGrp < pMan->pGroup + pMan->
nGroups; pGrp++)
2313 for (i = vb + 1; i < ve; i++)
2316 for (j = i; j > vb && pOut[j - 1] > a; j--)
2317 pOut[j] = pOut[j - 1];
2323static void Abc_TgSplitGroupsByScc(
Abc_TgMan_t * pMan)
2329 Abc_TgCalcScc(pMan, pScc, 0);
2330 for (pGrp = pMan->
pGroup; pGrp < pMan->pGroup + pMan->
nGroups; pGrp++)
2331 pGrp += Abc_TgSplitGroup(pMan, pGrp, pScc + pGrp->
iStart);
2334 Abc_TgImplementPerm(pMan, pPermT);
2335 assert(Abc_TgCannonVerify(pMan));
2338static int Abc_TgCompareCoef(
int * pIn1,
int * pIn2,
int n)
2341 for (i = 0; i < n; i++)
2342 if (pIn1[i] != pIn2[i])
2343 return (pIn1[i] < pIn2[i]) ? -1 : 1;
2348static const int log2fn[17] = { 0, 0, 100, 258, 458, 691, 949, 1230, 1530, 1847, 2179, 2525, 2884, 3254, 3634, 4025, 4425 };
2349static int Abc_TgPermCostScc(
Abc_TgMan_t * pMan,
int *pScc)
2351 int i, j, k, cost = 0;
2353 for (i = k = 0; i < pMan->
nGroups; i++)
2357 for (j = 1, k++; j < n; j++, k++)
2358 if (pScc[k] == pScc[k - 1]) d++;
2370 static word pCopy[1024];
2372 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2374 Abc_TgSplitGroupsByScc(&tgManCopy);
2375 Abc_TgFirstPermutation(&tgManCopy);
2377 Abc_TgSaveBest(&tgManCopy, pBest);
2378 }
while (Abc_TgNextPermutation(&tgManCopy));
2383 char * pFGrps = pMan->
pFGrps;
2387 for (i = 0; i < n; i++)
2389 char iv = pMan->
pPerm[i];
2390 for (j = i; j > 0 && pMan->
symPhase[(int)pFGrps[j - 1]] > pMan->
symPhase[(int)iv]; j--)
2391 pFGrps[j] = pFGrps[j - 1];
2396static int ilog2(
int n)
2399 for (i = 0; n /= 2; i++)
2412 int nStart =
mode == 0 ? 1 : 0;
2413 int nCoefs = pMan->
nGVars + 2 - nStart;
2414 int pScc[18], pMinScc[18];
2421 Abc_TgCalcScc(pMan, pScc + 2, 1);
2422 ret.
cPerm = Abc_TgPermCostScc(pMan, pScc + 2);
2426 Abc_TgReorderFGrps(pMan);
2428 Abc_TgCalcScc(pMan, pMinScc + 2, 1);
2429 pMinScc[0] =
mode == 0 ? 0 : Abc_TgPermCostScc(pMan, pMinScc + 2);
2430 Vec_IntPush(vPhase, 0);
2431 for (i = 0; (j = grayFlip(i)) < n; i++)
2433 Abc_TgFlipSymGroupByVar(pMan, pMan->
pFGrps[j]);
2435 if (
mode == 0 && pScc[1] > pMinScc[1])
continue;
2436 Abc_TgCalcScc(pMan, pScc + 2, 1);
2438 pScc[0] = Abc_TgPermCostScc(pMan, pScc + 2);
2439 if (Abc_TgCompareCoef(pScc + nStart, pMinScc + nStart, nCoefs) < 0)
2441 memcpy(pMinScc + nStart, pScc + nStart, nCoefs *
sizeof(
int));
2442 Vec_IntClear(vPhase);
2444 if (Abc_TgCompareCoef(pScc + nStart, pMinScc + nStart, nCoefs) == 0)
2445 Vec_IntPush(vPhase, grayCode(i+1));
2447 Abc_TgFlipSymGroupByVar(pMan, pMan->
pFGrps[n - 1]);
2450 ret.
cPhase = ilog2(Vec_IntSize(vPhase));
2451 ret.
cPerm = Abc_TgPermCostScc(pMan, pMinScc + 2);
2462 assert (Vec_IntSize(vPhase) == 0);
2465 Abc_TgReorderFGrps(pMan);
2467 Vec_IntPush(vPhase, 0);
2468 for (i = 0; (j = grayFlip(i)) < n; i++)
2470 Abc_TgFlipSymGroupByVar(pMan, pMan->
pFGrps[j]);
2472 if (nScc > nMinScc)
continue;
2476 Vec_IntClear(vPhase);
2478 Vec_IntPush(vPhase, grayCode(i + 1));
2481 Abc_TgFlipSymGroupByVar(pMan, pMan->
pFGrps[n - 1]);
2482 return ilog2(Vec_IntSize(vPhase));
2489 int ph0 = 0, ph, flp;
2490 static word pCopy[1024];
2495 Abc_TgPermEnumerationScc(pMan, pBest);
2499 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2503 for (j = 0; j < n; j++)
2505 Abc_TgFlipSymGroupByVar(&tgManCopy, pMan->
pFGrps[j]);
2507 Abc_TgPermEnumerationScc(&tgManCopy, pBest);
2515 Abc_TtFill(pBest->
pTruth, Abc_TtWordNum(pBest->
nVars));
2516 Abc_TgPhaseEnumerationScc(pWork, pBest);
2520 Abc_TgFirstPermutation(pWork);
2521 do Abc_TgPhaseEnumeration(pWork, pBest);
2522 while (Abc_TgNextPermutation(pWork));
2524 pBest->
uPhase |= 1 << 30;
2528static inline double Abc_SccPhaseCost(
Abc_TgMan_t * pMan)
2530 return pMan->
nVars * 0.997 + pMan->
nGVars * 1.043 - 15.9;
2540 case 2:
return pMan->
nVars * 0.94 + c.
cPhase * 0.885 + c.
cPerm * 0.00855 - 20.59;
2545static int Abc_TgEnumerationCost(
Abc_TgMan_t * pMan)
2549 if (pMan->
nGroups == 0)
return 0;
2551 for (i = 0; i < pMan->
nGroups; i++)
2556 : Abc_TgRecordPhase1(pMan);
2559 return Abc_SccEnumCost(pMan, c) + 0.5;
2575 int nWords = Abc_TtWordNum(nVars);
2576 unsigned fExac = 0, fHash = 1 << 29;
2577 static word pCopy[1024];
2580 const int MaxCost = 84;
2581 const int nAlg = iThres >= 1000 ? 1 : 0;
2582 const int fHigh = (iThres % 1000) >= 100, nEnumThres = iThres % 100;
2586 Abc_TtClear( pTruth,
nWords );
2590 Abc_TtVerifySmallTruth(pTruth, nVars);
2598 Abc_TgInitMan(&tgMan, pTruth, nVars, nAlg,
p ?
p->vPhase : NULL);
2599 Abc_TgCreateGroups(&tgMan);
2601 Abc_TgPurgeSymmetry(&tgMan, fHigh);
2604 Abc_TgImplementPerm(&tgMan, pCanonPerm);
2605 assert(Abc_TgCannonVerify(&tgMan));
2607 iCost = Abc_TgEnumerationCost(&tgMan);
2608 if (
p == NULL ||
p->nLastLevel == 0) {
2609 if (nEnumThres > MaxCost || iCost < nEnumThres) {
2610 Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
2611 Abc_TgFullEnumeration(&tgManCopy, &tgMan);
2614 Abc_TgSimpleEnumeration(&tgMan);
2617 if (nEnumThres > MaxCost || iCost < nEnumThres) fExac = 1 << 30;
2619 Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
2620 Abc_TgSimpleEnumeration(&tgMan);
2623 Abc_TgManCopy(&tgMan, pTruth, &tgManCopy);
2624 Abc_TgFullEnumeration(&tgManCopy, &tgMan);
2628 memcpy(pCanonPerm, tgMan.
pPermT,
sizeof(
char) * nVars);
2631 if (!Abc_TgCannonVerify(&tgMan))
2632 printf(
"Canonical form verification failed!\n");
2639 int nWords = Abc_TtWordNum(nVars);
2640 unsigned fHard = 0, fHash = 1 << 29;
2641 static word pCopy[1024];
2647 Abc_TtClear(pTruth,
nWords);
2651 Abc_TtVerifySmallTruth(pTruth, nVars);
2659 Abc_TgInitMan(&tgMan, pTruth, nVars, 2,
p->vPhase);
2661 Abc_TgCreateGroups(&tgMan);
2663 Abc_TgPurgeSymmetry(&tgMan, 1);
2666 Abc_TgImplementPerm(&tgMan, pCanonPerm);
2667 assert(Abc_TgCannonVerify(&tgMan));
2670 Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
2671 Abc_TgSimpleEnumeration(&tgMan);
2673 Abc_TgManCopy(&tgMan, pTruth, &tgManCopy);
2674 Abc_TtFill(pTruth,
nWords);
2676 assert(Abc_TgCannonVerify(&tgManCopy));
2677 sc = Abc_TgRecordPhase(&tgManCopy, 0);
2678 if (fCA && Abc_SccEnumCost(&tgManCopy, sc) > Abc_SccPhaseCost(&tgManCopy))
2680 Abc_TgResetGroup(&tgManCopy);
2681 sc = Abc_TgRecordPhase(&tgManCopy, 1);
2684 Abc_TgFullEnumeration(&tgManCopy, &tgMan);
2686 memcpy(pCanonPerm, tgMan.
pPermT,
sizeof(
char) * nVars);
2689 if (!Abc_TgCannonVerify(&tgMan))
2690 printf(
"Canonical form verification failed!\n");
2692 return tgMan.
uPhase | fHard;
#define ABC_SWAP(Type, a, b)
#define ABC_CALLOC(type, num)
#define ABC_CONST(number)
PARAMETERS ///.
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
void freePermInfoPtr(permInfo *x)
permInfo * setPermInfoPtr(int var)
int Abc_TtCofactorPermConfig(word *pTruth, int i, int nWords, int fSwapOnly, int fNaive)
int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t *p, int level, word *pTruth, word *pResult)
int Abc_Tt6CofactorPermNaive(word *pTruth, int i, int fSwapOnly)
int Abc_TtCountOnesInCofsFast_rec(word *pTruth, int iVar, int nWords, int *pStore)
int Abc_TtCountOnesInCofsSimple(word *pTruth, int nVars, int *pStore)
int Abc_TtCountOnesInCofsFast6_rec(word Truth, int iVar, int nBytes, int *pStore)
int Abc_TtCofactorPerm(word *pTruth, int i, int nWords, int fSwapOnly, char *pCanonPerm, unsigned *puCanonPhase, int fNaive)
unsigned Abc_TtCanonicizePhase(word *pTruth, int nVars)
unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t *p, word *pTruthInit, int nVars, char *pCanonPerm, int fExact)
struct TiedGroup_ TiedGroup
struct Abc_SccCost_t_ Abc_SccCost_t
int Abc_TtCountOnesInCofsFast(word *pTruth, int nVars, int *pStore)
void Abc_TtNormalizeSmallTruth(word *pTruth, int nVars)
unsigned Abc_TtCanonicizePerm(word *pTruth, int nVars, char *pCanonPerm)
int Abc_TgExpendSymmetry(Abc_TgMan_t *pMan, char *pDest)
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int iThres)
struct Abc_TgMan_t_ Abc_TgMan_t
void Abc_TtCofactorTest10(word *pTruth, int nVars, int N)
int Abc_TtScc(word *pTruth, int nVars)
Abc_TtHieMan_t * Abc_TtHieManStart(int nVars, int nLevels)
void Abc_TtHieManStop(Abc_TtHieMan_t *p)
unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int flag)
unsigned Abc_TtCanonicizeCA(Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int fCA)
unsigned Abc_TtCanonicize(word *pTruth, int nVars, char *pCanonPerm)
FUNCTION DECLARATIONS ///.
int Abc_TtCofactorPermNaive(word *pTruth, int i, int nWords, int fSwapOnly)
struct Abc_TtHieMan_t_ Abc_TtHieMan_t
unsigned(* TtCanonicizeFunc)(Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int flag)
int Abc_TtCountOnesInCofsQuick(word *pTruth, int nVars, int *pStore)
unsigned __int64 word
DECLARATIONS ///.
void simpleMinimalGroups(word *x, word *pAux, word *minimal, int *pGroups, int nGroups, permInfo **pis, int nVars, int fFlipOutput, int fFlipInput)
Vec_Mem_t * vTtMem[TT_MAX_LEVELS]
Vec_Int_t * vRepres[TT_MAX_LEVELS]
int vTruthId[TT_MAX_LEVELS]
typedefABC_NAMESPACE_IMPL_START struct Vec_Mem_t_ Vec_Mem_t
DECLARATIONS ///.
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.