ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
dauCanon.c
Go to the documentation of this file.
1
20
21#include "dauInt.h"
22#include "misc/util/utilTruth.h"
23#include "misc/vec/vecMem.h"
24#include "bool/lucky/lucky.h"
25#include <math.h>
26
27#ifdef _MSC_VER
28# include <intrin.h>
29# define __builtin_popcount __popcnt
30#endif
31
33
37
38static word s_CMasks6[5] = {
39 ABC_CONST(0x1111111111111111),
40 ABC_CONST(0x0303030303030303),
41 ABC_CONST(0x000F000F000F000F),
42 ABC_CONST(0x000000FF000000FF),
43 ABC_CONST(0x000000000000FFFF)
44};
45
49
61/*
62static inline int Abc_TtCompare1VarCofs( word * pTruth, int nWords, int iVar )
63{
64 if ( nWords == 1 )
65 {
66 word Cof0 = pTruth[0] & s_Truths6Neg[iVar];
67 word Cof1 = (pTruth[0] >> (1 << iVar)) & s_Truths6Neg[iVar];
68 if ( Cof0 != Cof1 )
69 return Cof0 < Cof1 ? -1 : 1;
70 return 0;
71 }
72 if ( iVar <= 5 )
73 {
74 word Cof0, Cof1;
75 int w, shift = (1 << iVar);
76 for ( w = 0; w < nWords; w++ )
77 {
78 Cof0 = pTruth[w] & s_Truths6Neg[iVar];
79 Cof1 = (pTruth[w] >> shift) & s_Truths6Neg[iVar];
80 if ( Cof0 != Cof1 )
81 return Cof0 < Cof1 ? -1 : 1;
82 }
83 return 0;
84 }
85 // if ( iVar > 5 )
86 {
87 word * pLimit = pTruth + nWords;
88 int i, iStep = Abc_TtWordNum(iVar);
89 assert( nWords >= 2 );
90 for ( ; pTruth < pLimit; pTruth += 2*iStep )
91 for ( i = 0; i < iStep; i++ )
92 if ( pTruth[i] != pTruth[i + iStep] )
93 return pTruth[i] < pTruth[i + iStep] ? -1 : 1;
94 return 0;
95 }
96}
97static inline int Abc_TtCompare1VarCofsRev( word * pTruth, int nWords, int iVar )
98{
99 if ( nWords == 1 )
100 {
101 word Cof0 = pTruth[0] & s_Truths6Neg[iVar];
102 word Cof1 = (pTruth[0] >> (1 << iVar)) & s_Truths6Neg[iVar];
103 if ( Cof0 != Cof1 )
104 return Cof0 < Cof1 ? -1 : 1;
105 return 0;
106 }
107 if ( iVar <= 5 )
108 {
109 word Cof0, Cof1;
110 int w, shift = (1 << iVar);
111 for ( w = nWords - 1; w >= 0; w-- )
112 {
113 Cof0 = pTruth[w] & s_Truths6Neg[iVar];
114 Cof1 = (pTruth[w] >> shift) & s_Truths6Neg[iVar];
115 if ( Cof0 != Cof1 )
116 return Cof0 < Cof1 ? -1 : 1;
117 }
118 return 0;
119 }
120 // if ( iVar > 5 )
121 {
122 word * pLimit = pTruth + nWords;
123 int i, iStep = Abc_TtWordNum(iVar);
124 assert( nWords >= 2 );
125 for ( pLimit -= 2*iStep; pLimit >= pTruth; pLimit -= 2*iStep )
126 for ( i = iStep - 1; i >= 0; i-- )
127 if ( pLimit[i] != pLimit[i + iStep] )
128 return pLimit[i] < pLimit[i + iStep] ? -1 : 1;
129 return 0;
130 }
131}
132*/
133
145static inline int Abc_TtCheckEqual2VarCofs( word * pTruth, int nWords, int iVar, int Num1, int Num2 )
146{
147 assert( Num1 < Num2 && Num2 < 4 );
148 if ( nWords == 1 )
149 return ((pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar]) == ((pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar]);
150 if ( iVar <= 4 )
151 {
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]) )
155 return 0;
156 return 1;
157 }
158 if ( iVar == 5 )
159 {
160 unsigned * pTruthU = (unsigned *)pTruth;
161 unsigned * pLimitU = (unsigned *)(pTruth + nWords);
162 assert( nWords >= 2 );
163 for ( ; pTruthU < pLimitU; pTruthU += 4 )
164 if ( pTruthU[Num2] != pTruthU[Num1] )
165 return 0;
166 return 1;
167 }
168 // if ( iVar > 5 )
169 {
170 word * pLimit = pTruth + nWords;
171 int i, iStep = Abc_TtWordNum(iVar);
172 assert( nWords >= 4 );
173 for ( ; pTruth < pLimit; pTruth += 4*iStep )
174 for ( i = 0; i < iStep; i++ )
175 if ( pTruth[i+Num2*iStep] != pTruth[i+Num1*iStep] )
176 return 0;
177 return 1;
178 }
179}
180
192static inline int Abc_TtCompare2VarCofs( word * pTruth, int nWords, int iVar, int Num1, int Num2 )
193{
194 assert( Num1 < Num2 && Num2 < 4 );
195 if ( nWords == 1 )
196 {
197 word Cof1 = (pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar];
198 word Cof2 = (pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar];
199 if ( Cof1 != Cof2 )
200 return Cof1 < Cof2 ? -1 : 1;
201 return 0;
202 }
203 if ( iVar <= 4 )
204 {
205 word Cof1, Cof2;
206 int w, shift = (1 << iVar);
207 for ( w = 0; w < nWords; w++ )
208 {
209 Cof1 = (pTruth[w] >> Num1 * shift) & s_CMasks6[iVar];
210 Cof2 = (pTruth[w] >> Num2 * shift) & s_CMasks6[iVar];
211 if ( Cof1 != Cof2 )
212 return Cof1 < Cof2 ? -1 : 1;
213 }
214 return 0;
215 }
216 if ( iVar == 5 )
217 {
218 unsigned * pTruthU = (unsigned *)pTruth;
219 unsigned * pLimitU = (unsigned *)(pTruth + nWords);
220 assert( nWords >= 2 );
221 for ( ; pTruthU < pLimitU; pTruthU += 4 )
222 if ( pTruthU[Num1] != pTruthU[Num2] )
223 return pTruthU[Num1] < pTruthU[Num2] ? -1 : 1;
224 return 0;
225 }
226 // if ( iVar > 5 )
227 {
228 word * pLimit = pTruth + nWords;
229 int i, iStep = Abc_TtWordNum(iVar);
230 int Offset1 = Num1*iStep;
231 int Offset2 = Num2*iStep;
232 assert( nWords >= 4 );
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;
237 return 0;
238 }
239}
240static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar, int Num1, int Num2 )
241{
242 assert( Num1 < Num2 && Num2 < 4 );
243 if ( nWords == 1 )
244 {
245 word Cof1 = (pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar];
246 word Cof2 = (pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar];
247 if ( Cof1 != Cof2 )
248 return Cof1 < Cof2 ? -1 : 1;
249 return 0;
250 }
251 if ( iVar <= 4 )
252 {
253 word Cof1, Cof2;
254 int w, shift = (1 << iVar);
255 for ( w = nWords - 1; w >= 0; w-- )
256 {
257 Cof1 = (pTruth[w] >> Num1 * shift) & s_CMasks6[iVar];
258 Cof2 = (pTruth[w] >> Num2 * shift) & s_CMasks6[iVar];
259 if ( Cof1 != Cof2 )
260 return Cof1 < Cof2 ? -1 : 1;
261 }
262 return 0;
263 }
264 if ( iVar == 5 )
265 {
266 unsigned * pTruthU = (unsigned *)pTruth;
267 unsigned * pLimitU = (unsigned *)(pTruth + nWords);
268 assert( nWords >= 2 );
269 for ( pLimitU -= 4; pLimitU >= pTruthU; pLimitU -= 4 )
270 if ( pLimitU[Num1] != pLimitU[Num2] )
271 return pLimitU[Num1] < pLimitU[Num2] ? -1 : 1;
272 return 0;
273 }
274 // if ( iVar > 5 )
275 {
276 word * pLimit = pTruth + nWords;
277 int i, iStep = Abc_TtWordNum(iVar);
278 int Offset1 = Num1*iStep;
279 int Offset2 = Num2*iStep;
280 assert( nWords >= 4 );
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;
285 return 0;
286 }
287}
288
300void Abc_TtNormalizeSmallTruth(word * pTruth, int nVars)
301{
302 if (nVars < 6) {
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;
307 }
308}
309
310static inline void Abc_TtVerifySmallTruth(word * pTruth, int nVars)
311{
312#ifndef NDEBUG
313 if (nVars < 6) {
314 word nTruth = *pTruth;
315 Abc_TtNormalizeSmallTruth(&nTruth, nVars);
316 assert(*pTruth == nTruth);
317 }
318#endif
319}
320
321static inline int Abc_TtCountOnesInTruth( word * pTruth, int nVars )
322{
323 int nWords = Abc_TtWordNum( nVars );
324 int k, Counter = 0;
325 Abc_TtVerifySmallTruth(pTruth, nVars);
326 for ( k = 0; k < nWords; k++ )
327 if ( pTruth[k] )
328 Counter += Abc_TtCountOnes( pTruth[k] );
329 return Counter;
330}
331static inline void Abc_TtCountOnesInCofs( word * pTruth, int nVars, int * pStore )
332{
333 word Temp;
334 int i, k, Counter, nWords;
335 if ( nVars <= 6 )
336 {
337 Abc_TtVerifySmallTruth(pTruth, nVars);
338 for ( i = 0; i < nVars; i++ )
339 pStore[i] = Abc_TtCountOnes( pTruth[0] & s_Truths6Neg[i] );
340 return;
341 }
342 assert( nVars > 6 );
343 nWords = Abc_TtWordNum( nVars );
344 memset( pStore, 0, sizeof(int) * nVars );
345 for ( k = 0; k < nWords; k++ )
346 {
347 // count 1's for the first six variables
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 );
351 // count 1's for all other variables
352 if ( pTruth[k] )
353 {
354 Counter = Abc_TtCountOnes( pTruth[k] );
355 for ( i = 6; i < nVars; i++ )
356 if ( (k & (1 << (i-6))) == 0 )
357 pStore[i] += Counter;
358 }
359 k++;
360 // count 1's for all other variables
361 if ( pTruth[k] )
362 {
363 Counter = Abc_TtCountOnes( pTruth[k] );
364 for ( i = 6; i < nVars; i++ )
365 if ( (k & (1 << (i-6))) == 0 )
366 pStore[i] += Counter;
367 }
368 }
369}
370int Abc_TtCountOnesInCofsSimple( word * pTruth, int nVars, int * pStore )
371{
372 Abc_TtCountOnesInCofs( pTruth, nVars, pStore );
373 return Abc_TtCountOnesInTruth( pTruth, nVars );
374}
375
376// Shifted Cofactor Coefficient
377static inline int shiftFunc(int ci)
378//{ return ci * ci; }
379{ return 1 << ci; }
380
381static int Abc_TtScc6(word wTruth, int ck)
382{
383 int i;
384 int sum = 0;
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);
390 }
391 return sum;
392}
393int Abc_TtScc(word * pTruth, int nVars)
394{
395 int k, nWords = Abc_TtWordNum(nVars);
396 int sum = 0;
397 Abc_TtNormalizeSmallTruth(pTruth, nVars);
398 for (k = 0; k < nWords; k++)
399 sum += Abc_TtScc6(pTruth[k], Abc_TtBitCount16(k));
400 return sum;
401}
402static inline void Abc_TtSccInCofs6(word wTruth, int nVars, int ck, int * pStore)
403{
404 int i, j, v;
405 assert(nVars <= 6);
406 for (v = 0; v < nVars; v++)
407 {
408 int sum = 0;
409 for (i = j = 0; j < 64; j++)
410 if (s_Truths6Neg[v] & (word)1 << j)
411 {
412 if (wTruth & (word)1 << j)
413 {
414 int ci = __builtin_popcount( i & 0xff ) + ck;
415 sum += shiftFunc(ci);
416 }
417 i++;
418 }
419 pStore[v] += sum;
420 }
421}
422static inline void Abc_TtSccInCofs(word * pTruth, int nVars, int * pStore)
423{
424 int k, v, nWords;
425 int kv[10] = { 0 };
426 memset(pStore, 0, sizeof(int) * nVars);
427 if (nVars <= 6)
428 {
429 Abc_TtNormalizeSmallTruth(pTruth, nVars);
430 Abc_TtSccInCofs6(pTruth[0], nVars, 0, pStore);
431 return;
432 }
433 assert(nVars > 6);
434 nWords = Abc_TtWordNum(nVars);
435 for (k = 0; k < nWords; k++)
436 {
437 // count 1's for the first six variables
438 Abc_TtSccInCofs6(pTruth[k], 6, Abc_TtBitCount16(k), pStore);
439
440 // count 1's for all other variables
441 for (v = 6; v < nVars; v++)
442 if ((k & (1 << (v - 6))) == 0)
443 {
444 pStore[v] += Abc_TtScc6(pTruth[k], Abc_TtBitCount16(kv[v - 6]));
445 kv[v - 6]++;
446 }
447 }
448}
449
461static inline void Abc_TtCountOnesInCofsSlow( word * pTruth, int nVars, int * pStore )
462{
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
472 };
473 int i, k, nBytes;
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++ )
478 {
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]];
485 }
486}
487
499int Abc_TtCountOnesInCofsFast6_rec( word Truth, int iVar, int nBytes, int * pStore )
500{
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
510 };
511 int nMints0, nMints1;
512 if ( Truth == 0 )
513 return 0;
514 if ( ~Truth == 0 )
515 {
516 int i;
517 for ( i = 0; i <= iVar; i++ )
518 pStore[i] += nBytes * 4;
519 return nBytes * 8;
520 }
521 if ( nBytes == 1 )
522 {
523 assert( iVar == 2 );
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 ];
528 }
529 nMints0 = Abc_TtCountOnesInCofsFast6_rec( Abc_Tt6Cofactor0(Truth, iVar), iVar - 1, nBytes/2, pStore );
530 nMints1 = Abc_TtCountOnesInCofsFast6_rec( Abc_Tt6Cofactor1(Truth, iVar), iVar - 1, nBytes/2, pStore );
531 pStore[iVar] += nMints0;
532 return nMints0 + nMints1;
533}
534
535int Abc_TtCountOnesInCofsFast_rec( word * pTruth, int iVar, int nWords, int * pStore )
536{
537 int nMints0, nMints1;
538 if ( nWords == 1 )
539 {
540 assert( iVar == 5 );
541 return Abc_TtCountOnesInCofsFast6_rec( pTruth[0], iVar, 8, pStore );
542 }
543 assert( nWords > 1 );
544 assert( iVar > 5 );
545 if ( pTruth[0] & 1 )
546 {
547 if ( Abc_TtIsConst1( pTruth, nWords ) )
548 {
549 int i;
550 for ( i = 0; i <= iVar; i++ )
551 pStore[i] += nWords * 32;
552 return nWords * 64;
553 }
554 }
555 else
556 {
557 if ( Abc_TtIsConst0( pTruth, nWords ) )
558 return 0;
559 }
560 nMints0 = Abc_TtCountOnesInCofsFast_rec( pTruth, iVar - 1, nWords/2, pStore );
561 nMints1 = Abc_TtCountOnesInCofsFast_rec( pTruth + nWords/2, iVar - 1, nWords/2, pStore );
562 pStore[iVar] += nMints0;
563 return nMints0 + nMints1;
564}
565int Abc_TtCountOnesInCofsFast( word * pTruth, int nVars, int * pStore )
566{
567 memset( pStore, 0, sizeof(int) * nVars );
568 assert( nVars >= 3 );
569 if ( nVars <= 6 )
570 return Abc_TtCountOnesInCofsFast6_rec( pTruth[0], nVars - 1, Abc_TtByteNum( nVars ), pStore );
571 else
572 return Abc_TtCountOnesInCofsFast_rec( pTruth, nVars - 1, Abc_TtWordNum( nVars ), pStore );
573}
574
575
587static inline unsigned Abc_TtSemiCanonicize( word * pTruth, int nVars, char * pCanonPerm, int * pStoreOut, int fOnlySwap )
588{
589 int fUseOld = 1;
590 int fOldSwap = 0;
591 int pStoreIn[17];
592 int * pStore = pStoreOut ? pStoreOut : pStoreIn;
593 int i, nOnes, nWords = Abc_TtWordNum( nVars );
594 unsigned uCanonPhase = 0;
595 assert( nVars <= 16 );
596 for ( i = 0; i < nVars; i++ )
597 pCanonPerm[i] = i;
598
599 if ( fUseOld )
600 {
601 // normalize polarity
602 nOnes = Abc_TtCountOnesInTruth( pTruth, nVars );
603 if ( nOnes > nWords * 32 && !fOnlySwap )
604 {
605 Abc_TtNot( pTruth, nWords );
606 nOnes = nWords*64 - nOnes;
607 uCanonPhase |= (1 << nVars);
608 }
609 // normalize phase
610 Abc_TtCountOnesInCofs( pTruth, nVars, pStore );
611 pStore[nVars] = nOnes;
612 for ( i = 0; i < nVars; i++ )
613 {
614 if ( pStore[i] >= nOnes - pStore[i] || fOnlySwap )
615 continue;
616 Abc_TtFlip( pTruth, nWords, i );
617 uCanonPhase |= (1 << i);
618 pStore[i] = nOnes - pStore[i];
619 }
620 }
621 else
622 {
623 nOnes = Abc_TtCountOnesInCofsQuick( pTruth, nVars, pStore );
624 // normalize polarity
625 if ( nOnes > nWords * 32 && !fOnlySwap )
626 {
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);
632 }
633 // normalize phase
634 pStore[nVars] = nOnes;
635 for ( i = 0; i < nVars; i++ )
636 {
637 if ( pStore[i] >= nOnes - pStore[i] || fOnlySwap )
638 continue;
639 Abc_TtFlip( pTruth, nWords, i );
640 uCanonPhase |= (1 << i);
641 pStore[i] = nOnes - pStore[i];
642 }
643 }
644
645 // normalize permutation
646 if ( fOldSwap )
647 {
648 int fChange;
649 do {
650 fChange = 0;
651 for ( i = 0; i < nVars-1; i++ )
652 {
653 if ( pStore[i] <= pStore[i+1] )
654 // if ( pStore[i] >= pStore[i+1] )
655 continue;
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) )
659 {
660 uCanonPhase ^= (1 << i);
661 uCanonPhase ^= (1 << (i+1));
662 }
663 Abc_TtSwapAdjacent( pTruth, nWords, i );
664 fChange = 1;
665 // nSwaps++;
666 }
667 }
668 while ( fChange );
669 }
670 else
671 {
672 int k, BestK;
673 for ( i = 0; i < nVars - 1; i++ )
674 {
675 BestK = i + 1;
676 for ( k = i + 2; k < nVars; k++ )
677 if ( pStore[BestK] > pStore[k] )
678 // if ( pStore[BestK] < pStore[k] )
679 BestK = k;
680 if ( pStore[i] <= pStore[BestK] )
681 // if ( pStore[i] >= pStore[BestK] )
682 continue;
683 ABC_SWAP( int, pCanonPerm[i], pCanonPerm[BestK] );
684 ABC_SWAP( int, pStore[i], pStore[BestK] );
685 if ( ((uCanonPhase >> i) & 1) != ((uCanonPhase >> BestK) & 1) )
686 {
687 uCanonPhase ^= (1 << i);
688 uCanonPhase ^= (1 << BestK);
689 }
690 Abc_TtSwapVars( pTruth, nVars, i, BestK );
691 // nSwaps++;
692 }
693 }
694 return uCanonPhase;
695}
696
697
698
710void Abc_TtCofactorTest10( word * pTruth, int nVars, int N )
711{
712 static word pCopy1[1024];
713 static word pCopy2[1024];
714 int nWords = Abc_TtWordNum( nVars );
715 int i;
716 for ( i = 0; i < nVars - 1; i++ )
717 {
718// Kit_DsdPrintFromTruth( pTruth, nVars ); printf( "\n" );
719 Abc_TtCopy( pCopy1, pTruth, nWords, 0 );
720 Abc_TtSwapAdjacent( pCopy1, nWords, i );
721// Kit_DsdPrintFromTruth( pCopy1, nVars ); printf( "\n" );
722 Abc_TtCopy( pCopy2, pTruth, nWords, 0 );
723 Abc_TtSwapVars( pCopy2, nVars, i, i+1 );
724// Kit_DsdPrintFromTruth( pCopy2, nVars ); printf( "\n" );
725 assert( Abc_TtEqual( pCopy1, pCopy2, nWords ) );
726 }
727}
728
740int Abc_Tt6CofactorPermNaive( word * pTruth, int i, int fSwapOnly )
741{
742 if ( fSwapOnly )
743 {
744 word Copy = Abc_Tt6SwapAdjacent( pTruth[0], i );
745 if ( pTruth[0] > Copy )
746 {
747 pTruth[0] = Copy;
748 return 4;
749 }
750 return 0;
751 }
752 {
753 word Copy = pTruth[0];
754 word Best = pTruth[0];
755 int Config = 0;
756 // PXY
757 // 001
758 Copy = Abc_Tt6Flip( Copy, i );
759 if ( Best > Copy )
760 Best = Copy, Config = 1;
761 // PXY
762 // 011
763 Copy = Abc_Tt6Flip( Copy, i+1 );
764 if ( Best > Copy )
765 Best = Copy, Config = 3;
766 // PXY
767 // 010
768 Copy = Abc_Tt6Flip( Copy, i );
769 if ( Best > Copy )
770 Best = Copy, Config = 2;
771 // PXY
772 // 110
773 Copy = Abc_Tt6SwapAdjacent( Copy, i );
774 if ( Best > Copy )
775 Best = Copy, Config = 6;
776 // PXY
777 // 111
778 Copy = Abc_Tt6Flip( Copy, i+1 );
779 if ( Best > Copy )
780 Best = Copy, Config = 7;
781 // PXY
782 // 101
783 Copy = Abc_Tt6Flip( Copy, i );
784 if ( Best > Copy )
785 Best = Copy, Config = 5;
786 // PXY
787 // 100
788 Copy = Abc_Tt6Flip( Copy, i+1 );
789 if ( Best > Copy )
790 Best = Copy, Config = 4;
791 // PXY
792 // 000
793 Copy = Abc_Tt6SwapAdjacent( Copy, i );
794 assert( Copy == pTruth[0] );
795 assert( Best <= pTruth[0] );
796 pTruth[0] = Best;
797 return Config;
798 }
799}
800int Abc_TtCofactorPermNaive( word * pTruth, int i, int nWords, int fSwapOnly )
801{
802 if ( fSwapOnly )
803 {
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 )
808 {
809 Abc_TtCopy( pTruth, pCopy, nWords, 0 );
810 return 4;
811 }
812 return 0;
813 }
814 {
815 static word pCopy[1024];
816 static word pBest[1024];
817 int Config = 0;
818 // save two copies
819 Abc_TtCopy( pCopy, pTruth, nWords, 0 );
820 Abc_TtCopy( pBest, pTruth, nWords, 0 );
821 // PXY
822 // 001
823 Abc_TtFlip( pCopy, nWords, i );
824 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
825 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 1;
826 // PXY
827 // 011
828 Abc_TtFlip( pCopy, nWords, i+1 );
829 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
830 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 3;
831 // PXY
832 // 010
833 Abc_TtFlip( pCopy, nWords, i );
834 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
835 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 2;
836 // PXY
837 // 110
838 Abc_TtSwapAdjacent( pCopy, nWords, i );
839 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
840 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 6;
841 // PXY
842 // 111
843 Abc_TtFlip( pCopy, nWords, i+1 );
844 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
845 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 7;
846 // PXY
847 // 101
848 Abc_TtFlip( pCopy, nWords, i );
849 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
850 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 5;
851 // PXY
852 // 100
853 Abc_TtFlip( pCopy, nWords, i+1 );
854 if ( Abc_TtCompareRev(pBest, pCopy, nWords) == 1 )
855 Abc_TtCopy( pBest, pCopy, nWords, 0 ), Config = 4;
856 // PXY
857 // 000
858 Abc_TtSwapAdjacent( pCopy, nWords, i );
859 assert( Abc_TtEqual( pTruth, pCopy, nWords ) );
860 if ( Config == 0 )
861 return 0;
862 assert( Abc_TtCompareRev(pTruth, pBest, nWords) == 1 );
863 Abc_TtCopy( pTruth, pBest, nWords, 0 );
864 return Config;
865 }
866}
867
868
880int Abc_TtCofactorPermConfig( word * pTruth, int i, int nWords, int fSwapOnly, int fNaive )
881{
882 if ( nWords == 1 )
883 return Abc_Tt6CofactorPermNaive( pTruth, i, fSwapOnly );
884 if ( fNaive )
885 return Abc_TtCofactorPermNaive( pTruth, i, nWords, fSwapOnly );
886 if ( fSwapOnly )
887 {
888 if ( Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 1, 2 ) < 0 ) // Cof1 < Cof2
889 {
890 Abc_TtSwapAdjacent( pTruth, nWords, i );
891 return 4;
892 }
893 return 0;
894 }
895 {
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 );
899 if ( fComp23 >= 0 ) // Cof2 >= Cof3
900 {
901 if ( fComp01 >= 0 ) // Cof0 >= Cof1
902 {
903 fComp13 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 1, 3 );
904 if ( fComp13 < 0 ) // Cof1 < Cof3
905 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 2;
906 else if ( fComp13 == 0 ) // Cof1 == Cof3
907 {
908 fComp02 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 0, 2 );
909 if ( fComp02 < 0 )
910 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 2;
911 }
912 // else Cof1 > Cof3 -- do nothing
913 }
914 else // Cof0 < Cof1
915 {
916 fComp03 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 0, 3 );
917 if ( fComp03 < 0 ) // Cof0 < Cof3
918 {
919 Abc_TtFlip( pTruth, nWords, i );
920 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 3;
921 }
922 else // Cof0 >= Cof3
923 {
924 if ( fComp23 == 0 ) // can flip Cof0 and Cof1
925 Abc_TtFlip( pTruth, nWords, i ), Config = 1;
926 }
927 }
928 }
929 else // Cof2 < Cof3
930 {
931 if ( fComp01 >= 0 ) // Cof0 >= Cof1
932 {
933 fComp12 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 1, 2 );
934 if ( fComp12 > 0 ) // Cof1 > Cof2
935 Abc_TtFlip( pTruth, nWords, i ), Config = 1;
936 else if ( fComp12 == 0 ) // Cof1 == Cof2
937 {
938 Abc_TtFlip( pTruth, nWords, i );
939 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 3;
940 }
941 else // Cof1 < Cof2
942 {
943 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 2;
944 if ( fComp01 == 0 )
945 Abc_TtFlip( pTruth, nWords, i ), Config ^= 1;
946 }
947 }
948 else // Cof0 < Cof1
949 {
950 fComp02 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 0, 2 );
951 if ( fComp02 == -1 ) // Cof0 < Cof2
952 {
953 Abc_TtFlip( pTruth, nWords, i );
954 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 3;
955 }
956 else if ( fComp02 == 0 ) // Cof0 == Cof2
957 {
958 fComp13 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 1, 3 );
959 if ( fComp13 >= 0 ) // Cof1 >= Cof3
960 Abc_TtFlip( pTruth, nWords, i ), Config = 1;
961 else // Cof1 < Cof3
962 {
963 Abc_TtFlip( pTruth, nWords, i );
964 Abc_TtFlip( pTruth, nWords, i + 1 ), Config = 3;
965 }
966 }
967 else // Cof0 > Cof2
968 Abc_TtFlip( pTruth, nWords, i ), Config = 1;
969 }
970 }
971 // perform final swap if needed
972 fComp12 = Abc_TtCompare2VarCofsRev( pTruth, nWords, i, 1, 2 );
973 if ( fComp12 < 0 ) // Cof1 < Cof2
974 Abc_TtSwapAdjacent( pTruth, nWords, i ), Config ^= 4;
975 return Config;
976 }
977}
978int Abc_TtCofactorPerm( word * pTruth, int i, int nWords, int fSwapOnly, char * pCanonPerm, unsigned * puCanonPhase, int fNaive )
979{
980 if ( fSwapOnly )
981 {
982 int Config = Abc_TtCofactorPermConfig( pTruth, i, nWords, 1, 0 );
983 if ( Config )
984 {
985 if ( ((*puCanonPhase >> i) & 1) != ((*puCanonPhase >> (i+1)) & 1) )
986 {
987 *puCanonPhase ^= (1 << i);
988 *puCanonPhase ^= (1 << (i+1));
989 }
990 ABC_SWAP( int, pCanonPerm[i], pCanonPerm[i+1] );
991 }
992 return Config;
993 }
994 {
995 static word pCopy1[1024];
996 int Config;
997 Abc_TtCopy( pCopy1, pTruth, nWords, 0 );
998 Config = Abc_TtCofactorPermConfig( pTruth, i, nWords, 0, fNaive );
999 if ( Config == 0 )
1000 return 0;
1001 if ( Abc_TtCompareRev(pTruth, pCopy1, nWords) == 1 ) // made it worse
1002 {
1003 Abc_TtCopy( pTruth, pCopy1, nWords, 0 );
1004 return 0;
1005 }
1006 // improved
1007 if ( Config & 1 )
1008 *puCanonPhase ^= (1 << i);
1009 if ( Config & 2 )
1010 *puCanonPhase ^= (1 << (i+1));
1011 if ( Config & 4 )
1012 {
1013 if ( ((*puCanonPhase >> i) & 1) != ((*puCanonPhase >> (i+1)) & 1) )
1014 {
1015 *puCanonPhase ^= (1 << i);
1016 *puCanonPhase ^= (1 << (i+1));
1017 }
1018 ABC_SWAP( int, pCanonPerm[i], pCanonPerm[i+1] );
1019 }
1020 return Config;
1021 }
1022}
1023
1035//#define CANON_VERIFY
1036unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm )
1037{
1038 int pStoreIn[17];
1039 unsigned uCanonPhase;
1040 int i, k, nWords = Abc_TtWordNum( nVars );
1041 int fNaive = 1;
1042
1043#ifdef CANON_VERIFY
1044 char pCanonPermCopy[16];
1045 static word pCopy1[1024];
1046 static word pCopy2[1024];
1047 Abc_TtCopy( pCopy1, pTruth, nWords, 0 );
1048#endif
1049
1050 uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn, 0 );
1051 for ( k = 0; k < 5; k++ )
1052 {
1053 int fChanges = 0;
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 );
1057 if ( !fChanges )
1058 break;
1059 fChanges = 0;
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 );
1063 if ( !fChanges )
1064 break;
1065 }
1066
1067#ifdef CANON_VERIFY
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" );
1073#endif
1074/*
1075 if ( !Abc_TtEqual( pCopy1, pCopy2, nWords ) )
1076 {
1077 Kit_DsdPrintFromTruth( pCopy1, nVars ); printf( "\n" );
1078 Kit_DsdPrintFromTruth( pCopy2, nVars ); printf( "\n" );
1079 i = 0;
1080 }
1081*/
1082 return uCanonPhase;
1083}
1084
1085unsigned Abc_TtCanonicizePerm( word * pTruth, int nVars, char * pCanonPerm )
1086{
1087 int pStoreIn[17];
1088 unsigned uCanonPhase;
1089 int i, k, nWords = Abc_TtWordNum( nVars );
1090 int fNaive = 1;
1091
1092#ifdef CANON_VERIFY
1093 char pCanonPermCopy[16];
1094 static word pCopy1[1024];
1095 static word pCopy2[1024];
1096 Abc_TtCopy( pCopy1, pTruth, nWords, 0 );
1097#endif
1098
1099 assert( nVars <= 16 );
1100 for ( i = 0; i < nVars; i++ )
1101 pCanonPerm[i] = i;
1102
1103 uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn, 1 );
1104 for ( k = 0; k < 5; k++ )
1105 {
1106 int fChanges = 0;
1107 for ( i = nVars - 2; i >= 0; i-- )
1108 if ( pStoreIn[i] == pStoreIn[i+1] )
1109 fChanges |= Abc_TtCofactorPerm( pTruth, i, nWords, 1, pCanonPerm, &uCanonPhase, fNaive );
1110 if ( !fChanges )
1111 break;
1112 fChanges = 0;
1113 for ( i = 1; i < nVars - 1; i++ )
1114 if ( pStoreIn[i] == pStoreIn[i+1] )
1115 fChanges |= Abc_TtCofactorPerm( pTruth, i, nWords, 1, pCanonPerm, &uCanonPhase, fNaive );
1116 if ( !fChanges )
1117 break;
1118 }
1119
1120#ifdef CANON_VERIFY
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" );
1126#endif
1127
1128 assert( uCanonPhase == 0 );
1129 return uCanonPhase;
1130}
1131
1143static inline int Abc_TtCanonicizePhaseVar6( word * pTruth, int nVars, int v )
1144{
1145 int w, nWords = Abc_TtWordNum( nVars );
1146 int s, nStep = 1 << (v-6);
1147 assert( v >= 6 );
1148 for ( w = nWords - 1, s = nWords - nStep; w > 0; w-- )
1149 {
1150 if ( pTruth[w-nStep] == pTruth[w] )
1151 {
1152 if ( w == s ) { w = s - nStep; s = w - nStep; }
1153 continue;
1154 }
1155 if ( pTruth[w-nStep] > pTruth[w] )
1156 return -1;
1157 for ( ; w > 0; w-- )
1158 {
1159 ABC_SWAP( word, pTruth[w-nStep], pTruth[w] );
1160 if ( w == s ) { w = s - nStep; s = w - nStep; }
1161 }
1162 assert( w == -1 );
1163 return 1;
1164 }
1165 return 0;
1166}
1167static inline int Abc_TtCanonicizePhaseVar5( word * pTruth, int nVars, int v )
1168{
1169 int w, nWords = Abc_TtWordNum( nVars );
1170 int Shift = 1 << v;
1171 word Mask = s_Truths6[v];
1172 assert( v < 6 );
1173 for ( w = nWords - 1; w >= 0; w-- )
1174 {
1175 if ( ((pTruth[w] << Shift) & Mask) == (pTruth[w] & Mask) )
1176 continue;
1177 if ( ((pTruth[w] << Shift) & Mask) > (pTruth[w] & Mask) )
1178 return -1;
1179// Extra_PrintHex( stdout, (unsigned *)pTruth, nVars ); printf("\n" );
1180 for ( ; w >= 0; w-- )
1181 pTruth[w] = ((pTruth[w] << Shift) & Mask) | ((pTruth[w] & Mask) >> Shift);
1182// Extra_PrintHex( stdout, (unsigned *)pTruth, nVars ); printf( " changed %d", v ), printf("\n" );
1183 return 1;
1184 }
1185 return 0;
1186}
1187unsigned Abc_TtCanonicizePhase( word * pTruth, int nVars )
1188{
1189 unsigned uCanonPhase = 0;
1190 int v, nWords = Abc_TtWordNum( nVars );
1191// static int Counter = 0;
1192// Counter++;
1193
1194#ifdef CANON_VERIFY
1195 static word pCopy1[1024];
1196 static word pCopy2[1024];
1197 Abc_TtCopy( pCopy1, pTruth, nWords, 0 );
1198#endif
1199
1200 if ( (pTruth[nWords-1] >> 63) & 1 )
1201 {
1202 Abc_TtNot( pTruth, nWords );
1203 uCanonPhase ^= (1 << nVars);
1204 }
1205
1206// while ( 1 )
1207// {
1208// unsigned uCanonPhase2 = uCanonPhase;
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;
1215// if ( uCanonPhase2 == uCanonPhase )
1216// break;
1217// }
1218
1219// for ( v = 5; v >= 0; v-- )
1220// assert( Abc_TtCanonicizePhaseVar5( pTruth, nVars, v ) != 1 );
1221
1222#ifdef CANON_VERIFY
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" );
1227#endif
1228 return uCanonPhase;
1229}
1230
1231
1243#define TT_MAX_LEVELS 5
1244
1246{
1248 Vec_Mem_t * vTtMem[TT_MAX_LEVELS]; // truth table memory and hash tables
1249 Vec_Int_t * vRepres[TT_MAX_LEVELS]; // pointers to the representatives from the last hierarchical level
1251
1253};
1254
1255Abc_TtHieMan_t * Abc_TtHieManStart(int nVars, int nLevels)
1256{
1257 Abc_TtHieMan_t * p = NULL;
1258 int i;
1259 if (nLevels > TT_MAX_LEVELS) return p;
1261 p->nLastLevel = nLevels - 1;
1262 p->nWords = Abc_TtWordNum(nVars);
1263 for (i = 0; i < nLevels; i++)
1264 {
1265 p->vTtMem[i] = Vec_MemAlloc(p->nWords, 12);
1266 Vec_MemHashAlloc(p->vTtMem[i], 10000);
1267 p->vRepres[i] = Vec_IntAlloc(1);
1268 }
1269 p->vPhase = Vec_IntAlloc(2500);
1270 return p;
1271}
1272
1274{
1275 int i;
1276 for (i = 0; i <= p->nLastLevel; i++)
1277 {
1278 Vec_MemHashFree(p->vTtMem[i]);
1279 Vec_MemFreeP(&p->vTtMem[i]);
1280 Vec_IntFree(p->vRepres[i]);
1281 }
1282 Vec_IntFree( p->vPhase );
1283 ABC_FREE(p);
1284}
1285
1286int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t * p, int level, word * pTruth, word * pResult)
1287{
1288 int i, iSpot, truthId;
1289 word * pRepTruth;
1290 if (!p) return -1;
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);
1294 if (iSpot == -1) {
1295 p->vTruthId[level] = Vec_MemHashInsert(p->vTtMem[level], pTruth);
1296 if (level < p->nLastLevel) return 0;
1297 iSpot = p->vTruthId[level];
1298 }
1299 // return the class representative
1300 if (level < p->nLastLevel)
1301 truthId = Vec_IntEntry(p->vRepres[level], iSpot);
1302 else
1303 truthId = iSpot;
1304 for (i = 0; i < level; i++)
1305 Vec_IntSetEntry(p->vRepres[i], p->vTruthId[i], truthId);
1306
1307 pRepTruth = Vec_MemReadEntry(p->vTtMem[p->nLastLevel], truthId);
1308 if (level < p->nLastLevel) {
1309 Abc_TtCopy(pResult, pRepTruth, p->nWords, 0);
1310 return 1;
1311 }
1312 assert(Abc_TtEqual(pTruth, pRepTruth, p->nWords));
1313 if (pTruth != pResult)
1314 Abc_TtCopy(pResult, pRepTruth, p->nWords, 0);
1315 return 0;
1316}
1317
1318unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, char * pCanonPerm, int fExact )
1319{
1320 int fNaive = 1;
1321 int pStore[17];
1322 //static word pTruth[1024];
1323 word * pTruth = pTruthInit;
1324 unsigned uCanonPhase = 0;
1325 int nOnes, nWords = Abc_TtWordNum( nVars );
1326 int i, k;
1327 assert( nVars <= 16 );
1328
1329 // handle constant
1330 if ( nVars == 0 )
1331 {
1332 Abc_TtClear( pTruthInit, nWords );
1333 return 0;
1334 }
1335
1336 //Abc_TtCopy( pTruth, pTruthInit, nWords, 0 );
1337
1338 for ( i = 0; i < nVars; i++ )
1339 pCanonPerm[i] = i;
1340
1341 // normalize polarity
1342 nOnes = Abc_TtCountOnesInTruth( pTruth, nVars );
1343 if ( nOnes > nWords * 32 )
1344 {
1345 Abc_TtNot( pTruth, nWords );
1346 nOnes = nWords*64 - nOnes;
1347 uCanonPhase |= (1 << nVars);
1348 }
1349 // check cache
1350 if (Abc_TtHieRetrieveOrInsert(p, 0, pTruth, pTruthInit) > 0) return 0;
1351
1352 // normalize phase
1353 Abc_TtCountOnesInCofs( pTruth, nVars, pStore );
1354 pStore[nVars] = nOnes;
1355 for ( i = 0; i < nVars; i++ )
1356 {
1357 if ( pStore[i] >= nOnes - pStore[i] )
1358 continue;
1359 Abc_TtFlip( pTruth, nWords, i );
1360 uCanonPhase |= (1 << i);
1361 pStore[i] = nOnes - pStore[i];
1362 }
1363 // check cache
1364 if (Abc_TtHieRetrieveOrInsert(p, 1, pTruth, pTruthInit) > 0) return 0;
1365
1366 // normalize permutation
1367 {
1368 int k, BestK;
1369 for ( i = 0; i < nVars - 1; i++ )
1370 {
1371 BestK = i + 1;
1372 for ( k = i + 2; k < nVars; k++ )
1373 if ( pStore[BestK] > pStore[k] )
1374 BestK = k;
1375 if ( pStore[i] <= pStore[BestK] )
1376 continue;
1377 ABC_SWAP( int, pCanonPerm[i], pCanonPerm[BestK] );
1378 ABC_SWAP( int, pStore[i], pStore[BestK] );
1379 if ( ((uCanonPhase >> i) & 1) != ((uCanonPhase >> BestK) & 1) )
1380 {
1381 uCanonPhase ^= (1 << i);
1382 uCanonPhase ^= (1 << BestK);
1383 }
1384 Abc_TtSwapVars( pTruth, nVars, i, BestK );
1385 }
1386 }
1387 // check cache
1388 if (Abc_TtHieRetrieveOrInsert(p, 2, pTruth, pTruthInit) > 0) return 0;
1389
1390 // iterate TT permutations for tied variables
1391 for ( k = 0; k < 5; k++ )
1392 {
1393 int fChanges = 0;
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 );
1397 if ( !fChanges )
1398 break;
1399 fChanges = 0;
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 );
1403 if ( !fChanges )
1404 break;
1405 }
1406 // check cache
1407 if (Abc_TtHieRetrieveOrInsert(p, 3, pTruth, pTruthInit) > 0) return 0;
1408
1409 // perform exact NPN using groups
1410 if ( fExact ) {
1411 extern void simpleMinimalGroups(word* x, word* pAux, word* minimal, int* pGroups, int nGroups, permInfo** pis, int nVars, int fFlipOutput, int fFlipInput);
1412 word pAuxWord[1024], pAuxWord1[1024];
1413 int pGroups[16];
1414 int nGroups = 0;
1415 permInfo * pis[17];
1416 // get groups
1417 pGroups[0] = 0;
1418 for (i = 0; i < nVars - 1; i++) {
1419 if (pStore[i] == pStore[i + 1]) {
1420 pGroups[nGroups]++;
1421 } else {
1422 pGroups[nGroups]++;
1423 nGroups++;
1424 pGroups[nGroups] = 0;
1425 }
1426 }
1427 pGroups[nGroups]++;
1428 nGroups++;
1429
1430 // compute permInfo from 0 to nVars (incl.)
1431 for (i = 0; i <= nVars; i++) {
1432 pis[i] = setPermInfoPtr(i);
1433 }
1434
1435 // do the exact matching
1436 if (nOnes == nWords * 32) /* balanced output */
1437 simpleMinimalGroups(pTruth, pAuxWord, pAuxWord1, pGroups, nGroups, pis, nVars, 1, 1);
1438 else if (pStore[0] != pStore[1] && pStore[0] == (nOnes - pStore[0])) /* balanced singleton input */
1439 simpleMinimalGroups(pTruth, pAuxWord, pAuxWord1, pGroups, nGroups, pis, nVars, 0, 1);
1440 else
1441 simpleMinimalGroups(pTruth, pAuxWord, pAuxWord1, pGroups, nGroups, pis, nVars, 0, 0);
1442
1443 // cleanup
1444 for (i = 0; i <= nVars; i++) {
1445 freePermInfoPtr(pis[i]);
1446 }
1447 }
1448 // update cache
1449 Abc_TtHieRetrieveOrInsert(p, 4, pTruth, pTruthInit);
1450 return 0;
1451}
1452
1453
1465
1466typedef struct TiedGroup_
1467{
1468 char iStart; // index of Abc_TgMan_t::pPerm
1469 char nGVars; // the number of variables in the group
1471
1472typedef struct Abc_TgMan_t_
1473{
1475 int nVars; // the number of variables
1476 int nGVars; // the number of variables in groups ( symmetric variables purged )
1477 int nGroups; // the number of tied groups
1478 unsigned uPhase; // phase of each variable and the function
1479 int fPhased; // if the phases of all the variables are determined
1480 char pPerm[16]; // permutation of variables, symmetric variables purged, for grouping
1481 char pPermT[16]; // permutation of variables, symmetric variables expanded, actual transformation for pTruth
1482 char pPermTRev[16]; // reverse permutation of pPermT
1483 signed char pPermDir[16]; // for generating the next permutation
1484 TiedGroup pGroup[16]; // tied groups
1485 // symemtric group attributes
1486 char symPhase[16]; // phase type of symemtric groups
1487 signed char symLink[17]; // singly linked list, indicate the variables in symemtric groups
1488
1489 int nAlgorithm; // 0: AdjCE, 1: AdjSE, 2: E: Cost-Aware
1490 char pFGrps[16]; // tied groups to be flipped
1491 Vec_Int_t * vPhase; // candidate phase assignments
1493
1494#if !defined(NDEBUG) && !defined(CANON_VERIFY)
1495#define CANON_VERIFY
1496#endif
1508
1509// JohnsonCTrotter algorithm
1510static int Abc_NextPermSwapC(char * pData, signed char * pDir, int size)
1511{
1512 int i, j, k = -1;
1513 for (i = 0; i < size; i++)
1514 {
1515 j = i + pDir[i];
1516 if (j >= 0 && j < size && pData[i] > pData[j] && (k < 0 || pData[i] > pData[k]))
1517 k = i;
1518 }
1519 if (k < 0) k = 0;
1520
1521 for (i = 0; i < size; i++)
1522 if (pData[i] > pData[k])
1523 pDir[i] = -pDir[i];
1524
1525 j = k + pDir[k];
1526 return j < k ? j : k;
1527}
1528
1529//typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
1530unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag)
1531{
1532 int nWords = Abc_TtWordNum(nVars);
1533 unsigned uCanonPhase1, uCanonPhase2;
1534 char pCanonPerm2[16];
1535 static word pTruth2[1024];
1536
1537 Abc_TtNormalizeSmallTruth(pTruth, nVars);
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;
1548}
1549
1551static int Abc_TtCannonVerify(word* pTruth, int nVars, char * pCanonPerm, unsigned uCanonPhase)
1552{
1553#ifdef CANON_VERIFY
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);
1561 return Abc_TtEqual(gpVerCopy, pCopy2, nWords);
1562#else
1563 return 1;
1564#endif
1565}
1566
1578
1579static void Abc_TgInitMan(Abc_TgMan_t * pMan, word * pTruth, int nVars, int nAlg, Vec_Int_t * vPhase)
1580{
1581 int i;
1582 pMan->pTruth = pTruth;
1583 pMan->uPhase = 0;
1584 pMan->fPhased = 0;
1585 pMan->nVars = pMan->nGVars = nVars;
1586 pMan->nGroups = 1;
1587 pMan->pGroup[0].iStart = 0;
1588 pMan->pGroup[0].nGVars = nVars;
1589 for (i = 0; i < nVars; i++)
1590 {
1591 pMan->pPerm[i] = i;
1592 pMan->pPermT[i] = i;
1593 pMan->pPermTRev[i] = i;
1594 pMan->symPhase[i] = 1;
1595 pMan->symLink[i] = -1;
1596 }
1597 pMan->symLink[i] = -1;
1598 pMan->nAlgorithm = nAlg;
1599 pMan->vPhase = vPhase;
1600 Vec_IntClear(vPhase);
1601}
1602
1603static int Abc_TgSplitGroup(Abc_TgMan_t * pMan, TiedGroup * pGrp, int * pCoef)
1604{
1605 int i, j, n = 0;
1606 int nGVars = pGrp->nGVars;
1607 char * pVars = pMan->pPerm + pGrp->iStart;
1608 int iGrp = pGrp - pMan->pGroup;
1609
1610 // sort variables
1611 for (i = 1; i < nGVars; i++)
1612 {
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;
1617 }
1618 for (i = 1; i < nGVars; i++)
1619 if (pCoef[i] != pCoef[i - 1]) n++;
1620 if (n == 0) return 0;
1621 memmove(pGrp + n + 1, pGrp + 1, (pMan->nGroups - iGrp - 1) * sizeof(TiedGroup));
1622 // group variables
1623 for (i = j = 1; i < nGVars; i++)
1624 {
1625 if (pCoef[i] == pCoef[i - 1]) continue;
1626 pGrp[j].iStart = pGrp->iStart + i;
1627 pGrp[j - 1].nGVars = pGrp[j].iStart - pGrp[j - 1].iStart;
1628 j++;
1629 }
1630 assert(j == n + 1);
1631 pGrp[n].nGVars = pGrp->iStart + i - pGrp[n].iStart;
1632 pMan->nGroups += n;
1633 return n;
1634}
1635static inline void Abc_TgManCopy(Abc_TgMan_t* pDst, word* pDstTruth, Abc_TgMan_t* pSrc)
1636{
1637 *pDst = *pSrc;
1638 Abc_TtCopy(pDstTruth, pSrc->pTruth, Abc_TtWordNum(pSrc->nVars), 0);
1639 pDst->pTruth = pDstTruth;
1640}
1641
1642static inline int Abc_TgCannonVerify(Abc_TgMan_t* pMan)
1643{
1644 return Abc_TtCannonVerify(pMan->pTruth, pMan->nVars, pMan->pPermT, pMan->uPhase);
1645}
1646
1647extern int Abc_TgExpendSymmetry(Abc_TgMan_t * pMan, char * pDest);
1648
1649static void CheckConfig(Abc_TgMan_t * pMan)
1650{
1651#ifndef NDEBUG
1652 int i;
1653 char pPermE[16];
1654 Abc_TgExpendSymmetry(pMan, pPermE);
1655 for (i = 0; i < pMan->nVars; i++)
1656 {
1657 assert(pPermE[i] == pMan->pPermT[i]);
1658 assert(pMan->pPermTRev[(int)pMan->pPermT[i]] == i);
1659 }
1660 assert(Abc_TgCannonVerify(pMan));
1661#endif
1662}
1663
1675
1676static inline void Abc_TgFlipVar(Abc_TgMan_t* pMan, int iVar)
1677{
1678 int nWords = Abc_TtWordNum(pMan->nVars);
1679 int ivp = pMan->pPermTRev[iVar];
1680 Abc_TtFlip(pMan->pTruth, nWords, ivp);
1681 pMan->uPhase ^= 1 << ivp;
1682}
1683
1684static inline void Abc_TgFlipSymGroupByVar(Abc_TgMan_t* pMan, int iVar)
1685{
1686 for (; iVar >= 0; iVar = pMan->symLink[iVar])
1687 if (pMan->symPhase[iVar])
1688 Abc_TgFlipVar(pMan, iVar);
1689}
1690
1691static inline void Abc_TgFlipSymGroup(Abc_TgMan_t* pMan, int idx)
1692{
1693 Abc_TgFlipSymGroupByVar(pMan, pMan->pPerm[idx]);
1694}
1695
1696static inline void Abc_TgClearSymGroupPhase(Abc_TgMan_t* pMan, int iVar)
1697{
1698 for (; iVar >= 0; iVar = pMan->symLink[iVar])
1699 pMan->symPhase[iVar] = 0;
1700}
1701
1702static void Abc_TgImplementPerm(Abc_TgMan_t* pMan, const char *pPermDest)
1703{
1704 int i, nVars = pMan->nVars;
1705 char *pPerm = pMan->pPermT;
1706 char *pRev = pMan->pPermTRev;
1707 unsigned uPhase = pMan->uPhase & (1 << nVars);
1708
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;
1715
1716 Abc_TtImplementNpnConfig(pMan->pTruth, nVars, pRev, 0);
1717// Abc_TtVerifySmallTruth(pMan->pTruth, nVars);
1718
1719 for (i = 0; i < nVars; i++)
1720 {
1721 if (pMan->uPhase & (1 << pPerm[i]))
1722 uPhase |= (1 << i);
1723 pPerm[i] = pPermDest[i];
1724 pRev[(int)pPerm[i]] = i;
1725 }
1726 pMan->uPhase = uPhase;
1727}
1728
1729static void Abc_TgSwapAdjacentSymGroups(Abc_TgMan_t* pMan, int idx)
1730{
1731 int iVar, jVar, ix;
1732 char pPermNew[16];
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;
1738 ABC_SWAP(char, pMan->pPermDir[idx], pMan->pPermDir[idx + 1]);
1739 if (pMan->symLink[iVar] >= 0 || pMan->symLink[jVar] >= 0)
1740 {
1741 Abc_TgExpendSymmetry(pMan, pPermNew);
1742 Abc_TgImplementPerm(pMan, pPermNew);
1743 return;
1744 }
1745 // plain variable swap
1746 ix = pMan->pPermTRev[iVar];
1747 assert(pMan->pPermT[ix] == iVar && pMan->pPermT[ix + 1] == jVar);
1748 Abc_TtSwapAdjacent(pMan->pTruth, Abc_TtWordNum(pMan->nVars), ix);
1749 pMan->pPermT[ix] = jVar;
1750 pMan->pPermT[ix + 1] = iVar;
1751 pMan->pPermTRev[iVar] = ix + 1;
1752 pMan->pPermTRev[jVar] = ix;
1753 if (((pMan->uPhase >> ix) & 1) != ((pMan->uPhase >> (ix + 1)) & 1))
1754 pMan->uPhase ^= 1 << ix | 1 << (ix + 1);
1755 assert(Abc_TgCannonVerify(pMan));
1756}
1757
1769
1770static word pSymCopy[1024];
1771
1772static int Abc_TtIsSymmetric(word * pTruth, int nVars, int iVar, int jVar, int fPhase)
1773{
1774 int rv;
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);
1783}
1784
1785static int Abc_TtIsSymmetricHigh(Abc_TgMan_t * pMan, int iVar, int jVar, int fPhase)
1786{
1787 int rv, iv, jv, n;
1788 int nWords = Abc_TtWordNum(pMan->nVars);
1789 Abc_TtCopy(pSymCopy, pMan->pTruth, nWords, 0);
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); // two symmetric groups must have the same size
1793 rv = Abc_TtEqual(pMan->pTruth, pSymCopy, nWords) * 2;
1794 if (!fPhase) return rv;
1795 for (iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->symLink[iv], jv = pMan->symLink[jv])
1796 {
1797 if (pMan->symPhase[iv]) Abc_TtFlip(pSymCopy, nWords, iv);
1798 if (pMan->symPhase[jv]) Abc_TtFlip(pSymCopy, nWords, jv);
1799 }
1800 return rv + Abc_TtEqual(pMan->pTruth, pSymCopy, nWords);
1801}
1802
1816
1817static void Abc_TgCreateGroups(Abc_TgMan_t * pMan)
1818{
1819 int pStore[17];
1820 int i, nOnes;
1821 int nVars = pMan->nVars, nWords = Abc_TtWordNum(nVars);
1822 //TiedGroup * pGrp = pMan->pGroup;
1823 assert(nVars <= 16);
1824 // normalize polarity
1825 nOnes = Abc_TtCountOnesInTruth(pMan->pTruth, nVars);
1826 if (nOnes > nWords * 32)
1827 {
1828 Abc_TtNot(pMan->pTruth, nWords);
1829 nOnes = nWords * 64 - nOnes;
1830 pMan->uPhase |= (1 << nVars);
1831 }
1832 // normalize phase
1833 Abc_TtCountOnesInCofs(pMan->pTruth, nVars, pStore);
1834 pStore[nVars] = nOnes;
1835 for (i = 0; i < nVars; i++)
1836 {
1837 if (pStore[i] >= nOnes - pStore[i])
1838 continue;
1839 Abc_TtFlip(pMan->pTruth, nWords, i);
1840 pMan->uPhase |= (1 << i);
1841 pStore[i] = nOnes - pStore[i];
1842 }
1843
1844 Abc_TgSplitGroup(pMan, pMan->pGroup, pStore);
1845 pMan->fPhased = pStore[0] * 2 != nOnes;
1846}
1847
1859
1860static int Abc_TgGroupSymmetry(Abc_TgMan_t * pMan, TiedGroup * pGrp, int fHigh)
1861{
1862 int i, j, iVar, jVar, nsym = 0;
1863 int fDone[16], scnt[16], stype[16];
1864 signed char *symLink = pMan->symLink;
1865// char * symPhase = pMan->symPhase;
1866 int nGVars = pGrp->nGVars;
1867 int fPhase = (pGrp == pMan->pGroup) && !pMan->fPhased;
1868 char * pVars = pMan->pPerm + pGrp->iStart;
1869 int modified;
1870
1871 for (i = 0; i < nGVars; i++)
1872 fDone[i] = 0, scnt[i] = 1;
1873
1874 do {
1875 modified = 0;
1876 for (i = 0; i < nGVars - 1; i++)
1877 {
1878 iVar = pVars[i];
1879 if (iVar < 0 || fDone[i]) continue;
1880// if (!pGrp->fPhased && !Abc_TtHasVar(pMan->pTruth, pMan->nVars, iVar)) continue;
1881 // Mark symmetric variables/groups
1882 for (j = i + 1; j < nGVars; j++)
1883 {
1884 jVar = pVars[j];
1885 if (jVar < 0 || scnt[j] != scnt[i]) // || pMan->symPhase[jVar] != pMan->symPhase[iVar])
1886 stype[j] = 0;
1887 else if (scnt[j] == 1)
1888 stype[j] = Abc_TtIsSymmetric(pMan->pTruth, pMan->nVars, iVar, jVar, fPhase);
1889 else
1890 stype[j] = Abc_TtIsSymmetricHigh(pMan, iVar, jVar, fPhase);
1891 }
1892 fDone[i] = 1;
1893 // Merge symmetric groups
1894 for (j = i + 1; j < nGVars; j++)
1895 {
1896 int ii;
1897 jVar = pVars[j];
1898 switch (stype[j])
1899 {
1900 case 1: // E-Symmetry
1901 Abc_TgFlipSymGroupByVar(pMan, jVar);
1902 // fallthrough
1903 case 2: // NE-Symmetry
1904 pMan->symPhase[iVar] += pMan->symPhase[jVar];
1905 break;
1906 case 3: // multiform Symmetry
1907 Abc_TgClearSymGroupPhase(pMan, jVar);
1908 break;
1909 default: // case 0: No Symmetry
1910 continue;
1911 }
1912
1913 for (ii = iVar; symLink[ii] >= 0; ii = symLink[ii])
1914 ;
1915 symLink[ii] = jVar;
1916 pVars[j] = -1;
1917 scnt[i] += scnt[j];
1918 modified = 1;
1919 fDone[i] = 0;
1920 nsym++;
1921 }
1922 }
1923// if (++order > 3) printf("%d", order);
1924 } while (fHigh && modified);
1925
1926 return nsym;
1927}
1928
1929static void Abc_TgPurgeSymmetry(Abc_TgMan_t * pMan, int fHigh)
1930{
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;
1935
1936 // purge unsupported variables
1937 if (!pMan->fPhased)
1938 {
1939 int iVar = pMan->nVars;
1940 for (j = 0; j < pMan->pGroup[0].nGVars; j++)
1941 {
1942 int jVar = pPerm[j];
1943 assert(jVar >= 0);
1944 if (!Abc_TtHasVar(pMan->pTruth, nVars, jVar))
1945 {
1946 symLink[jVar] = symLink[iVar];
1947 symLink[iVar] = jVar;
1948 pPerm[j] = -1;
1949 gcnt[0]++;
1950 }
1951 }
1952 }
1953
1954 for (k = 0; k < pMan->nGroups; k++)
1955 gcnt[k] += Abc_TgGroupSymmetry(pMan, pMan->pGroup + k, fHigh);
1956
1957 for (i = 0; i < nVars && pPerm[i] >= 0; i++)
1958 ;
1959 for (j = i + 1; ; i++, j++)
1960 {
1961 while (j < nVars && pPerm[j] < 0) j++;
1962 if (j >= nVars) break;
1963 pPerm[i] = pPerm[j];
1964 }
1965 for (k = 0; k < pMan->nGroups; k++)
1966 {
1967 pMan->pGroup[k].nGVars -= gcnt[k];
1968 pMan->pGroup[k].iStart -= sum;
1969 sum += gcnt[k];
1970 }
1971 if (pMan->pGroup[0].nGVars == 0)
1972 {
1973 pMan->nGroups--;
1974 memmove(pMan->pGroup, pMan->pGroup + 1, sizeof(TiedGroup) * pMan->nGroups);
1975 assert(pMan->pGroup[0].iStart == 0);
1976 }
1977 pMan->nGVars -= sum;
1978}
1979
1980int Abc_TgExpendSymmetry(Abc_TgMan_t * pMan, char * pDest)
1981{
1982 int i = 0, j, k, s;
1983 char * pPerm = pMan->pPerm;
1984 for (j = 0; j < pMan->nGVars; j++)
1985 for (k = pPerm[j]; k >= 0; k = pMan->symLink[k])
1986 pDest[i++] = k;
1987 s = i;
1988 for (k = pMan->symLink[pMan->nVars]; k >= 0; k = pMan->symLink[k])
1989 pDest[i++] = k;
1990 assert(i == pMan->nVars);
1991 return s;
1992}
1993
1994static void Abc_TgResetGroup(Abc_TgMan_t * pMan)
1995{
1996 int i, j;
1997 char * pPerm = pMan->pPerm;
1998 char pPermNew[16];
1999 int nGVars = pMan->nGVars;
2000 for (i = 1; i < nGVars; i++)
2001 {
2002 char t = pPerm[i];
2003 for (j = i; j > 0 && pPerm[j - 1] > t; j--)
2004 pPerm[j] = pPerm[j - 1];
2005 pPerm[j] = t;
2006 }
2007 Abc_TgExpendSymmetry(pMan, pPermNew);
2008 Abc_TgImplementPerm(pMan, pPermNew);
2009 pMan->fPhased = 0;
2010 pMan->nGroups = 1;
2011 pMan->pGroup->nGVars = nGVars;
2012 Vec_IntClear(pMan->vPhase);
2013}
2014
2015static void Abc_TgResetGroup1(Abc_TgMan_t * pMan)
2016{
2017 int i, j;
2018 char pPermNew[16];
2019 int nSVars = Abc_TgExpendSymmetry(pMan, pPermNew);
2020 for (i = 1; i < nSVars; i++)
2021 {
2022 char t = pPermNew[i];
2023 for (j = i; j > 0 && pPermNew[j - 1] > t; j--)
2024 pPermNew[j] = pPermNew[j - 1];
2025 pPermNew[j] = t;
2026 }
2027 Abc_TgImplementPerm(pMan, pPermNew);
2028 pMan->fPhased = 0;
2029 pMan->nGroups = 1;
2030 pMan->nGVars = pMan->pGroup->nGVars = nSVars;
2031 for (i = 0; i < pMan->nVars; i++)
2032 {
2033 pMan->pPerm[i] = pPermNew[i];
2034 pMan->symPhase[i] = 1;
2035 pMan->symLink[i] = -1;
2036 }
2037 Vec_IntClear(pMan->vPhase);
2038}
2039
2051static int Abc_TgSymGroupPerm(Abc_TgMan_t* pMan, int idx, int fSwapOnly)
2052{
2053 word* pTruth = pMan->pTruth;
2054 static word pCopy[1024];
2055 static word pBest[1024];
2056 int Config = 0;
2057 int nWords = Abc_TtWordNum(pMan->nVars);
2058 Abc_TgMan_t tgManCopy, tgManBest;
2059
2060 CheckConfig(pMan);
2061 if (fSwapOnly)
2062 {
2063 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2064 Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx);
2065 CheckConfig(&tgManCopy);
2066 if (Abc_TtCompareRev(pTruth, pCopy, nWords) < 0)
2067 {
2068 Abc_TgManCopy(pMan, pTruth, &tgManCopy);
2069 return 4;
2070 }
2071 return 0;
2072 }
2073
2074 // save two copies
2075 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2076 Abc_TgManCopy(&tgManBest, pBest, pMan);
2077 // PXY
2078 // 001
2079 Abc_TgFlipSymGroup(&tgManCopy, idx);
2080 CheckConfig(&tgManCopy);
2081 if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1)
2082 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 1;
2083 // PXY
2084 // 011
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;
2089 // PXY
2090 // 010
2091 Abc_TgFlipSymGroup(&tgManCopy, idx);
2092 CheckConfig(&tgManCopy);
2093 if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1)
2094 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 2;
2095 // PXY
2096 // 110
2097 Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx);
2098 CheckConfig(&tgManCopy);
2099 if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1)
2100 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 6;
2101 // PXY
2102 // 111
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;
2107 // PXY
2108 // 101
2109 Abc_TgFlipSymGroup(&tgManCopy, idx);
2110 CheckConfig(&tgManCopy);
2111 if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1)
2112 Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 5;
2113 // PXY
2114 // 100
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;
2119 // PXY
2120 // 000
2121 Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx);
2122 CheckConfig(&tgManCopy);
2123 assert(Abc_TtEqual(pTruth, pCopy, nWords));
2124 if (Config == 0)
2125 return 0;
2126 assert(Abc_TtCompareRev(pTruth, pBest, nWords) == 1);
2127 Abc_TgManCopy(pMan, pTruth, &tgManBest);
2128 return Config;
2129}
2130
2131static int Abc_TgPermPhase(Abc_TgMan_t* pMan, int iVar)
2132{
2133 static word pCopy[1024];
2134 int nWords = Abc_TtWordNum(pMan->nVars);
2135 int ivp = pMan->pPermTRev[iVar];
2136 Abc_TtCopy(pCopy, pMan->pTruth, nWords, 0);
2137 Abc_TtFlip(pCopy, nWords, ivp);
2138 if (Abc_TtCompareRev(pMan->pTruth, pCopy, nWords) == 1)
2139 {
2140 Abc_TtCopy(pMan->pTruth, pCopy, nWords, 0);
2141 pMan->uPhase ^= 1 << ivp;
2142 return 16;
2143 }
2144 return 0;
2145}
2146
2147static void Abc_TgSimpleEnumeration(Abc_TgMan_t * pMan)
2148{
2149 int i, j, k;
2150 int pGid[16];
2151
2152 for (k = j = 0; j < pMan->nGroups; j++)
2153 for (i = 0; i < pMan->pGroup[j].nGVars; i++, k++)
2154 pGid[k] = j;
2155 assert(k == pMan->nGVars);
2156
2157 for (k = 0; k < 5; k++)
2158 {
2159 int fChanges = 0;
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);
2166
2167 for (i = pMan->nVars - 1; i >= 0; i--)
2168 if (pMan->symPhase[i])
2169 fChanges |= Abc_TgPermPhase(pMan, i);
2170 for (i = 1; i < pMan->nVars; i++)
2171 if (pMan->symPhase[i])
2172 fChanges |= Abc_TgPermPhase(pMan, i);
2173 if (!fChanges) break;
2174 }
2175 assert(Abc_TgCannonVerify(pMan));
2176}
2177
2189
2190static int Abc_TgIsInitPerm(char * pData, signed char * pDir, int size)
2191{
2192 int i;
2193 if (pDir[0] != -1) return 0;
2194 for (i = 1; i < size; i++)
2195 if (pDir[i] != -1 || pData[i] < pData[i - 1])
2196 return 0;
2197 return 1;
2198}
2199
2200static void Abc_TgFirstPermutation(Abc_TgMan_t * pMan)
2201{
2202 int i;
2203 for (i = 0; i < pMan->nGVars; i++)
2204 pMan->pPermDir[i] = -1;
2205#ifndef NDEBUG
2206 for (i = 0; i < pMan->nGroups; i++)
2207 {
2208 TiedGroup * pGrp = pMan->pGroup + i;
2209 int nGvars = pGrp->nGVars;
2210 char * pVars = pMan->pPerm + pGrp->iStart;
2211 signed char * pDirs = pMan->pPermDir + pGrp->iStart;
2212 assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars));
2213 }
2214#endif
2215}
2216
2217static int Abc_TgNextPermutation(Abc_TgMan_t * pMan)
2218{
2219 int i, j, nGvars;
2220 TiedGroup * pGrp;
2221 char * pVars;
2222 signed char * pDirs;
2223 for (i = 0; i < pMan->nGroups; i++)
2224 {
2225 pGrp = pMan->pGroup + i;
2226 nGvars = pGrp->nGVars;
2227 if (nGvars == 1) continue;
2228 pVars = pMan->pPerm + pGrp->iStart;
2229 pDirs = pMan->pPermDir + pGrp->iStart;
2230 j = Abc_NextPermSwapC(pVars, pDirs, nGvars);
2231 if (j >= 0)
2232 {
2233 Abc_TgSwapAdjacentSymGroups(pMan, j + pGrp->iStart);
2234 return 1;
2235 }
2236 Abc_TgSwapAdjacentSymGroups(pMan, pGrp->iStart);
2237 assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars));
2238 }
2239 return 0;
2240}
2241
2242static inline unsigned grayCode(unsigned a) { return a ^ (a >> 1); }
2243
2244static int grayFlip(unsigned a)
2245{
2246 int i;
2247 for (i = 0, a++; ; i++)
2248 if (a & (1 << i)) return i;
2249 }
2250
2251static inline void Abc_TgSaveBest(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest)
2252{
2253 if (Abc_TtCompareRev(pBest->pTruth, pMan->pTruth, Abc_TtWordNum(pMan->nVars)) == 1)
2254 Abc_TgManCopy(pBest, pBest->pTruth, pMan);
2255}
2256
2257static void Abc_TgPhaseEnumeration(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest)
2258{
2259 char pFGrps[16];
2260 int i, j, n = pMan->pGroup->nGVars;
2261
2262 Abc_TgSaveBest(pMan, pBest);
2263 if (pMan->fPhased) return;
2264
2265 // sort by symPhase
2266 for (i = 0; i < n; i++)
2267 {
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];
2271 pFGrps[j] = iv;
2272 }
2273
2274 for (i = 0; i < (1 << n) - 1; i++)
2275 {
2276 Abc_TgFlipSymGroupByVar(pMan, pFGrps[grayFlip(i)]);
2277 Abc_TgSaveBest(pMan, pBest);
2278 }
2279}
2280
2292static void Abc_TgCalcScc(Abc_TgMan_t * pMan, int * pOut, int fSort)
2293{
2294 int i, j, k;
2295 TiedGroup * pGrp;
2296
2297 Abc_TtSccInCofs(pMan->pTruth, pMan->nVars, pOut);
2298
2299 for (i = j = 0; j < pMan->nGVars; j++)
2300 {
2301 pOut[j] = pOut[i];
2302 for (k = pMan->pPerm[j]; k >= 0; k = pMan->symLink[k])
2303 {
2304 i++;
2305 assert(pMan->symLink[k] < 0 || pOut[j] == pOut[i]);
2306 }
2307 }
2308 if (!fSort) return;
2309
2310 for (pGrp = pMan->pGroup; pGrp < pMan->pGroup + pMan->nGroups; pGrp++)
2311 {
2312 int vb = pGrp->iStart, ve = vb + pGrp->nGVars;
2313 for (i = vb + 1; i < ve; i++)
2314 {
2315 int a = pOut[i];
2316 for (j = i; j > vb && pOut[j - 1] > a; j--)
2317 pOut[j] = pOut[j - 1];
2318 pOut[j] = a;
2319 }
2320 }
2321}
2322
2323static void Abc_TgSplitGroupsByScc(Abc_TgMan_t * pMan)
2324{
2325 int pScc[16];
2326 char pPermT[16];
2327 TiedGroup * pGrp;
2328
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);
2332
2333 Abc_TgExpendSymmetry(pMan, pPermT);
2334 Abc_TgImplementPerm(pMan, pPermT);
2335 assert(Abc_TgCannonVerify(pMan));
2336}
2337
2338static int Abc_TgCompareCoef(int * pIn1, int * pIn2, int n)
2339{
2340 int i;
2341 for (i = 0; i < n; i++)
2342 if (pIn1[i] != pIn2[i])
2343 return (pIn1[i] < pIn2[i]) ? -1 : 1;
2344 return 0;
2345}
2346
2347// log2(n!)*100
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)
2350{
2351 int i, j, k, cost = 0;
2352
2353 for (i = k = 0; i < pMan->nGroups; i++)
2354 {
2355 int n = pMan->pGroup[i].nGVars;
2356 int d = 1;
2357 for (j = 1, k++; j < n; j++, k++)
2358 if (pScc[k] == pScc[k - 1]) d++;
2359 else {
2360 cost += log2fn[d];
2361 d = 1;
2362 }
2363 cost += log2fn[d];
2364 }
2365 return cost;
2366}
2367
2368static void Abc_TgPermEnumerationScc(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest)
2369{
2370 static word pCopy[1024];
2371 Abc_TgMan_t tgManCopy;
2372 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2373 if (pMan->nAlgorithm > 1)
2374 Abc_TgSplitGroupsByScc(&tgManCopy);
2375 Abc_TgFirstPermutation(&tgManCopy);
2376 do {
2377 Abc_TgSaveBest(&tgManCopy, pBest);
2378 } while (Abc_TgNextPermutation(&tgManCopy));
2379}
2380
2381static void Abc_TgReorderFGrps(Abc_TgMan_t * pMan)
2382{
2383 char * pFGrps = pMan->pFGrps;
2384 int i, j, n = pMan->fPhased ? 0 : pMan->pGroup->nGVars;
2385
2386 // sort by symPhase
2387 for (i = 0; i < n; i++)
2388 {
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];
2392 pFGrps[j] = iv;
2393 }
2394}
2395
2396static int ilog2(int n)
2397{
2398 int i;
2399 for (i = 0; n /= 2; i++)
2400 ;
2401 return i;
2402}
2403
2407
2408static Abc_SccCost_t Abc_TgRecordPhase(Abc_TgMan_t * pMan, int mode)
2409{
2410 Vec_Int_t * vPhase = pMan->vPhase;
2411 int i, j, n = pMan->pGroup->nGVars;
2412 int nStart = mode == 0 ? 1 : 0;
2413 int nCoefs = pMan->nGVars + 2 - nStart;
2414 int pScc[18], pMinScc[18];
2415 Abc_SccCost_t ret;
2416
2417 if (pMan->fPhased)
2418 {
2419 ret.cNeg = 0;
2420 ret.cPhase = 0;
2421 Abc_TgCalcScc(pMan, pScc + 2, 1);
2422 ret.cPerm = Abc_TgPermCostScc(pMan, pScc + 2);
2423 return ret;
2424 }
2425
2426 Abc_TgReorderFGrps(pMan);
2427 pMinScc[1] = Abc_TtScc(pMan->pTruth, pMan->nVars);
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++)
2432 {
2433 Abc_TgFlipSymGroupByVar(pMan, pMan->pFGrps[j]);
2434 pScc[1] = Abc_TtScc(pMan->pTruth, pMan->nVars);
2435 if (mode == 0 && pScc[1] > pMinScc[1]) continue;
2436 Abc_TgCalcScc(pMan, pScc + 2, 1);
2437 if (mode > 0)
2438 pScc[0] = Abc_TgPermCostScc(pMan, pScc + 2);
2439 if (Abc_TgCompareCoef(pScc + nStart, pMinScc + nStart, nCoefs) < 0)
2440 {
2441 memcpy(pMinScc + nStart, pScc + nStart, nCoefs * sizeof(int));
2442 Vec_IntClear(vPhase);
2443 }
2444 if (Abc_TgCompareCoef(pScc + nStart, pMinScc + nStart, nCoefs) == 0)
2445 Vec_IntPush(vPhase, grayCode(i+1));
2446 }
2447 Abc_TgFlipSymGroupByVar(pMan, pMan->pFGrps[n - 1]);
2448
2449 ret.cNeg = n;
2450 ret.cPhase = ilog2(Vec_IntSize(vPhase));
2451 ret.cPerm = Abc_TgPermCostScc(pMan, pMinScc + 2);
2452 return ret;
2453}
2454
2455static int Abc_TgRecordPhase1(Abc_TgMan_t * pMan) // for AdjSE
2456{
2457 Vec_Int_t * vPhase = pMan->vPhase;
2458 int i, j, n = pMan->pGroup->nGVars;
2459 //int nCoefs = pMan->nGVars + 2;
2460 int nScc, nMinScc;
2461
2462 assert (Vec_IntSize(vPhase) == 0);
2463 if (pMan->fPhased) return 0;
2464
2465 Abc_TgReorderFGrps(pMan);
2466 nMinScc = Abc_TtScc(pMan->pTruth, pMan->nVars);
2467 Vec_IntPush(vPhase, 0);
2468 for (i = 0; (j = grayFlip(i)) < n; i++)
2469 {
2470 Abc_TgFlipSymGroupByVar(pMan, pMan->pFGrps[j]);
2471 nScc = Abc_TtScc(pMan->pTruth, pMan->nVars);
2472 if (nScc > nMinScc) continue;
2473 if (nScc < nMinScc)
2474 {
2475 nMinScc = nScc;
2476 Vec_IntClear(vPhase);
2477 }
2478 Vec_IntPush(vPhase, grayCode(i + 1));
2479 }
2480
2481 Abc_TgFlipSymGroupByVar(pMan, pMan->pFGrps[n - 1]);
2482 return ilog2(Vec_IntSize(vPhase));
2483}
2484
2485static void Abc_TgPhaseEnumerationScc(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest)
2486{
2487 Vec_Int_t * vPhase = pMan->vPhase;
2488 int i, j, n = pMan->pGroup->nGVars;
2489 int ph0 = 0, ph, flp;
2490 static word pCopy[1024];
2491 Abc_TgMan_t tgManCopy;
2492
2493 if (pMan->fPhased)
2494 {
2495 Abc_TgPermEnumerationScc(pMan, pBest);
2496 return;
2497 }
2498
2499 Abc_TgManCopy(&tgManCopy, pCopy, pMan);
2500 Vec_IntForEachEntry(vPhase, ph, i)
2501 {
2502 flp = ph ^ ph0;
2503 for (j = 0; j < n; j++)
2504 if (flp & (1 << j))
2505 Abc_TgFlipSymGroupByVar(&tgManCopy, pMan->pFGrps[j]);
2506 ph0 = ph;
2507 Abc_TgPermEnumerationScc(&tgManCopy, pBest);
2508 }
2509}
2510
2511static void Abc_TgFullEnumeration(Abc_TgMan_t * pWork, Abc_TgMan_t * pBest)
2512{
2513 if (pWork->nAlgorithm > 0)
2514 {
2515 Abc_TtFill(pBest->pTruth, Abc_TtWordNum(pBest->nVars));
2516 Abc_TgPhaseEnumerationScc(pWork, pBest);
2517 }
2518 else
2519 {
2520 Abc_TgFirstPermutation(pWork);
2521 do Abc_TgPhaseEnumeration(pWork, pBest);
2522 while (Abc_TgNextPermutation(pWork));
2523 }
2524 pBest->uPhase |= 1 << 30;
2525}
2526
2527// runtime cost for Abc_TgRecordPhase (mode = 1)
2528static inline double Abc_SccPhaseCost(Abc_TgMan_t * pMan)
2529{
2530 return pMan->nVars * 0.997 + pMan->nGVars * 1.043 - 15.9;
2531}
2532
2533// runtime cost for Abc_TgFullEnumeration
2534static inline double Abc_SccEnumCost(Abc_TgMan_t * pMan, Abc_SccCost_t c)
2535{
2536 switch (pMan->nAlgorithm)
2537 {
2538 case 0: return pMan->nVars + c.cPhase * 1.09 + c.cPerm * 0.01144;
2539 case 1: return pMan->nVars + c.cPhase * 0.855 + c.cPerm * 0.00797;
2540 case 2: return pMan->nVars * 0.94 + c.cPhase * 0.885 + c.cPerm * 0.00855 - 20.59;
2541 }
2542 return 0;
2543}
2544
2545static int Abc_TgEnumerationCost(Abc_TgMan_t * pMan)
2546{
2547 int i;
2548 Abc_SccCost_t c = { 0,0,0 };
2549 if (pMan->nGroups == 0) return 0;
2550
2551 for (i = 0; i < pMan->nGroups; i++)
2552 c.cPerm += log2fn[(int)pMan->pGroup[i].nGVars];
2553
2554 c.cPhase = pMan->fPhased ? 0
2555 : pMan->nAlgorithm == 0 ? pMan->pGroup->nGVars
2556 : Abc_TgRecordPhase1(pMan);
2557
2558 // coefficients computed by linear regression
2559 return Abc_SccEnumCost(pMan, c) + 0.5;
2560}
2561
2573unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres)
2574{
2575 int nWords = Abc_TtWordNum(nVars);
2576 unsigned fExac = 0, fHash = 1 << 29;
2577 static word pCopy[1024];
2578 Abc_TgMan_t tgMan, tgManCopy;
2579 int iCost;
2580 const int MaxCost = 84; // maximun posible cost for function with 16 inputs
2581 const int nAlg = iThres >= 1000 ? 1 : 0;
2582 const int fHigh = (iThres % 1000) >= 100, nEnumThres = iThres % 100;
2583
2584 // handle constant
2585 if ( nVars == 0 ) {
2586 Abc_TtClear( pTruth, nWords );
2587 return 0;
2588 }
2589
2590 Abc_TtVerifySmallTruth(pTruth, nVars);
2591#ifdef CANON_VERIFY
2592 Abc_TtCopy(gpVerCopy, pTruth, nWords, 0);
2593#endif
2594
2595 assert(nVars <= 16);
2596 assert(!(nAlg && p == NULL));
2597 if (p && Abc_TtHieRetrieveOrInsert(p, -5, pTruth, pTruth) > 0) return fHash;
2598 Abc_TgInitMan(&tgMan, pTruth, nVars, nAlg, p ? p->vPhase : NULL);
2599 Abc_TgCreateGroups(&tgMan);
2600 if (p && Abc_TtHieRetrieveOrInsert(p, -4, pTruth, pTruth) > 0) return fHash;
2601 Abc_TgPurgeSymmetry(&tgMan, fHigh);
2602
2603 Abc_TgExpendSymmetry(&tgMan, pCanonPerm);
2604 Abc_TgImplementPerm(&tgMan, pCanonPerm);
2605 assert(Abc_TgCannonVerify(&tgMan));
2606
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);
2612 }
2613 else
2614 Abc_TgSimpleEnumeration(&tgMan);
2615 }
2616 else {
2617 if (nEnumThres > MaxCost || iCost < nEnumThres) fExac = 1 << 30;
2618 if (Abc_TtHieRetrieveOrInsert(p, -3, pTruth, pTruth) > 0) return fHash + fExac;
2619 Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
2620 Abc_TgSimpleEnumeration(&tgMan);
2621 if (Abc_TtHieRetrieveOrInsert(p, -2, pTruth, pTruth) > 0) return fHash + fExac;
2622 if (fExac) {
2623 Abc_TgManCopy(&tgMan, pTruth, &tgManCopy);
2624 Abc_TgFullEnumeration(&tgManCopy, &tgMan);
2625 }
2626 Abc_TtHieRetrieveOrInsert(p, -1, pTruth, pTruth);
2627 }
2628 memcpy(pCanonPerm, tgMan.pPermT, sizeof(char) * nVars);
2629
2630#ifdef CANON_VERIFY
2631 if (!Abc_TgCannonVerify(&tgMan))
2632 printf("Canonical form verification failed!\n");
2633#endif
2634 return tgMan.uPhase;
2635}
2636
2637unsigned Abc_TtCanonicizeCA(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fCA)
2638{
2639 int nWords = Abc_TtWordNum(nVars);
2640 unsigned fHard = 0, fHash = 1 << 29;
2641 static word pCopy[1024];
2642 Abc_TgMan_t tgMan, tgManCopy;
2643 Abc_SccCost_t sc;
2644
2645 // handle constant
2646 if (nVars == 0) {
2647 Abc_TtClear(pTruth, nWords);
2648 return 0;
2649 }
2650
2651 Abc_TtVerifySmallTruth(pTruth, nVars);
2652#ifdef CANON_VERIFY
2653 Abc_TtCopy(gpVerCopy, pTruth, nWords, 0);
2654#endif
2655
2656 assert(nVars <= 16);
2657 assert(p != NULL);
2658 if (Abc_TtHieRetrieveOrInsert(p, -5, pTruth, pTruth) > 0) return fHash;
2659 Abc_TgInitMan(&tgMan, pTruth, nVars, 2, p->vPhase);
2660
2661 Abc_TgCreateGroups(&tgMan);
2662 if (p && Abc_TtHieRetrieveOrInsert(p, -4, pTruth, pTruth) > 0) return fHash;
2663 Abc_TgPurgeSymmetry(&tgMan, 1);
2664
2665 Abc_TgExpendSymmetry(&tgMan, pCanonPerm);
2666 Abc_TgImplementPerm(&tgMan, pCanonPerm);
2667 assert(Abc_TgCannonVerify(&tgMan));
2668
2669 if (Abc_TtHieRetrieveOrInsert(p, -3, pTruth, pTruth) > 0) return fHash;
2670 Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
2671 Abc_TgSimpleEnumeration(&tgMan);
2672 if (Abc_TtHieRetrieveOrInsert(p, -2, pTruth, pTruth) > 0) return fHash;
2673 Abc_TgManCopy(&tgMan, pTruth, &tgManCopy);
2674 Abc_TtFill(pTruth, nWords);
2675
2676 assert(Abc_TgCannonVerify(&tgManCopy));
2677 sc = Abc_TgRecordPhase(&tgManCopy, 0);
2678 if (fCA && Abc_SccEnumCost(&tgManCopy, sc) > Abc_SccPhaseCost(&tgManCopy))
2679 {
2680 Abc_TgResetGroup(&tgManCopy);
2681 sc = Abc_TgRecordPhase(&tgManCopy, 1);
2682 fHard = 1 << 28;
2683 }
2684 Abc_TgFullEnumeration(&tgManCopy, &tgMan);
2685 Abc_TtHieRetrieveOrInsert(p, -1, pTruth, pTruth);
2686 memcpy(pCanonPerm, tgMan.pPermT, sizeof(char) * nVars);
2687
2688#ifdef CANON_VERIFY
2689 if (!Abc_TgCannonVerify(&tgMan))
2690 printf("Canonical form verification failed!\n");
2691#endif
2692 return tgMan.uPhase | fHard;
2693}
2694
2695
2699
2700
2702
int nWords
Definition abcNpn.c:127
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_CONST(number)
PARAMETERS ///.
Definition abc_global.h:240
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
void freePermInfoPtr(permInfo *x)
permInfo * setPermInfoPtr(int var)
int Abc_TtCofactorPermConfig(word *pTruth, int i, int nWords, int fSwapOnly, int fNaive)
Definition dauCanon.c:880
int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t *p, int level, word *pTruth, word *pResult)
Definition dauCanon.c:1286
int Abc_Tt6CofactorPermNaive(word *pTruth, int i, int fSwapOnly)
Definition dauCanon.c:740
int Abc_TtCountOnesInCofsFast_rec(word *pTruth, int iVar, int nWords, int *pStore)
Definition dauCanon.c:535
int Abc_TtCountOnesInCofsSimple(word *pTruth, int nVars, int *pStore)
Definition dauCanon.c:370
int Abc_TtCountOnesInCofsFast6_rec(word Truth, int iVar, int nBytes, int *pStore)
Definition dauCanon.c:499
int Abc_TtCofactorPerm(word *pTruth, int i, int nWords, int fSwapOnly, char *pCanonPerm, unsigned *puCanonPhase, int fNaive)
Definition dauCanon.c:978
unsigned Abc_TtCanonicizePhase(word *pTruth, int nVars)
Definition dauCanon.c:1187
unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t *p, word *pTruthInit, int nVars, char *pCanonPerm, int fExact)
Definition dauCanon.c:1318
struct TiedGroup_ TiedGroup
struct Abc_SccCost_t_ Abc_SccCost_t
int Abc_TtCountOnesInCofsFast(word *pTruth, int nVars, int *pStore)
Definition dauCanon.c:565
void Abc_TtNormalizeSmallTruth(word *pTruth, int nVars)
Definition dauCanon.c:300
unsigned Abc_TtCanonicizePerm(word *pTruth, int nVars, char *pCanonPerm)
Definition dauCanon.c:1085
int Abc_TgExpendSymmetry(Abc_TgMan_t *pMan, char *pDest)
Definition dauCanon.c:1980
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int iThres)
Definition dauCanon.c:2573
struct Abc_TgMan_t_ Abc_TgMan_t
void Abc_TtCofactorTest10(word *pTruth, int nVars, int N)
Definition dauCanon.c:710
int Abc_TtScc(word *pTruth, int nVars)
Definition dauCanon.c:393
Abc_TtHieMan_t * Abc_TtHieManStart(int nVars, int nLevels)
Definition dauCanon.c:1255
void Abc_TtHieManStop(Abc_TtHieMan_t *p)
Definition dauCanon.c:1273
#define TT_MAX_LEVELS
Definition dauCanon.c:1243
word gpVerCopy[1024]
Definition dauCanon.c:1550
unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int flag)
Definition dauCanon.c:1530
unsigned Abc_TtCanonicizeCA(Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int fCA)
Definition dauCanon.c:2637
unsigned Abc_TtCanonicize(word *pTruth, int nVars, char *pCanonPerm)
FUNCTION DECLARATIONS ///.
Definition dauCanon.c:1036
int Abc_TtCofactorPermNaive(word *pTruth, int i, int nWords, int fSwapOnly)
Definition dauCanon.c:800
struct Abc_TtHieMan_t_ Abc_TtHieMan_t
Definition dau.h:62
unsigned(* TtCanonicizeFunc)(Abc_TtHieMan_t *p, word *pTruth, int nVars, char *pCanonPerm, int flag)
Definition dau.h:63
int Abc_TtCountOnesInCofsQuick(word *pTruth, int nVars, int *pStore)
Definition dauCount.c:376
Cube * p
Definition exorList.c:222
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
void simpleMinimalGroups(word *x, word *pAux, word *minimal, int *pGroups, int nGroups, permInfo **pis, int nVars, int fFlipOutput, int fFlipInput)
unsigned long long size
Definition giaNewBdd.h:39
char pPerm[16]
Definition dauCanon.c:1480
signed char symLink[17]
Definition dauCanon.c:1487
char pPermT[16]
Definition dauCanon.c:1481
word * pTruth
Definition dauCanon.c:1474
char pFGrps[16]
Definition dauCanon.c:1490
char symPhase[16]
Definition dauCanon.c:1486
char pPermTRev[16]
Definition dauCanon.c:1482
TiedGroup pGroup[16]
Definition dauCanon.c:1484
unsigned uPhase
Definition dauCanon.c:1478
Vec_Int_t * vPhase
Definition dauCanon.c:1491
signed char pPermDir[16]
Definition dauCanon.c:1483
Vec_Mem_t * vTtMem[TT_MAX_LEVELS]
Definition dauCanon.c:1248
Vec_Int_t * vRepres[TT_MAX_LEVELS]
Definition dauCanon.c:1249
int vTruthId[TT_MAX_LEVELS]
Definition dauCanon.c:1250
Vec_Int_t * vPhase
Definition dauCanon.c:1252
char iStart
Definition dauCanon.c:1468
char nGVars
Definition dauCanon.c:1469
Definition mode.h:11
typedefABC_NAMESPACE_IMPL_START struct Vec_Mem_t_ Vec_Mem_t
DECLARATIONS ///.
Definition utilMem.c:35
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * memset()
char * memmove()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54