ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
plaFxch.c
Go to the documentation of this file.
1
20
21#include "pla.h"
22#include "misc/vec/vecHash.h"
23#include "misc/vec/vecQue.h"
24
26
30
31typedef struct Fxch_Obj_t_ Fxch_Obj_t;
33{
34 unsigned Table : 30;
35 unsigned MarkN : 1;
36 unsigned MarkP : 1;
37 int Next;
38 int Prev;
39 int Cube;
40};
41
42typedef struct Fxch_Man_t_ Fxch_Man_t;
44{
45 // user's data
46 Vec_Wec_t vCubes; // cube -> lit
47 // internal data
48 Vec_Wec_t vLits; // lit -> cube
49 Vec_Int_t vRands; // random numbers for each literal
50 Vec_Int_t vCubeLinks; // first link for each cube
51 Fxch_Obj_t * pBins; // hash table (lits -> cube + lit)
52 Hash_IntMan_t * vHash; // divisor hash table
53 Vec_Que_t * vPrio; // priority queue for divisors by weight
54 Vec_Flt_t vWeights; // divisor weights
55 Vec_Wec_t vPairs; // cube pairs for each div
56 Vec_Wrd_t vDivs; // extracted divisors
57 // temporary data
58 Vec_Int_t vCubesS; // cube pairs for single
59 Vec_Int_t vCubesD; // cube pairs for double
60 Vec_Int_t vCube1; // first cube
61 Vec_Int_t vCube2; // second cube
62 // statistics
63 abctime timeStart; // starting time
64 int SizeMask; // hash table mask
65 int nVars; // original problem variables
66 int nLits; // the number of SOP literals
67 int nCompls; // the number of complements
68 int nPairsS; // number of lit pairs
69 int nPairsD; // number of cube pairs
70};
71
72#define Fxch_ManForEachCubeVec( vVec, vCubes, vCube, i ) \
73 for ( i = 0; (i < Vec_IntSize(vVec)) && ((vCube) = Vec_WecEntry(vCubes, Vec_IntEntry(vVec, i))); i++ )
74
75static inline Vec_Int_t * Fxch_ManCube( Fxch_Man_t * p, int hCube ) { return Vec_WecEntry(&p->vCubes, Pla_CubeNum(hCube)); }
76
77
81
93void Fxch_ManWriteBlif( char * pFileName, Vec_Wec_t * vCubes, Vec_Wrd_t * vDivs )
94{
95 // find the number of original variables
96 int nVarsInit = Vec_WrdCountZero(vDivs);
97 FILE * pFile = fopen( pFileName, "wb" );
98 if ( pFile == NULL )
99 printf( "Cannot open file \"%s\" for writing.\n", pFileName );
100 else
101 {
102 //char * pLits = "-01?";
103 Vec_Str_t * vStr;
104 Vec_Int_t * vCube;
105 int i, k, Lit;
106 word Div;
107 // comment
108 fprintf( pFile, "# BLIF file written via PLA package in ABC on " );
109 fprintf( pFile, "%s", Extra_TimeStamp() );
110 fprintf( pFile, "\n\n" );
111 // header
112 fprintf( pFile, ".model %s\n", pFileName );
113 fprintf( pFile, ".inputs" );
114 for ( i = 0; i < nVarsInit; i++ )
115 fprintf( pFile, " i%d", i );
116 fprintf( pFile, "\n" );
117 fprintf( pFile, ".outputs o" );
118 fprintf( pFile, "\n" );
119 // SOP header
120 fprintf( pFile, ".names" );
121 for ( i = 0; i < Vec_WrdSize(vDivs); i++ )
122 fprintf( pFile, " i%d", i );
123 fprintf( pFile, " o\n" );
124 // SOP cubes
125 vStr = Vec_StrStart( Vec_WrdSize(vDivs) + 1 );
126 Vec_WecForEachLevel( vCubes, vCube, i )
127 {
128 if ( !Vec_IntSize(vCube) )
129 continue;
130 for ( k = 0; k < Vec_WrdSize(vDivs); k++ )
131 Vec_StrWriteEntry( vStr, k, '-' );
132 Vec_IntForEachEntry( vCube, Lit, k )
133 Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (char)(Abc_LitIsCompl(Lit) ? '0' : '1') );
134 fprintf( pFile, "%s 1\n", Vec_StrArray(vStr) );
135 }
136 Vec_StrFree( vStr );
137 // divisors
138 Vec_WrdForEachEntryStart( vDivs, Div, i, nVarsInit )
139 {
140 int pLits[2] = { (int)(Div & 0xFFFFFFFF), (int)(Div >> 32) };
141 fprintf( pFile, ".names" );
142 fprintf( pFile, " i%d", Abc_Lit2Var(pLits[0]) );
143 fprintf( pFile, " i%d", Abc_Lit2Var(pLits[1]) );
144 fprintf( pFile, " i%d\n", i );
145 fprintf( pFile, "%d%d 1\n", !Abc_LitIsCompl(pLits[0]), !Abc_LitIsCompl(pLits[1]) );
146 }
147 fprintf( pFile, ".end\n\n" );
148 fclose( pFile );
149 printf( "Written BLIF file \"%s\".\n", pFileName );
150 }
151}
152
165{
166 Vec_Int_t * vCube; int i, LogSize;
168 p->vCubes = *vCubes;
169 p->vLits = *vLits;
170 p->nVars = Vec_WecSize(vLits)/2;
171 p->nLits = 0;
172 // random numbers
173 Gia_ManRandom( 1 );
174 Vec_IntGrow( &p->vRands, 2*p->nVars );
175 for ( i = 0; i < 2*p->nVars; i++ )
176 Vec_IntPush( &p->vRands, Gia_ManRandom(0) & 0x3FFFFFF ); // assert( LogSize <= 26 );
177 // create cube links
178 Vec_IntGrow( &p->vCubeLinks, Vec_WecSize(&p->vCubes) );
179 Vec_WecForEachLevel( vCubes, vCube, i )
180 {
181 Vec_IntPush( &p->vCubeLinks, p->nLits+1 );
182 p->nLits += Vec_IntSize(vCube);
183 }
184 assert( Vec_IntSize(&p->vCubeLinks) == Vec_WecSize(&p->vCubes) );
185 // create table
186 LogSize = Abc_Base2Log( p->nLits+1 );
187 assert( LogSize <= 26 );
188 p->SizeMask = (1 << LogSize) - 1;
189 p->pBins = ABC_CALLOC( Fxch_Obj_t, p->SizeMask + 1 );
190 assert( p->nLits+1 < p->SizeMask+1 );
191 // divisor weights and cube pairs
192 Vec_FltGrow( &p->vWeights, 1000 );
193 Vec_FltPush( &p->vWeights, -1 );
194 Vec_WecGrow( &p->vPairs, 1000 );
195 Vec_WecPushLevel( &p->vPairs );
196 // prepare divisors
197 Vec_WrdGrow( &p->vDivs, p->nVars + 1000 );
198 Vec_WrdFill( &p->vDivs, p->nVars, 0 );
199 return p;
200}
202{
203 Vec_WecErase( &p->vCubes );
204 Vec_WecErase( &p->vLits );
205 Vec_IntErase( &p->vRands );
206 Vec_IntErase( &p->vCubeLinks );
207 Hash_IntManStop( p->vHash );
208 Vec_QueFree( p->vPrio );
209 Vec_FltErase( &p->vWeights );
210 Vec_WecErase( &p->vPairs );
211 Vec_WrdErase( &p->vDivs );
212 Vec_IntErase( &p->vCubesS );
213 Vec_IntErase( &p->vCubesD );
214 Vec_IntErase( &p->vCube1 );
215 Vec_IntErase( &p->vCube2 );
216 ABC_FREE( p->pBins );
217 ABC_FREE( p );
218}
219
231static inline int Fxch_TabCompare( Fxch_Man_t * p, int hCube1, int hCube2 )
232{
233 Vec_Int_t * vCube1 = Fxch_ManCube( p, hCube1 );
234 Vec_Int_t * vCube2 = Fxch_ManCube( p, hCube2 );
235 if ( !Vec_IntSize(vCube1) || !Vec_IntSize(vCube2) || Vec_IntSize(vCube1) != Vec_IntSize(vCube2) )
236 return 0;
237 Vec_IntClear( &p->vCube1 );
238 Vec_IntClear( &p->vCube2 );
239 Vec_IntAppendSkip( &p->vCube1, vCube1, Pla_CubeLit(hCube1) );
240 Vec_IntAppendSkip( &p->vCube2, vCube2, Pla_CubeLit(hCube2) );
241 return Vec_IntEqual( &p->vCube1, &p->vCube2 );
242}
243static inline void Fxch_CompressCubes( Fxch_Man_t * p, Vec_Int_t * vLit2Cube )
244{
245 int i, hCube, k = 0;
246 Vec_IntForEachEntry( vLit2Cube, hCube, i )
247 if ( Vec_IntSize(Vec_WecEntry(&p->vCubes, hCube)) > 0 )
248 Vec_IntWriteEntry( vLit2Cube, k++, hCube );
249 Vec_IntShrink( vLit2Cube, k );
250}
251static inline int Fxch_CollectSingles( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vArr )
252{
253 int * pBeg1 = vArr1->pArray;
254 int * pBeg2 = vArr2->pArray;
255 int * pEnd1 = vArr1->pArray + vArr1->nSize;
256 int * pEnd2 = vArr2->pArray + vArr2->nSize;
257 int * pBeg1New = vArr1->pArray;
258 int * pBeg2New = vArr2->pArray;
259 Vec_IntClear( vArr );
260 while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
261 {
262 if ( Pla_CubeNum(*pBeg1) == Pla_CubeNum(*pBeg2) )
263 Vec_IntPushTwo( vArr, *pBeg1, *pBeg2 ), pBeg1++, pBeg2++;
264 else if ( *pBeg1 < *pBeg2 )
265 *pBeg1New++ = *pBeg1++;
266 else
267 *pBeg2New++ = *pBeg2++;
268 }
269 while ( pBeg1 < pEnd1 )
270 *pBeg1New++ = *pBeg1++;
271 while ( pBeg2 < pEnd2 )
272 *pBeg2New++ = *pBeg2++;
273 Vec_IntShrink( vArr1, pBeg1New - vArr1->pArray );
274 Vec_IntShrink( vArr2, pBeg2New - vArr2->pArray );
275 return Vec_IntSize(vArr);
276}
277static inline void Fxch_CollectDoubles( Fxch_Man_t * p, Vec_Int_t * vPairs, Vec_Int_t * vRes, int Lit0, int Lit1 )
278{
279 int i, hCube1, hCube2;
280 Vec_IntClear( vRes );
281 Vec_IntForEachEntryDouble( vPairs, hCube1, hCube2, i )
282 if ( Fxch_TabCompare(p, hCube1, hCube2) &&
283 Vec_IntEntry(Fxch_ManCube(p, hCube1), Pla_CubeLit(hCube1)) == Lit0 &&
284 Vec_IntEntry(Fxch_ManCube(p, hCube2), Pla_CubeLit(hCube2)) == Lit1 )
285 Vec_IntPushTwo( vRes, hCube1, hCube2 );
286 Vec_IntClear( vPairs );
287 // order pairs in the increasing order of the first cube
288 //Vec_IntSortPairs( vRes );
289}
290static inline void Fxch_CompressLiterals2( Vec_Int_t * p, int iInd1, int iInd2 )
291{
292 int i, Lit, k = 0;
293 assert( iInd1 >= 0 && iInd1 < Vec_IntSize(p) );
294 if ( iInd2 != -1 )
295 assert( iInd1 >= 0 && iInd1 < Vec_IntSize(p) );
296 Vec_IntForEachEntry( p, Lit, i )
297 if ( i != iInd1 && i != iInd2 )
298 Vec_IntWriteEntry( p, k++, Lit );
299 Vec_IntShrink( p, k );
300}
301static inline void Fxch_CompressLiterals( Vec_Int_t * p, int iLit1, int iLit2 )
302{
303 int i, Lit, k = 0;
304 Vec_IntForEachEntry( p, Lit, i )
305 if ( Lit != iLit1 && Lit != iLit2 )
306 Vec_IntWriteEntry( p, k++, Lit );
307 assert( Vec_IntSize(p) == k + 2 );
308 Vec_IntShrink( p, k );
309}
310static inline void Fxch_FilterCubes( Fxch_Man_t * p, Vec_Int_t * vCubesS, int Lit0, int Lit1 )
311{
312 Vec_Int_t * vCube;
313 int i, k, Lit, iCube, n = 0;
314 int fFound0, fFound1;
315 Vec_IntForEachEntry( vCubesS, iCube, i )
316 {
317 vCube = Vec_WecEntry( &p->vCubes, iCube );
318 fFound0 = fFound1 = 0;
319 Vec_IntForEachEntry( vCube, Lit, k )
320 {
321 if ( Lit == Lit0 )
322 fFound0 = 1;
323 else if ( Lit == Lit1 )
324 fFound1 = 1;
325 }
326 if ( fFound0 && fFound1 )
327 Vec_IntWriteEntry( vCubesS, n++, Pla_CubeHandle(iCube, 255) );
328 }
329 Vec_IntShrink( vCubesS, n );
330}
331
332
344int Fxch_DivisorAdd( Fxch_Man_t * p, int Lit0, int Lit1, int Weight )
345{
346 int iDiv;
347 assert( Lit0 != Lit1 );
348 if ( Lit0 < Lit1 )
349 iDiv = Hash_Int2ManInsert( p->vHash, Lit0, Lit1, 0 );
350 else
351 iDiv = Hash_Int2ManInsert( p->vHash, Lit1, Lit0, 0 );
352 if ( iDiv == Vec_FltSize(&p->vWeights) )
353 {
354 Vec_FltPush( &p->vWeights, -2 );
355 Vec_WecPushLevel( &p->vPairs );
356 assert( Vec_FltSize(&p->vWeights) == Vec_WecSize(&p->vPairs) );
357 }
358 Vec_FltAddToEntry( &p->vWeights, iDiv, Weight );
359 if ( p->vPrio )
360 {
361 if ( Vec_QueIsMember(p->vPrio, iDiv) )
362 Vec_QueUpdate( p->vPrio, iDiv );
363 else
364 Vec_QuePush( p->vPrio, iDiv );
365 //assert( iDiv < Vec_QueSize(p->vPrio) );
366 }
367 return iDiv;
368}
369void Fxch_DivisorRemove( Fxch_Man_t * p, int Lit0, int Lit1, int Weight )
370{
371 int iDiv;
372 assert( Lit0 != Lit1 );
373 if ( Lit0 < Lit1 )
374 iDiv = *Hash_Int2ManLookup( p->vHash, Lit0, Lit1 );
375 else
376 iDiv = *Hash_Int2ManLookup( p->vHash, Lit1, Lit0 );
377 assert( iDiv > 0 && iDiv < Vec_FltSize(&p->vWeights) );
378 Vec_FltAddToEntry( &p->vWeights, iDiv, -Weight );
379 if ( Vec_QueIsMember(p->vPrio, iDiv) )
380 Vec_QueUpdate( p->vPrio, iDiv );
381}
382
394static inline Fxch_Obj_t * Fxch_TabBin( Fxch_Man_t * p, int Value ) { return p->pBins + (Value & p->SizeMask); }
395static inline Fxch_Obj_t * Fxch_TabEntry( Fxch_Man_t * p, int i ) { return i ? p->pBins + i : NULL; }
396static inline int Fxch_TabEntryId( Fxch_Man_t * p, Fxch_Obj_t * pEnt ) { assert(pEnt > p->pBins); return pEnt - p->pBins; }
397
398static inline void Fxch_TabMarkPair( Fxch_Man_t * p, int i, int j )
399{
400 Fxch_Obj_t * pI = Fxch_TabEntry(p, i);
401 Fxch_Obj_t * pJ = Fxch_TabEntry(p, j);
402 assert( pI->Next == j );
403 assert( pJ->Prev == i );
404 assert( pI->MarkN == 0 );
405 assert( pI->MarkP == 0 );
406 assert( pJ->MarkN == 0 );
407 assert( pJ->MarkP == 0 );
408 pI->MarkN = 1;
409 pJ->MarkP = 1;
410}
411static inline void Fxch_TabUnmarkPair( Fxch_Man_t * p, int i, int j )
412{
413 Fxch_Obj_t * pI = Fxch_TabEntry(p, i);
414 Fxch_Obj_t * pJ = Fxch_TabEntry(p, j);
415 assert( pI->Next == j );
416 assert( pJ->Prev == i );
417 assert( pI->MarkN == 1 );
418 assert( pI->MarkP == 0 );
419 assert( pJ->MarkN == 0 );
420 assert( pJ->MarkP == 1 );
421 pI->MarkN = 0;
422 pJ->MarkP = 0;
423}
424static inline void Fxch_TabInsertLink( Fxch_Man_t * p, int i, int j, int fSkipCheck )
425{
426 Fxch_Obj_t * pI = Fxch_TabEntry(p, i);
427 Fxch_Obj_t * pN = Fxch_TabEntry(p, pI->Next);
428 Fxch_Obj_t * pJ = Fxch_TabEntry(p, j);
429 //assert( pJ->Cube != 0 );
430 assert( pN->Prev == i );
431 assert( fSkipCheck || pI->MarkN == 0 );
432 assert( fSkipCheck || pN->MarkP == 0 );
433 assert( fSkipCheck || pJ->MarkN == 0 );
434 assert( fSkipCheck || pJ->MarkP == 0 );
435 pJ->Next = pI->Next; pI->Next = j;
436 pJ->Prev = i; pN->Prev = j;
437}
438static inline void Fxch_TabExtractLink( Fxch_Man_t * p, int i, int j )
439{
440 Fxch_Obj_t * pI = Fxch_TabEntry(p, i);
441 Fxch_Obj_t * pJ = Fxch_TabEntry(p, j);
442 Fxch_Obj_t * pN = Fxch_TabEntry(p, pJ->Next);
443 //assert( pJ->Cube != 0 );
444 assert( pI->Next == j );
445 assert( pJ->Prev == i );
446 assert( pN->Prev == j );
447 assert( pI->MarkN == 0 );
448 assert( pJ->MarkP == 0 );
449 assert( pJ->MarkN == 0 );
450 assert( pN->MarkP == 0 );
451 pI->Next = pJ->Next; pJ->Next = 0;
452 pN->Prev = pJ->Prev; pJ->Prev = 0;
453}
454static inline void Fxch_TabInsert( Fxch_Man_t * p, int iLink, int Value, int hCube )
455{
456 int iEnt, iDiv, Lit0, Lit1, fStart = 1;
457 Fxch_Obj_t * pEnt;
458 Fxch_Obj_t * pBin = Fxch_TabBin( p, Value );
459 Fxch_Obj_t * pCell = Fxch_TabEntry( p, iLink );
460 assert( pCell->MarkN == 0 );
461 assert( pCell->MarkP == 0 );
462 assert( pCell->Cube == 0 );
463 pCell->Cube = hCube;
464 if ( pBin->Table == 0 )
465 {
466 pBin->Table = pCell->Next = pCell->Prev = iLink;
467 return;
468 }
469 // find equal cubes
470 for ( iEnt = pBin->Table; iEnt != (int)pBin->Table || fStart; iEnt = pEnt->Next, fStart = 0 )
471 {
472 pEnt = Fxch_TabBin( p, iEnt );
473 if ( pEnt->MarkN || pEnt->MarkP || !Fxch_TabCompare(p, pEnt->Cube, hCube) )
474 continue;
475 Fxch_TabInsertLink( p, iEnt, iLink, 0 );
476 Fxch_TabMarkPair( p, iEnt, iLink );
477 // get literals
478 Lit0 = Vec_IntEntry( Fxch_ManCube(p, hCube), Pla_CubeLit(hCube) );
479 Lit1 = Vec_IntEntry( Fxch_ManCube(p, pEnt->Cube), Pla_CubeLit(pEnt->Cube) );
480 // increment divisor weight
481 iDiv = Fxch_DivisorAdd( p, Abc_LitNot(Lit0), Abc_LitNot(Lit1), Vec_IntSize(Fxch_ManCube(p, hCube)) );
482 // add divisor pair
483 assert( iDiv < Vec_WecSize(&p->vPairs) );
484 if ( Lit0 < Lit1 )
485 {
486 Vec_WecPush( &p->vPairs, iDiv, hCube );
487 Vec_WecPush( &p->vPairs, iDiv, pEnt->Cube );
488 }
489 else
490 {
491 Vec_WecPush( &p->vPairs, iDiv, pEnt->Cube );
492 Vec_WecPush( &p->vPairs, iDiv, hCube );
493 }
494 p->nPairsD++;
495 return;
496 }
497 assert( iEnt == (int)pBin->Table );
498 pEnt = Fxch_TabBin( p, iEnt );
499 Fxch_TabInsertLink( p, pEnt->Prev, iLink, 1 );
500}
501static inline void Fxch_TabExtract( Fxch_Man_t * p, int iLink, int Value, int hCube )
502{
503 int Lit0, Lit1;
504 Fxch_Obj_t * pPair = NULL;
505 Fxch_Obj_t * pBin = Fxch_TabBin( p, Value );
506 Fxch_Obj_t * pLink = Fxch_TabEntry( p, iLink );
507 assert( pLink->Cube == hCube );
508 if ( pLink->MarkN )
509 {
510 pPair = Fxch_TabEntry( p, pLink->Next );
511 Fxch_TabUnmarkPair( p, iLink, pLink->Next );
512 }
513 else if ( pLink->MarkP )
514 {
515 pPair = Fxch_TabEntry( p, pLink->Prev );
516 Fxch_TabUnmarkPair( p, pLink->Prev, iLink );
517 }
518 if ( (int)pBin->Table == iLink )
519 pBin->Table = pLink->Next != iLink ? pLink->Next : 0;
520 if ( pLink->Next == iLink )
521 {
522 assert( pLink->Prev == iLink );
523 pLink->Next = pLink->Prev = 0;
524 }
525 else
526 Fxch_TabExtractLink( p, pLink->Prev, iLink );
527 pLink->Cube = 0;
528 if ( pPair == NULL )
529 return;
530 assert( Fxch_TabCompare(p, pPair->Cube, hCube) );
531 // get literals
532 Lit0 = Vec_IntEntry( Fxch_ManCube(p, hCube), Pla_CubeLit(hCube) );
533 Lit1 = Vec_IntEntry( Fxch_ManCube(p, pPair->Cube), Pla_CubeLit(pPair->Cube) );
534 // decrement divisor weight
535 Fxch_DivisorRemove( p, Abc_LitNot(Lit0), Abc_LitNot(Lit1), Vec_IntSize(Fxch_ManCube(p, hCube)) );
536 p->nPairsD--;
537}
538
550int Fxch_TabSingleDivisors( Fxch_Man_t * p, int iCube, int fAdd )
551{
552 Vec_Int_t * vCube = Vec_WecEntry( &p->vCubes, iCube );
553 int i, k, Lit, Lit2;
554 if ( Vec_IntSize(vCube) < 2 )
555 return 0;
556 Vec_IntForEachEntry( vCube, Lit, i )
557 Vec_IntForEachEntryStart( vCube, Lit2, k, i+1 )
558 {
559 assert( Lit < Lit2 );
560 if ( fAdd )
561 Fxch_DivisorAdd( p, Lit, Lit2, 1 ), p->nPairsS++;
562 else
563 Fxch_DivisorRemove( p, Lit, Lit2, 1 ), p->nPairsS--;
564 }
565 return Vec_IntSize(vCube) * (Vec_IntSize(vCube) - 1) / 2;
566}
567int Fxch_TabDoubleDivisors( Fxch_Man_t * p, int iCube, int fAdd )
568{
569 Vec_Int_t * vCube = Vec_WecEntry( &p->vCubes, iCube );
570 int iLinkFirst = Vec_IntEntry( &p->vCubeLinks, iCube );
571 int k, Lit, Value = 0;
572 Vec_IntForEachEntry( vCube, Lit, k )
573 Value += Vec_IntEntry(&p->vRands, Lit);
574 Vec_IntForEachEntry( vCube, Lit, k )
575 {
576 Value -= Vec_IntEntry(&p->vRands, Lit);
577 if ( fAdd )
578 Fxch_TabInsert( p, iLinkFirst + k, Value, Pla_CubeHandle(iCube, k) );
579 else
580 Fxch_TabExtract( p, iLinkFirst + k, Value, Pla_CubeHandle(iCube, k) );
581 Value += Vec_IntEntry(&p->vRands, Lit);
582 }
583 return 1;
584}
586{
587 float Weight; int i;
588 // alloc hash table
589 assert( p->vHash == NULL );
590 p->vHash = Hash_IntManStart( 1000 );
591 // create single-cube two-literal divisors
592 for ( i = 0; i < Vec_WecSize(&p->vCubes); i++ )
593 Fxch_TabSingleDivisors( p, i, 1 ); // add - no update
594 // create two-cube divisors
595 for ( i = 0; i < Vec_WecSize(&p->vCubes); i++ )
596 Fxch_TabDoubleDivisors( p, i, 1 ); // add - no update
597 // create queue with all divisors
598 p->vPrio = Vec_QueAlloc( Vec_FltSize(&p->vWeights) );
599 Vec_QueSetPriority( p->vPrio, Vec_FltArrayP(&p->vWeights) );
600 Vec_FltForEachEntry( &p->vWeights, Weight, i )
601 if ( Weight > 0.0 )
602 Vec_QuePush( p->vPrio, i );
603}
604
605
617void Fxch_ManUpdate( Fxch_Man_t * p, int iDiv )
618{
619 Vec_Int_t * vCube1, * vCube2, * vLitP, * vLitN;
620 //int nLitsNew = p->nLits - (int)Vec_FltEntry(&p->vWeights, iDiv);
621 int i, Lit0, Lit1, hCube1, hCube2, iVarNew;
622 //float Diff = Vec_FltEntry(&p->vWeights, iDiv) - (float)((int)Vec_FltEntry(&p->vWeights, iDiv));
623 //assert( Diff > 0.0 && Diff < 1.0 );
624
625 // get the divisor and select pivot variables
626 Vec_IntPush( &p->vRands, Gia_ManRandom(0) & 0x3FFFFFF );
627 Vec_IntPush( &p->vRands, Gia_ManRandom(0) & 0x3FFFFFF );
628 Lit0 = Hash_IntObjData0( p->vHash, iDiv );
629 Lit1 = Hash_IntObjData1( p->vHash, iDiv );
630 assert( Lit0 >= 0 && Lit1 >= 0 && Lit0 < Lit1 );
631 Vec_WrdPush( &p->vDivs, ((word)Lit1 << 32) | (word)Lit0 );
632
633 // if the input cover is not prime, it may happen that we are extracting divisor (x + !x)
634 // although it is not strictly correct, it seems to be fine to just skip such divisors
635// if ( Abc_Lit2Var(Lit0) == Abc_Lit2Var(Lit1) && Vec_IntSize(Hsh_VecReadEntry(p->vHash, iDiv)) == 2 )
636// return;
637
638 // collect single-cube-divisor cubes
639 vLitP = Vec_WecEntry(&p->vLits, Lit0);
640 vLitN = Vec_WecEntry(&p->vLits, Lit1);
641 Fxch_CompressCubes( p, vLitP );
642 Fxch_CompressCubes( p, vLitN );
643// Fxch_CollectSingles( vLitP, vLitN, &p->vCubesS );
644// assert( Vec_IntSize(&p->vCubesS) % 2 == 0 );
645 Vec_IntTwoRemoveCommon( vLitP, vLitN, &p->vCubesS );
646 Fxch_FilterCubes( p, &p->vCubesS, Lit0, Lit1 );
647
648 // collect double-cube-divisor cube pairs
649 Fxch_CollectDoubles( p, Vec_WecEntry(&p->vPairs, iDiv), &p->vCubesD, Abc_LitNot(Lit0), Abc_LitNot(Lit1) );
650 assert( Vec_IntSize(&p->vCubesD) % 2 == 0 );
651 Vec_IntUniqifyPairs( &p->vCubesD );
652 assert( Vec_IntSize(&p->vCubesD) % 2 == 0 );
653
654 // subtract cost of single-cube divisors
655// Vec_IntForEachEntryDouble( &p->vCubesS, hCube1, hCube2, i )
656 Vec_IntForEachEntry( &p->vCubesS, hCube1, i )
657 Fxch_TabSingleDivisors( p, Pla_CubeNum(hCube1), 0 ); // remove - update
658 Vec_IntForEachEntryDouble( &p->vCubesD, hCube1, hCube2, i )
659 Fxch_TabSingleDivisors( p, Pla_CubeNum(hCube1), 0 ), // remove - update
660 Fxch_TabSingleDivisors( p, Pla_CubeNum(hCube2), 0 ); // remove - update
661
662 // subtract cost of double-cube divisors
663// Vec_IntForEachEntryDouble( &p->vCubesS, hCube1, hCube2, i )
664 Vec_IntForEachEntry( &p->vCubesS, hCube1, i )
665 {
666 //printf( "%d ", Pla_CubeNum(hCube1) );
667 Fxch_TabDoubleDivisors( p, Pla_CubeNum(hCube1), 0 ); // remove - update
668 }
669 //printf( "\n" );
670
671 Vec_IntForEachEntryDouble( &p->vCubesD, hCube1, hCube2, i )
672 {
673 //printf( "%d ", Pla_CubeNum(hCube1) );
674 //printf( "%d ", Pla_CubeNum(hCube2) );
675 Fxch_TabDoubleDivisors( p, Pla_CubeNum(hCube1), 0 ), // remove - update
676 Fxch_TabDoubleDivisors( p, Pla_CubeNum(hCube2), 0 ); // remove - update
677 }
678 //printf( "\n" );
679
680 // create new literals
681 p->nLits += 2;
682 iVarNew = Vec_WecSize( &p->vLits ) / 2;
683 vLitP = Vec_WecPushLevel( &p->vLits );
684 vLitN = Vec_WecPushLevel( &p->vLits );
685 vLitP = Vec_WecEntry( &p->vLits, Vec_WecSize(&p->vLits) - 2 );
686 // update single-cube divisor cubes
687// Vec_IntForEachEntryDouble( &p->vCubesS, hCube1, hCube2, i )
688 Vec_IntForEachEntry( &p->vCubesS, hCube1, i )
689 {
690// int Lit0s, Lit1s;
691 vCube1 = Fxch_ManCube( p, hCube1 );
692// Lit0s = Vec_IntEntry(vCube1, Pla_CubeLit(hCube1));
693// Lit1s = Vec_IntEntry(vCube1, Pla_CubeLit(hCube2));
694// assert( Pla_CubeNum(hCube1) == Pla_CubeNum(hCube2) );
695// assert( Vec_IntEntry(vCube1, Pla_CubeLit(hCube1)) == Lit0 );
696// assert( Vec_IntEntry(vCube1, Pla_CubeLit(hCube2)) == Lit1 );
697 Fxch_CompressLiterals( vCube1, Lit0, Lit1 );
698// Vec_IntPush( vLitP, Pla_CubeHandle(Pla_CubeNum(hCube1), Vec_IntSize(vCube1)) );
699 Vec_IntPush( vLitP, Pla_CubeNum(hCube1) );
700 Vec_IntPush( vCube1, Abc_Var2Lit(iVarNew, 0) );
701
702 //if ( Pla_CubeNum(hCube1) == 3 )
703 // printf( "VecSize = %d\n", Vec_IntSize(vCube1) );
704
705 p->nLits--;
706 }
707 // update double-cube divisor cube pairs
708 Vec_IntForEachEntryDouble( &p->vCubesD, hCube1, hCube2, i )
709 {
710 vCube1 = Fxch_ManCube( p, hCube1 );
711 vCube2 = Fxch_ManCube( p, hCube2 );
712 assert( Vec_IntEntry(vCube1, Pla_CubeLit(hCube1)) == Abc_LitNot(Lit0) );
713 assert( Vec_IntEntry(vCube2, Pla_CubeLit(hCube2)) == Abc_LitNot(Lit1) );
714 Fxch_CompressLiterals2( vCube1, Pla_CubeLit(hCube1), -1 );
715// Vec_IntPush( vLitN, Pla_CubeHandle(Pla_CubeNum(hCube1), Vec_IntSize(vCube1)) );
716 Vec_IntPush( vLitN, Pla_CubeNum(hCube1) );
717 Vec_IntPush( vCube1, Abc_Var2Lit(iVarNew, 1) );
718 p->nLits -= Vec_IntSize(vCube2);
719
720 //if ( Pla_CubeNum(hCube1) == 3 )
721 // printf( "VecSize = %d\n", Vec_IntSize(vCube1) );
722
723 // remove second cube
724 Vec_IntClear( vCube2 );
725 }
726 Vec_IntSort( vLitN, 0 );
727 Vec_IntSort( vLitP, 0 );
728
729 // add cost of single-cube divisors
730// Vec_IntForEachEntryDouble( &p->vCubesS, hCube1, hCube2, i )
731 Vec_IntForEachEntry( &p->vCubesS, hCube1, i )
732 Fxch_TabSingleDivisors( p, Pla_CubeNum(hCube1), 1 ); // add - update
733 Vec_IntForEachEntryDouble( &p->vCubesD, hCube1, hCube2, i )
734 Fxch_TabSingleDivisors( p, Pla_CubeNum(hCube1), 1 ); // add - update
735
736 // add cost of double-cube divisors
737// Vec_IntForEachEntryDouble( &p->vCubesS, hCube1, hCube2, i )
738 Vec_IntForEachEntry( &p->vCubesS, hCube1, i )
739 Fxch_TabDoubleDivisors( p, Pla_CubeNum(hCube1), 1 ); // add - update
740 Vec_IntForEachEntryDouble( &p->vCubesD, hCube1, hCube2, i )
741 Fxch_TabDoubleDivisors( p, Pla_CubeNum(hCube1), 1 ); // add - update
742
743 // check predicted improvement: (new SOP lits == old SOP lits - divisor weight)
744 //assert( p->nLits == nLitsNew );
745}
746
758static void Fxch_PrintStats( Fxch_Man_t * p, abctime clk )
759{
760 printf( "Num =%6d ", Vec_WrdSize(&p->vDivs) - p->nVars );
761 printf( "Cubes =%8d ", Vec_WecSizeUsed(&p->vCubes) );
762 printf( "Lits =%8d ", p->nLits );
763 printf( "Divs =%8d ", Hash_IntManEntryNum(p->vHash) );
764 printf( "Divs+ =%8d ", Vec_QueSize(p->vPrio) );
765 printf( "PairS =%6d ", p->nPairsS );
766 printf( "PairD =%6d ", p->nPairsD );
767 Abc_PrintTime( 1, "Time", clk );
768// printf( "\n" );
769}
770static inline void Fxch_PrintDivOne( Fxch_Man_t * p, int iDiv )
771{
772 int i;
773 int Lit0 = Hash_IntObjData0( p->vHash, iDiv );
774 int Lit1 = Hash_IntObjData1( p->vHash, iDiv );
775 assert( Lit0 >= 0 && Lit1 >= 0 && Lit0 < Lit1 );
776 printf( "Div %4d : ", iDiv );
777 printf( "Weight %12.5f ", Vec_FltEntry(&p->vWeights, iDiv) );
778 printf( "Pairs = %5d ", Vec_IntSize(Vec_WecEntry(&p->vPairs, iDiv))/2 );
779 for ( i = 0; i < Vec_WrdSize(&p->vDivs); i++ )
780 {
781 if ( i == Abc_Lit2Var(Lit0) )
782 printf( "%d", !Abc_LitIsCompl(Lit0) );
783 else if ( i == Abc_Lit2Var(Lit1) )
784 printf( "%d", !Abc_LitIsCompl(Lit1) );
785 else
786 printf( "-" );
787 }
788 printf( "\n" );
789}
790static void Fxch_PrintDivisors( Fxch_Man_t * p )
791{
792 int iDiv;
793 for ( iDiv = 1; iDiv < Vec_FltSize(&p->vWeights); iDiv++ )
794 Fxch_PrintDivOne( p, iDiv );
795 printf( "\n" );
796}
797
798int Fxch_ManFastExtract( Fxch_Man_t * p, int fVerbose, int fVeryVerbose )
799{
800 int nNewNodesMax = ABC_INFINITY;
801 abctime clk = Abc_Clock();
802 int i, iDiv;
804// Fxch_PrintDivisors( p );
805 if ( fVerbose )
806 Fxch_PrintStats( p, Abc_Clock() - clk );
807 p->timeStart = Abc_Clock();
808 for ( i = 0; i < nNewNodesMax && Vec_QueTopPriority(p->vPrio) > 0.0; i++ )
809 {
810 iDiv = Vec_QuePop(p->vPrio);
811 //if ( fVerbose )
812 // Fxch_PrintStats( p, Abc_Clock() - clk );
813 if ( fVeryVerbose )
814 Fxch_PrintDivOne( p, iDiv );
815 Fxch_ManUpdate( p, iDiv );
816 }
817 if ( fVerbose )
818 Fxch_PrintStats( p, Abc_Clock() - clk );
819 return 1;
820}
821
834{
835 char pFileName[1000];
836 Fxch_Man_t * pFxch;
838 pFxch = Fxch_ManStart( &p->vCubeLits, &p->vOccurs );
839 Vec_WecZero( &p->vCubeLits );
840 Vec_WecZero( &p->vOccurs );
841 Fxch_ManFastExtract( pFxch, 1, 0 );
842 sprintf( pFileName, "%s.blif", Pla_ManName(p) );
843 //Fxch_ManWriteBlif( pFileName, &pFxch->vCubes, &pFxch->vDivs );
844 Fxch_ManStop( pFxch );
845 return 1;
846}
847
851
852
854
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#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
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
Cube * p
Definition exorList.c:222
char * Extra_TimeStamp()
unsigned Gia_ManRandom(int fReset)
FUNCTION DEFINITIONS ///.
Definition giaUtil.c:49
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
void Fxch_ManStop(Fxch_Man_t *p)
Definition plaFxch.c:201
int Fxch_TabDoubleDivisors(Fxch_Man_t *p, int iCube, int fAdd)
Definition plaFxch.c:567
int Pla_ManPerformFxch(Pla_Man_t *p)
Definition plaFxch.c:833
void Fxch_DivisorRemove(Fxch_Man_t *p, int Lit0, int Lit1, int Weight)
Definition plaFxch.c:369
int Fxch_ManFastExtract(Fxch_Man_t *p, int fVerbose, int fVeryVerbose)
Definition plaFxch.c:798
typedefABC_NAMESPACE_IMPL_START struct Fxch_Obj_t_ Fxch_Obj_t
DECLARATIONS ///.
Definition plaFxch.c:31
void Fxch_ManWriteBlif(char *pFileName, Vec_Wec_t *vCubes, Vec_Wrd_t *vDivs)
FUNCTION DEFINITIONS ///.
Definition plaFxch.c:93
struct Fxch_Man_t_ Fxch_Man_t
TYPEDEF DECLARATIONS ///.
Definition plaFxch.c:42
void Fxch_ManCreateDivisors(Fxch_Man_t *p)
Definition plaFxch.c:585
int Fxch_DivisorAdd(Fxch_Man_t *p, int Lit0, int Lit1, int Weight)
Definition plaFxch.c:344
int Fxch_TabSingleDivisors(Fxch_Man_t *p, int iCube, int fAdd)
Definition plaFxch.c:550
Fxch_Man_t * Fxch_ManStart(Vec_Wec_t *vCubes, Vec_Wec_t *vLits)
Definition plaFxch.c:164
void Fxch_ManUpdate(Fxch_Man_t *p, int iDiv)
Definition plaFxch.c:617
void Pla_ManConvertFromBits(Pla_Man_t *p)
Definition plaMan.c:221
struct Pla_Man_t_ Pla_Man_t
Definition pla.h:63
int nVars
Definition plaFxch.c:65
Vec_Wec_t vLits
Definition plaFxch.c:48
Vec_Wec_t vCubes
Definition plaFxch.c:46
Vec_Int_t vCube1
Definition plaFxch.c:60
Fxch_Obj_t * pBins
Definition plaFxch.c:51
Vec_Wec_t vPairs
Definition plaFxch.c:55
int nLits
Definition plaFxch.c:66
Vec_Int_t vCubesD
Definition plaFxch.c:59
Hash_IntMan_t * vHash
Definition plaFxch.c:52
abctime timeStart
Definition plaFxch.c:63
Vec_Int_t vCubesS
Definition plaFxch.c:58
Vec_Que_t * vPrio
Definition plaFxch.c:53
Vec_Int_t vRands
Definition plaFxch.c:49
Vec_Wrd_t vDivs
Definition plaFxch.c:56
Vec_Int_t vCube2
Definition plaFxch.c:61
Vec_Int_t vCubeLinks
Definition plaFxch.c:50
int nPairsS
Definition plaFxch.c:68
int nCompls
Definition plaFxch.c:67
int nPairsD
Definition plaFxch.c:69
int SizeMask
Definition plaFxch.c:64
Vec_Flt_t vWeights
Definition plaFxch.c:54
unsigned MarkP
Definition plaFxch.c:36
unsigned MarkN
Definition plaFxch.c:35
unsigned Table
Definition plaFxch.c:34
#define assert(ex)
Definition util_old.h:213
char * sprintf()
#define Vec_FltForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecFlt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
Definition vecFlt.h:42
struct Hash_IntMan_t_ Hash_IntMan_t
Definition vecHash.h:51
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
Definition vecInt.h:72
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
Definition vecInt.h:56
typedefABC_NAMESPACE_HEADER_START struct Vec_Que_t_ Vec_Que_t
INCLUDES ///.
Definition vecQue.h:40
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition vecWec.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42
#define Vec_WrdForEachEntryStart(vVec, Entry, i, Start)
Definition vecWrd.h:56
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42