ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
fxuSelect.c
Go to the documentation of this file.
1
18
19#include "fxuInt.h"
20
22
23
27
28#define MAX_SIZE_LOOKAHEAD 20
29
30static int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar );
31
32static Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
33static Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble );
34static Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble );
35
37 int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 );
39 int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 );
40
41
45
57int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble )
58{
59 // the top entries
60 Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD] = {0};
61 Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD] = {0};
62 // the complements
63 Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD] = {0};
64 Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD] = {0};
65 Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD] = {0};
66 Fxu_Pair * pPair;
67 int nSingles;
68 int nDoubles;
69 int i;
70 int WeightBest;
71 int WeightCur;
72 int iNum, fBestS;
73
74 // collect the top entries from the queues
75 for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ )
76 {
77 pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle );
78 if ( pSingles[nSingles] == NULL )
79 break;
80 }
81 // put them back into the queue
82 for ( i = 0; i < nSingles; i++ )
83 if ( pSingles[i] )
84 Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] );
85
86 // the same for doubles
87 // collect the top entries from the queues
88 for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ )
89 {
90 pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble );
91 if ( pDoubles[nDoubles] == NULL )
92 break;
93 }
94 // put them back into the queue
95 for ( i = 0; i < nDoubles; i++ )
96 if ( pDoubles[i] )
97 Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] );
98
99 // for each single, find the complement double (if any)
100 for ( i = 0; i < nSingles; i++ )
101 if ( pSingles[i] )
102 pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] );
103
104 // for each double, find the complement single or double (if any)
105 for ( i = 0; i < nDoubles; i++ )
106 if ( pDoubles[i] )
107 {
108 pPair = pDoubles[i]->lPairs.pHead;
109 if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 )
110 {
111 pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] );
112 pDComplD[i] = NULL;
113 }
114// else if ( pPair->nLits1 == 2 && pPair->nLits2 == 2 )
115// {
116// pDComplS[i] = NULL;
117// pDComplD[i] = Fxu_MatrixFindComplementDouble4( p, pDoubles[i] );
118// }
119 else
120 {
121 pDComplS[i] = NULL;
122 pDComplD[i] = NULL;
123 }
124 }
125
126 // select the best pair
127 WeightBest = -1;
128 for ( i = 0; i < nSingles; i++ )
129 {
130 WeightCur = pSingles[i]->Weight;
131 if ( pSCompl[i] )
132 {
133 // add the weight of the double
134 WeightCur += pSCompl[i]->Weight;
135 // there is no need to implement this double, so...
136 pPair = pSCompl[i]->lPairs.pHead;
137 WeightCur += pPair->nLits1 + pPair->nLits2;
138 }
139 if ( WeightBest < WeightCur )
140 {
141 WeightBest = WeightCur;
142 *ppSingle = pSingles[i];
143 *ppDouble = pSCompl[i];
144 fBestS = 1;
145 iNum = i;
146 }
147 }
148 for ( i = 0; i < nDoubles; i++ )
149 {
150 WeightCur = pDoubles[i]->Weight;
151 if ( pDComplS[i] )
152 {
153 // add the weight of the single
154 WeightCur += pDComplS[i]->Weight;
155 // there is no need to implement this double, so...
156 pPair = pDoubles[i]->lPairs.pHead;
157 WeightCur += pPair->nLits1 + pPair->nLits2;
158 }
159 if ( WeightBest < WeightCur )
160 {
161 WeightBest = WeightCur;
162 *ppSingle = pDComplS[i];
163 *ppDouble = pDoubles[i];
164 fBestS = 0;
165 iNum = i;
166 }
167 }
168/*
169 // print the statistics
170 printf( "\n" );
171 for ( i = 0; i < nSingles; i++ )
172 {
173 printf( "Single #%d: Weight = %3d. ", i, pSingles[i]->Weight );
174 printf( "Compl: " );
175 if ( pSCompl[i] == NULL )
176 printf( "None." );
177 else
178 printf( "D Weight = %3d Sum = %3d",
179 pSCompl[i]->Weight, pSCompl[i]->Weight + pSingles[i]->Weight );
180 printf( "\n" );
181 }
182 printf( "\n" );
183 for ( i = 0; i < nDoubles; i++ )
184 {
185 printf( "Double #%d: Weight = %3d. ", i, pDoubles[i]->Weight );
186 printf( "Compl: " );
187 if ( pDComplS[i] == NULL && pDComplD[i] == NULL )
188 printf( "None." );
189 else if ( pDComplS[i] )
190 printf( "S Weight = %3d Sum = %3d",
191 pDComplS[i]->Weight, pDComplS[i]->Weight + pDoubles[i]->Weight );
192 else if ( pDComplD[i] )
193 printf( "D Weight = %3d Sum = %3d",
194 pDComplD[i]->Weight, pDComplD[i]->Weight + pDoubles[i]->Weight );
195 printf( "\n" );
196 }
197 if ( WeightBest == -1 )
198 printf( "Selected NONE\n" );
199 else
200 {
201 printf( "Selected = %s. ", fBestS? "S": "D" );
202 printf( "Number = %d. ", iNum );
203 printf( "Weight = %d.\n", WeightBest );
204 }
205 printf( "\n" );
206*/
207 return WeightBest;
208}
209
210
222Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle )
223{
224// int * pValue2Node = p->pValue2Node;
225 int iVar1, iVar2;
226 int iVar1C, iVar2C;
227 // get the variables of this single div
228 iVar1 = pSingle->pVar1->iVar;
229 iVar2 = pSingle->pVar2->iVar;
230 iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
231 iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
232 if ( iVar1C == -1 || iVar2C == -1 )
233 return NULL;
234 assert( iVar1C < iVar2C );
235 return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 );
236}
237
249Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble )
250{
251// int * pValue2Node = p->pValue2Node;
252 int piVarsC1[10], piVarsC2[10];
253 int nVarsC1, nVarsC2;
254 int iVar1, iVar2, iVarTemp;
255 int iVar1C, iVar2C;
256 Fxu_Single * pSingle;
257
258 // get the variables of this double div
259 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
260 assert( nVarsC1 == 1 );
261 assert( nVarsC2 == 1 );
262 iVar1 = piVarsC1[0];
263 iVar2 = piVarsC2[0];
264 assert( iVar1 < iVar2 );
265
266 iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
267 iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
268 if ( iVar1C == -1 || iVar2C == -1 )
269 return NULL;
270
271 // go through the queque and find this one
272// assert( iVar1C < iVar2C );
273 if ( iVar1C > iVar2C )
274 {
275 iVarTemp = iVar1C;
276 iVar1C = iVar2C;
277 iVar2C = iVarTemp;
278 }
279
280 Fxu_MatrixForEachSingle( p, pSingle )
281 if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C )
282 return pSingle;
283 return NULL;
284}
285
297Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble )
298{
299// int * pValue2Node = p->pValue2Node;
300 int piVarsC1[10], piVarsC2[10];
301 int nVarsC1, nVarsC2;
302 int iVar11, iVar12, iVar21, iVar22;
303 int iVar11C, iVar12C, iVar21C, iVar22C;
304 int RetValue;
305
306 // get the variables of this double div
307 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
308 assert( nVarsC1 == 2 && nVarsC2 == 2 );
309
310 iVar11 = piVarsC1[0];
311 iVar12 = piVarsC1[1];
312 iVar21 = piVarsC2[0];
313 iVar22 = piVarsC2[1];
314 assert( iVar11 < iVar21 );
315
316 iVar11C = Fxu_MatrixFindComplement( p, iVar11 );
317 iVar12C = Fxu_MatrixFindComplement( p, iVar12 );
318 iVar21C = Fxu_MatrixFindComplement( p, iVar21 );
319 iVar22C = Fxu_MatrixFindComplement( p, iVar22 );
320 if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 )
321 return NULL;
322 if ( iVar11C != iVar21 || iVar12C != iVar22 ||
323 iVar21C != iVar11 || iVar22C != iVar12 )
324 return NULL;
325
326 // a'b' + ab => a'b + ab'
327 // a'b + ab' => a'b' + ab
328 // swap the second pair in each cube
329 RetValue = piVarsC1[1];
330 piVarsC1[1] = piVarsC2[1];
331 piVarsC2[1] = RetValue;
332
333 return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 );
334}
335
336
348int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar )
349{
350 return iVar ^ 1;
351/*
352// int * pValue2Node = p->pValue2Node;
353 int iVarC;
354 int iNode;
355 int Beg, End;
356
357 // get the nodes
358 iNode = pValue2Node[iVar];
359 // get the first node with the same var
360 for ( Beg = iVar; Beg >= 0; Beg-- )
361 if ( pValue2Node[Beg] != iNode )
362 {
363 Beg++;
364 break;
365 }
366 // get the last node with the same var
367 for ( End = iVar; ; End++ )
368 if ( pValue2Node[End] != iNode )
369 {
370 End--;
371 break;
372 }
373
374 // if one of the vars is not binary, quit
375 if ( End - Beg > 1 )
376 return -1;
377
378 // get the complements
379 if ( iVar == Beg )
380 iVarC = End;
381 else if ( iVar == End )
382 iVarC = Beg;
383 else
384 {
385 assert( 0 );
386 }
387 return iVarC;
388*/
389}
390
391
404 int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 )
405{
406 Fxu_Pair * pPair;
407 Fxu_Lit * pLit1, * pLit2;
408 int nLits1, nLits2;
409
410 // get the first pair
411 pPair = pDouble->lPairs.pHead;
412 // init the parameters
413 nLits1 = 0;
414 nLits2 = 0;
415 pLit1 = pPair->pCube1->lLits.pHead;
416 pLit2 = pPair->pCube2->lLits.pHead;
417 while ( 1 )
418 {
419 if ( pLit1 && pLit2 )
420 {
421 if ( pLit1->iVar == pLit2->iVar )
422 { // ensure cube-free
423 pLit1 = pLit1->pHNext;
424 pLit2 = pLit2->pHNext;
425 }
426 else if ( pLit1->iVar < pLit2->iVar )
427 {
428 piVarsC1[nLits1++] = pLit1->iVar;
429 pLit1 = pLit1->pHNext;
430 }
431 else
432 {
433 piVarsC2[nLits2++] = pLit2->iVar;
434 pLit2 = pLit2->pHNext;
435 }
436 }
437 else if ( pLit1 && !pLit2 )
438 {
439 piVarsC1[nLits1++] = pLit1->iVar;
440 pLit1 = pLit1->pHNext;
441 }
442 else if ( !pLit1 && pLit2 )
443 {
444 piVarsC2[nLits2++] = pLit2->iVar;
445 pLit2 = pLit2->pHNext;
446 }
447 else
448 break;
449 }
450 *pnVarsC1 = nLits1;
451 *pnVarsC2 = nLits2;
452}
453
454
467 int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 )
468{
469 int piVarsC1_[100], piVarsC2_[100];
470 int nVarsC1_, nVarsC2_, i;
471 Fxu_Double * pDouble;
472 Fxu_Pair * pPair;
473 unsigned Key;
474
475 assert( nVarsC1 > 0 );
476 assert( nVarsC2 > 0 );
477 assert( piVarsC1[0] < piVarsC2[0] );
478
479 // get the hash key
480 Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 );
481
482 // check if the divisor for this pair already exists
483 Key %= p->nTableSize;
484 Fxu_TableForEachDouble( p, Key, pDouble )
485 {
486 pPair = pDouble->lPairs.pHead;
487 if ( pPair->nLits1 != nVarsC1 )
488 continue;
489 if ( pPair->nLits2 != nVarsC2 )
490 continue;
491 // get the cubes of this divisor
492 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ );
493 // compare lits of the first cube
494 for ( i = 0; i < nVarsC1; i++ )
495 if ( piVarsC1[i] != piVarsC1_[i] )
496 break;
497 if ( i != nVarsC1 )
498 continue;
499 // compare lits of the second cube
500 for ( i = 0; i < nVarsC2; i++ )
501 if ( piVarsC2[i] != piVarsC2_[i] )
502 break;
503 if ( i != nVarsC2 )
504 continue;
505 return pDouble;
506 }
507 return NULL;
508}
509
510
511
512
513
525int Fxu_SelectSCD( Fxu_Matrix * p, int WeightLimit, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 )
526{
527// int * pValue2Node = p->pValue2Node;
528 Fxu_Var * pVar1;
529 Fxu_Var * pVar2, * pVarTemp;
530 Fxu_Lit * pLitV, * pLitH;
531 int Coin;
532 int CounterAll;
533 int CounterTest;
534 int WeightCur;
535 int WeightBest;
536
537 CounterAll = 0;
538 CounterTest = 0;
539
540 WeightBest = -10;
541
542 // iterate through the columns in the matrix
544 {
545 // start collecting the affected vars
547
548 // go through all the literals of this variable
549 for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
550 {
551 // for this literal, go through all the horizontal literals
552 for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext )
553 {
554 // get another variable
555 pVar2 = pLitH->pVar;
556 CounterAll++;
557 // skip the var if it is already used
558 if ( pVar2->pOrder )
559 continue;
560 // skip the var if it belongs to the same node
561// if ( pValue2Node[pVar1->iVar] == pValue2Node[pVar2->iVar] )
562// continue;
563 // collect the var
564 Fxu_MatrixRingVarsAdd( p, pVar2 );
565 }
566 }
567 // stop collecting the selected vars
569
570 // iterate through the selected vars
572 {
573 CounterTest++;
574
575 // count the coincidence
576 Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 );
577 assert( Coin > 0 );
578
579 // get the new weight
580 WeightCur = Coin - 2;
581
582 // compare the weights
583 if ( WeightBest < WeightCur )
584 {
585 WeightBest = WeightCur;
586 *ppVar1 = pVar1;
587 *ppVar2 = pVar2;
588 }
589 }
590 // unmark the vars
591 Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp )
592 pVar2->pOrder = NULL;
594 }
595
596// if ( WeightBest == WeightLimit )
597// return -1;
598 return WeightBest;
599}
600
601
605
606
608
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
Cube * p
Definition exorList.c:222
void Fxu_HeapDoubleInsert(Fxu_HeapDouble *p, Fxu_Double *pDiv)
Definition fxuHeapD.c:201
Fxu_Double * Fxu_HeapDoubleGetMax(Fxu_HeapDouble *p)
Definition fxuHeapD.c:291
Fxu_Single * Fxu_HeapSingleGetMax(Fxu_HeapSingle *p)
Definition fxuHeapS.c:293
void Fxu_HeapSingleInsert(Fxu_HeapSingle *p, Fxu_Single *pSingle)
Definition fxuHeapS.c:204
#define Fxu_MatrixForEachVarInRing(Matrix, Var)
Definition fxuInt.h:407
int Fxu_SingleCountCoincidence(Fxu_Matrix *p, Fxu_Var *pVar1, Fxu_Var *pVar2)
Definition fxuSingle.c:241
unsigned Fxu_PairHashKeyArray(Fxu_Matrix *p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2)
Definition fxuPair.c:137
struct FxuVar Fxu_Var
Definition fxuInt.h:67
#define Fxu_MatrixRingVarsStart( Matrix)
Definition fxuInt.h:386
#define Fxu_MatrixRingVarsAdd( Matrix, Var)
Definition fxuInt.h:395
#define Fxu_MatrixForEachVarInRingSafe(Matrix, Var, Var2)
Definition fxuInt.h:412
struct FxuSingle Fxu_Single
Definition fxuInt.h:73
#define Fxu_MatrixForEachSingle(Matrix, Single)
Definition fxuInt.h:312
typedefABC_NAMESPACE_HEADER_START struct FxuMatrix Fxu_Matrix
INCLUDES ///.
Definition fxuInt.h:63
struct FxuPair Fxu_Pair
Definition fxuInt.h:71
#define Fxu_TableForEachDouble(Matrix, Key, Div)
Definition fxuInt.h:321
struct FxuDouble Fxu_Double
Definition fxuInt.h:72
#define Fxu_MatrixRingVarsReset( Matrix)
Definition fxuInt.h:392
#define Fxu_MatrixRingVarsStop( Matrix)
Definition fxuInt.h:389
#define Fxu_MatrixForEachVariable(Matrix, Var)
Definition fxuInt.h:303
struct FxuLit Fxu_Lit
Definition fxuInt.h:68
void Fxu_MatrixGetDoubleVars(Fxu_Matrix *p, Fxu_Double *pDouble, int piVarsC1[], int piVarsC2[], int *pnVarsC1, int *pnVarsC2)
Definition fxuSelect.c:403
int Fxu_Select(Fxu_Matrix *p, Fxu_Single **ppSingle, Fxu_Double **ppDouble)
FUNCTION DEFINITIONS ///.
Definition fxuSelect.c:57
int Fxu_SelectSCD(Fxu_Matrix *p, int WeightLimit, Fxu_Var **ppVar1, Fxu_Var **ppVar2)
Definition fxuSelect.c:525
#define MAX_SIZE_LOOKAHEAD
DECLARATIONS ///.
Definition fxuSelect.c:28
Fxu_Double * Fxu_MatrixFindDouble(Fxu_Matrix *p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2)
Definition fxuSelect.c:466
Fxu_ListLit lLits
Definition fxuInt.h:206
int Weight
Definition fxuInt.h:258
Fxu_ListPair lPairs
Definition fxuInt.h:260
Fxu_Lit * pHead
Definition fxuInt.h:109
Fxu_Pair * pHead
Definition fxuInt.h:117
Fxu_Lit * pHNext
Definition fxuInt.h:233
Fxu_Lit * pVNext
Definition fxuInt.h:235
int iVar
Definition fxuInt.h:228
Fxu_Var * pVar
Definition fxuInt.h:231
int nLits2
Definition fxuInt.h:242
Fxu_Cube * pCube1
Definition fxuInt.h:245
int nLits1
Definition fxuInt.h:241
Fxu_Cube * pCube2
Definition fxuInt.h:246
int Weight
Definition fxuInt.h:271
Fxu_Var * pVar2
Definition fxuInt.h:273
Fxu_Var * pVar1
Definition fxuInt.h:272
Fxu_Var * pOrder
Definition fxuInt.h:222
int iVar
Definition fxuInt.h:215
Fxu_ListLit lLits
Definition fxuInt.h:219
#define assert(ex)
Definition util_old.h:213