abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
fraigFeed.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [fraigFeed.c]
4 
5  PackageName [FRAIG: Functionally reduced AND-INV graphs.]
6 
7  Synopsis [Procedures to support the solver feedback.]
8 
9  Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]
10 
11  Affiliation [UC Berkeley]
12 
13  Date [Ver. 2.0. Started - October 1, 2004]
14 
15  Revision [$Id: fraigFeed.c,v 1.8 2005/07/08 01:01:31 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include "fraigInt.h"
20 
22 
23 
24 ////////////////////////////////////////////////////////////////////////
25 /// DECLARATIONS ///
26 ////////////////////////////////////////////////////////////////////////
27 
28 static int Fraig_FeedBackPrepare( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars );
29 static int Fraig_FeedBackInsert( Fraig_Man_t * p, int nVarsPi );
30 static void Fraig_FeedBackVerify( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
31 
32 static void Fraig_FeedBackCovering( Fraig_Man_t * p, Msat_IntVec_t * vPats );
34 static int Fraig_GetSmallestColumn( int * pHits, int nHits );
35 static int Fraig_GetHittingPattern( unsigned * pSims, int nWords );
36 static void Fraig_CancelCoveredColumns( Fraig_NodeVec_t * vColumns, int * pHits, int iPat );
37 static void Fraig_FeedBackCheckTable( Fraig_Man_t * p );
40 
41 
42 ////////////////////////////////////////////////////////////////////////
43 /// FUNCTION DEFINITIONS ///
44 ////////////////////////////////////////////////////////////////////////
45 
46 /**Function*************************************************************
47 
48  Synopsis [Initializes the feedback information.]
49 
50  Description []
51 
52  SideEffects []
53 
54  SeeAlso []
55 
56 ***********************************************************************/
58 {
59  p->vCones = Fraig_NodeVecAlloc( 500 );
60  p->vPatsReal = Msat_IntVecAlloc( 1000 );
61  p->pSimsReal = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
62  memset( p->pSimsReal, 0, sizeof(unsigned) * p->nWordsDyna );
63  p->pSimsTemp = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
64  p->pSimsDiff = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
65 }
66 
67 /**Function*************************************************************
68 
69  Synopsis [Processes the feedback from teh solver.]
70 
71  Description [Array pModel gives the value of each variable in the SAT
72  solver. Array vVars is the array of integer numbers of variables
73  involves in this conflict.]
74 
75  SideEffects []
76 
77  SeeAlso []
78 
79 ***********************************************************************/
80 void Fraig_FeedBack( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars, Fraig_Node_t * pOld, Fraig_Node_t * pNew )
81 {
82  int nVarsPi, nWords;
83  int i;
84  abctime clk = Abc_Clock();
85 
86  // get the number of PI vars in the feedback (also sets the PI values)
87  nVarsPi = Fraig_FeedBackPrepare( p, pModel, vVars );
88 
89  // set the PI values
90  nWords = Fraig_FeedBackInsert( p, nVarsPi );
91  assert( p->iWordStart + nWords <= p->nWordsDyna );
92 
93  // resimulates the words from p->iWordStart to iWordStop
94  for ( i = 1; i < p->vNodes->nSize; i++ )
95  if ( Fraig_NodeIsAnd(p->vNodes->pArray[i]) )
96  Fraig_NodeSimulate( p->vNodes->pArray[i], p->iWordStart, p->iWordStart + nWords, 0 );
97 
98  if ( p->fDoSparse )
99  Fraig_TableRehashF0( p, 0 );
100 
101  if ( !p->fChoicing )
102  Fraig_FeedBackVerify( p, pOld, pNew );
103 
104  // if there is no room left, compress the patterns
105  if ( p->iWordStart + nWords == p->nWordsDyna )
106  p->iWordStart = Fraig_FeedBackCompress( p );
107  else // otherwise, update the starting word
108  p->iWordStart += nWords;
109 
110 p->timeFeed += Abc_Clock() - clk;
111 }
112 
113 /**Function*************************************************************
114 
115  Synopsis [Get the number and values of the PI variables.]
116 
117  Description [Returns the number of PI variables involved in this feedback.
118  Fills in the internal presence and value data for the primary inputs.]
119 
120  SideEffects []
121 
122  SeeAlso []
123 
124 ***********************************************************************/
125 int Fraig_FeedBackPrepare( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars )
126 {
127  Fraig_Node_t * pNode;
128  int i, nVars, nVarsPis, * pVars;
129 
130  // clean the presence flag for all PIs
131  for ( i = 0; i < p->vInputs->nSize; i++ )
132  {
133  pNode = p->vInputs->pArray[i];
134  pNode->fFeedUse = 0;
135  }
136 
137  // get the variables involved in the feedback
138  nVars = Msat_IntVecReadSize(vVars);
139  pVars = Msat_IntVecReadArray(vVars);
140 
141  // set the values for the present variables
142  nVarsPis = 0;
143  for ( i = 0; i < nVars; i++ )
144  {
145  pNode = p->vNodes->pArray[ pVars[i] ];
146  if ( !Fraig_NodeIsVar(pNode) )
147  continue;
148  // set its value
149  pNode->fFeedUse = 1;
150  pNode->fFeedVal = !MSAT_LITSIGN(pModel[pVars[i]]);
151  nVarsPis++;
152  }
153  return nVarsPis;
154 }
155 
156 /**Function*************************************************************
157 
158  Synopsis [Inserts the new simulation patterns.]
159 
160  Description []
161 
162  SideEffects []
163 
164  SeeAlso []
165 
166 ***********************************************************************/
167 int Fraig_FeedBackInsert( Fraig_Man_t * p, int nVarsPi )
168 {
169  Fraig_Node_t * pNode;
170  int nWords, iPatFlip, nPatFlipLimit, i, w;
171  int fUseNoPats = 0;
172  int fUse2Pats = 0;
173 
174  // get the number of words
175  if ( fUse2Pats )
176  nWords = FRAIG_NUM_WORDS( 2 * nVarsPi + 1 );
177  else if ( fUseNoPats )
178  nWords = 1;
179  else
180  nWords = FRAIG_NUM_WORDS( nVarsPi + 1 );
181  // update the number of words if they do not fit into the simulation info
182  if ( nWords > p->nWordsDyna - p->iWordStart )
183  nWords = p->nWordsDyna - p->iWordStart;
184  // determine the bound on the flipping bit
185  nPatFlipLimit = nWords * 32 - 2;
186 
187  // mark the real pattern
188  Msat_IntVecPush( p->vPatsReal, p->iWordStart * 32 );
189  // record the real pattern
190  Fraig_BitStringSetBit( p->pSimsReal, p->iWordStart * 32 );
191 
192  // set the values at the PIs
193  iPatFlip = 1;
194  for ( i = 0; i < p->vInputs->nSize; i++ )
195  {
196  pNode = p->vInputs->pArray[i];
197  for ( w = p->iWordStart; w < p->iWordStart + nWords; w++ )
198  if ( !pNode->fFeedUse )
199  pNode->puSimD[w] = FRAIG_RANDOM_UNSIGNED;
200  else if ( pNode->fFeedVal )
201  pNode->puSimD[w] = FRAIG_FULL;
202  else // if ( !pNode->fFeedVal )
203  pNode->puSimD[w] = 0;
204 
205  if ( fUse2Pats )
206  {
207  // flip two patterns
208  if ( pNode->fFeedUse && 2 * iPatFlip < nPatFlipLimit )
209  {
210  Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip - 1 );
211  Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip );
212  Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, 2 * iPatFlip + 1 );
213  iPatFlip++;
214  }
215  }
216  else if ( fUseNoPats )
217  {
218  }
219  else
220  {
221  // flip the diagonal
222  if ( pNode->fFeedUse && iPatFlip < nPatFlipLimit )
223  {
224  Fraig_BitStringXorBit( pNode->puSimD + p->iWordStart, iPatFlip );
225  iPatFlip++;
226  // Extra_PrintBinary( stdout, &pNode->puSimD, 45 ); printf( "\n" );
227  }
228  }
229  // clean the use mask
230  pNode->fFeedUse = 0;
231 
232  // add the info to the D hash value of the PIs
233  for ( w = p->iWordStart; w < p->iWordStart + nWords; w++ )
234  pNode->uHashD ^= pNode->puSimD[w] * s_FraigPrimes[w];
235 
236  }
237  return nWords;
238 }
239 
240 
241 /**Function*************************************************************
242 
243  Synopsis [Checks that the SAT solver pattern indeed distinquishes the nodes.]
244 
245  Description []
246 
247  SideEffects []
248 
249  SeeAlso []
250 
251 ***********************************************************************/
253 {
254  int fValue1, fValue2, iPat;
255  iPat = Msat_IntVecReadEntry( p->vPatsReal, Msat_IntVecReadSize(p->vPatsReal)-1 );
256  fValue1 = (Fraig_BitStringHasBit( pOld->puSimD, iPat ));
257  fValue2 = (Fraig_BitStringHasBit( pNew->puSimD, iPat ));
258 /*
259 Fraig_PrintNode( p, pOld );
260 printf( "\n" );
261 Fraig_PrintNode( p, pNew );
262 printf( "\n" );
263 */
264 // assert( fValue1 != fValue2 );
265 }
266 
267 /**Function*************************************************************
268 
269  Synopsis [Compress the simulation patterns.]
270 
271  Description []
272 
273  SideEffects []
274 
275  SeeAlso []
276 
277 ***********************************************************************/
279 {
280  unsigned * pSims;
281  unsigned uHash;
282  int i, w, t, nPats, * pPats;
283  int fPerformChecks = (p->nBTLimit == -1);
284 
285  // solve the covering problem
286  if ( fPerformChecks )
287  {
289  if ( p->fDoSparse )
291  }
292 
293  // solve the covering problem
294  Fraig_FeedBackCovering( p, p->vPatsReal );
295 
296 
297  // get the number of additional patterns
298  nPats = Msat_IntVecReadSize( p->vPatsReal );
299  pPats = Msat_IntVecReadArray( p->vPatsReal );
300  // get the new starting word
301  p->iWordStart = FRAIG_NUM_WORDS( p->iPatsPerm + nPats );
302 
303  // set the simulation info for the PIs
304  for ( i = 0; i < p->vInputs->nSize; i++ )
305  {
306  // get hold of the simulation info for this PI
307  pSims = p->vInputs->pArray[i]->puSimD;
308  // clean the storage for the new patterns
309  for ( w = p->iWordPerm; w < p->iWordStart; w++ )
310  p->pSimsTemp[w] = 0;
311  // set the patterns
312  for ( t = 0; t < nPats; t++ )
313  if ( Fraig_BitStringHasBit( pSims, pPats[t] ) )
314  {
315  // check if this pattern falls into temporary storage
316  if ( p->iPatsPerm + t < p->iWordPerm * 32 )
317  Fraig_BitStringSetBit( pSims, p->iPatsPerm + t );
318  else
319  Fraig_BitStringSetBit( p->pSimsTemp, p->iPatsPerm + t );
320  }
321  // copy the pattern
322  for ( w = p->iWordPerm; w < p->iWordStart; w++ )
323  pSims[w] = p->pSimsTemp[w];
324  // recompute the hashing info
325  uHash = 0;
326  for ( w = 0; w < p->iWordStart; w++ )
327  uHash ^= pSims[w] * s_FraigPrimes[w];
328  p->vInputs->pArray[i]->uHashD = uHash;
329  }
330 
331  // update info about the permanently stored patterns
332  p->iWordPerm = p->iWordStart;
333  p->iPatsPerm += nPats;
334  assert( p->iWordPerm == FRAIG_NUM_WORDS( p->iPatsPerm ) );
335 
336  // resimulate and recompute the hash values
337  for ( i = 1; i < p->vNodes->nSize; i++ )
338  if ( Fraig_NodeIsAnd(p->vNodes->pArray[i]) )
339  {
340  p->vNodes->pArray[i]->uHashD = 0;
341  Fraig_NodeSimulate( p->vNodes->pArray[i], 0, p->iWordPerm, 0 );
342  }
343 
344  // double-check that the nodes are still distinguished
345  if ( fPerformChecks )
347 
348  // rehash the values in the F0 table
349  if ( p->fDoSparse )
350  {
351  Fraig_TableRehashF0( p, 0 );
352  if ( fPerformChecks )
354  }
355 
356  // check if we need to resize the simulation info
357  // if less than FRAIG_WORDS_STORE words are left, reallocate simulation info
358  if ( p->iWordPerm + FRAIG_WORDS_STORE > p->nWordsDyna )
360 
361  // set the real patterns
362  Msat_IntVecClear( p->vPatsReal );
363  memset( p->pSimsReal, 0, sizeof(unsigned)*p->nWordsDyna );
364  for ( w = 0; w < p->iWordPerm; w++ )
365  p->pSimsReal[w] = FRAIG_FULL;
366  if ( p->iPatsPerm % 32 > 0 )
367  p->pSimsReal[p->iWordPerm-1] = FRAIG_MASK( p->iPatsPerm % 32 );
368 // printf( "The number of permanent words = %d.\n", p->iWordPerm );
369  return p->iWordStart;
370 }
371 
372 
373 
374 
375 /**Function*************************************************************
376 
377  Synopsis [Checks the correctness of the functional simulation table.]
378 
379  Description []
380 
381  SideEffects []
382 
383  SeeAlso []
384 
385 ***********************************************************************/
387 {
388  Fraig_NodeVec_t * vColumns;
389  unsigned * pSims;
390  int * pHits, iPat, iCol, i;
391  int nOnesTotal, nSolStarting;
392  int fVeryVerbose = 0;
393 
394  // collect the pairs to be distinguished
395  vColumns = Fraig_FeedBackCoveringStart( p );
396  // collect the number of 1s in each simulation vector
397  nOnesTotal = 0;
398  pHits = ABC_ALLOC( int, vColumns->nSize );
399  for ( i = 0; i < vColumns->nSize; i++ )
400  {
401  pSims = (unsigned *)vColumns->pArray[i];
402  pHits[i] = Fraig_BitStringCountOnes( pSims, p->iWordStart );
403  nOnesTotal += pHits[i];
404 // assert( pHits[i] > 0 );
405  }
406 
407  // go through the patterns
408  nSolStarting = Msat_IntVecReadSize(vPats);
409  while ( (iCol = Fraig_GetSmallestColumn( pHits, vColumns->nSize )) != -1 )
410  {
411  // find the pattern, which hits this column
412  iPat = Fraig_GetHittingPattern( (unsigned *)vColumns->pArray[iCol], p->iWordStart );
413  // cancel the columns covered by this pattern
414  Fraig_CancelCoveredColumns( vColumns, pHits, iPat );
415  // save the pattern
416  Msat_IntVecPush( vPats, iPat );
417  }
418 
419  // free the set of columns
420  for ( i = 0; i < vColumns->nSize; i++ )
421  Fraig_MemFixedEntryRecycle( p->mmSims, (char *)vColumns->pArray[i] );
422 
423  // print stats related to the covering problem
424  if ( p->fVerbose && fVeryVerbose )
425  {
426  printf( "%3d\\%3d\\%3d ", p->nWordsRand, p->nWordsDyna, p->iWordPerm );
427  printf( "Col (pairs) = %5d. ", vColumns->nSize );
428  printf( "Row (pats) = %5d. ", p->iWordStart * 32 );
429  printf( "Dns = %6.2f %%. ", vColumns->nSize==0? 0.0 : 100.0 * nOnesTotal / vColumns->nSize / p->iWordStart / 32 );
430  printf( "Sol = %3d (%3d). ", Msat_IntVecReadSize(vPats), nSolStarting );
431  printf( "\n" );
432  }
433  Fraig_NodeVecFree( vColumns );
434  ABC_FREE( pHits );
435 }
436 
437 
438 /**Function*************************************************************
439 
440  Synopsis [Checks the correctness of the functional simulation table.]
441 
442  Description []
443 
444  SideEffects []
445 
446  SeeAlso []
447 
448 ***********************************************************************/
450 {
451  Fraig_NodeVec_t * vColumns;
452  Fraig_HashTable_t * pT = p->pTableF;
453  Fraig_Node_t * pEntF, * pEntD;
454  unsigned * pSims;
455  unsigned * pUnsigned1, * pUnsigned2;
456  int i, k, m, w;//, nOnes;
457 
458  // start the set of columns
459  vColumns = Fraig_NodeVecAlloc( 100 );
460 
461  // go through the pairs of nodes to be distinguished
462  for ( i = 0; i < pT->nBins; i++ )
463  Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
464  {
465  p->vCones->nSize = 0;
466  Fraig_TableBinForEachEntryD( pEntF, pEntD )
467  Fraig_NodeVecPush( p->vCones, pEntD );
468  if ( p->vCones->nSize == 1 )
469  continue;
470  //////////////////////////////// bug fix by alanmi, September 14, 2006
471  if ( p->vCones->nSize > 20 )
472  continue;
473  ////////////////////////////////
474 
475  for ( k = 0; k < p->vCones->nSize; k++ )
476  for ( m = k+1; m < p->vCones->nSize; m++ )
477  {
478  if ( !Fraig_CompareSimInfoUnderMask( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0, p->pSimsReal ) )
479  continue;
480 
481  // primary simulation patterns (counter-examples) cannot distinguish this pair
482  // get memory to store the feasible simulation patterns
483  pSims = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
484  // find the pattern that distinguish this column, exept the primary ones
485  pUnsigned1 = p->vCones->pArray[k]->puSimD;
486  pUnsigned2 = p->vCones->pArray[m]->puSimD;
487  for ( w = 0; w < p->iWordStart; w++ )
488  pSims[w] = (pUnsigned1[w] ^ pUnsigned2[w]) & ~p->pSimsReal[w];
489  // store the pattern
490  Fraig_NodeVecPush( vColumns, (Fraig_Node_t *)pSims );
491 // nOnes = Fraig_BitStringCountOnes(pSims, p->iWordStart);
492 // assert( nOnes > 0 );
493  }
494  }
495 
496  // if the flag is not set, do not consider sparse nodes in p->pTableF0
497  if ( !p->fDoSparse )
498  return vColumns;
499 
500  // recalculate their hash values based on p->pSimsReal
501  pT = p->pTableF0;
502  for ( i = 0; i < pT->nBins; i++ )
503  Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
504  {
505  pSims = pEntF->puSimD;
506  pEntF->uHashD = 0;
507  for ( w = 0; w < p->iWordStart; w++ )
508  pEntF->uHashD ^= (pSims[w] & p->pSimsReal[w]) * s_FraigPrimes[w];
509  }
510 
511  // rehash the table using these values
512  Fraig_TableRehashF0( p, 1 );
513 
514  // collect the classes of equivalent node pairs
515  for ( i = 0; i < pT->nBins; i++ )
516  Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
517  {
518  p->vCones->nSize = 0;
519  Fraig_TableBinForEachEntryD( pEntF, pEntD )
520  Fraig_NodeVecPush( p->vCones, pEntD );
521  if ( p->vCones->nSize == 1 )
522  continue;
523 
524  // primary simulation patterns (counter-examples) cannot distinguish all these pairs
525  for ( k = 0; k < p->vCones->nSize; k++ )
526  for ( m = k+1; m < p->vCones->nSize; m++ )
527  {
528  // get memory to store the feasible simulation patterns
529  pSims = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
530  // find the patterns that are not distinquished
531  pUnsigned1 = p->vCones->pArray[k]->puSimD;
532  pUnsigned2 = p->vCones->pArray[m]->puSimD;
533  for ( w = 0; w < p->iWordStart; w++ )
534  pSims[w] = (pUnsigned1[w] ^ pUnsigned2[w]) & ~p->pSimsReal[w];
535  // store the pattern
536  Fraig_NodeVecPush( vColumns, (Fraig_Node_t *)pSims );
537 // nOnes = Fraig_BitStringCountOnes(pSims, p->iWordStart);
538 // assert( nOnes > 0 );
539  }
540  }
541  return vColumns;
542 }
543 
544 /**Function*************************************************************
545 
546  Synopsis [Selects the column, which has the smallest number of hits.]
547 
548  Description []
549 
550  SideEffects []
551 
552  SeeAlso []
553 
554 ***********************************************************************/
555 int Fraig_GetSmallestColumn( int * pHits, int nHits )
556 {
557  int i, iColMin = -1, nHitsMin = 1000000;
558  for ( i = 0; i < nHits; i++ )
559  {
560  // skip covered columns
561  if ( pHits[i] == 0 )
562  continue;
563  // take the column if it can only be covered by one pattern
564  if ( pHits[i] == 1 )
565  return i;
566  // find the column, which requires the smallest number of patterns
567  if ( nHitsMin > pHits[i] )
568  {
569  nHitsMin = pHits[i];
570  iColMin = i;
571  }
572  }
573  return iColMin;
574 }
575 
576 /**Function*************************************************************
577 
578  Synopsis [Select the pattern, which hits this column.]
579 
580  Description []
581 
582  SideEffects []
583 
584  SeeAlso []
585 
586 ***********************************************************************/
587 int Fraig_GetHittingPattern( unsigned * pSims, int nWords )
588 {
589  int i, b;
590  for ( i = 0; i < nWords; i++ )
591  {
592  if ( pSims[i] == 0 )
593  continue;
594  for ( b = 0; b < 32; b++ )
595  if ( pSims[i] & (1 << b) )
596  return i * 32 + b;
597  }
598  return -1;
599 }
600 
601 /**Function*************************************************************
602 
603  Synopsis [Cancel covered patterns.]
604 
605  Description []
606 
607  SideEffects []
608 
609  SeeAlso []
610 
611 ***********************************************************************/
612 void Fraig_CancelCoveredColumns( Fraig_NodeVec_t * vColumns, int * pHits, int iPat )
613 {
614  unsigned * pSims;
615  int i;
616  for ( i = 0; i < vColumns->nSize; i++ )
617  {
618  pSims = (unsigned *)vColumns->pArray[i];
619  if ( Fraig_BitStringHasBit( pSims, iPat ) )
620  pHits[i] = 0;
621  }
622 }
623 
624 
625 /**Function*************************************************************
626 
627  Synopsis [Checks the correctness of the functional simulation table.]
628 
629  Description []
630 
631  SideEffects []
632 
633  SeeAlso []
634 
635 ***********************************************************************/
637 {
638  Fraig_HashTable_t * pT = p->pTableF;
639  Fraig_Node_t * pEntF, * pEntD;
640  int i, k, m, nPairs;
641 
642  nPairs = 0;
643  for ( i = 0; i < pT->nBins; i++ )
644  Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
645  {
646  p->vCones->nSize = 0;
647  Fraig_TableBinForEachEntryD( pEntF, pEntD )
648  Fraig_NodeVecPush( p->vCones, pEntD );
649  if ( p->vCones->nSize == 1 )
650  continue;
651  for ( k = 0; k < p->vCones->nSize; k++ )
652  for ( m = k+1; m < p->vCones->nSize; m++ )
653  {
654  if ( Fraig_CompareSimInfo( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0 ) )
655  printf( "Nodes %d and %d have the same D simulation info.\n",
656  p->vCones->pArray[k]->Num, p->vCones->pArray[m]->Num );
657  nPairs++;
658  }
659  }
660 // printf( "\nThe total of %d node pairs have been verified.\n", nPairs );
661 }
662 
663 /**Function*************************************************************
664 
665  Synopsis [Checks the correctness of the functional simulation table.]
666 
667  Description []
668 
669  SideEffects []
670 
671  SeeAlso []
672 
673 ***********************************************************************/
675 {
676  Fraig_HashTable_t * pT = p->pTableF0;
677  Fraig_Node_t * pEntF;
678  int i, k, m, nPairs;
679 
680  nPairs = 0;
681  for ( i = 0; i < pT->nBins; i++ )
682  {
683  p->vCones->nSize = 0;
684  Fraig_TableBinForEachEntryF( pT->pBins[i], pEntF )
685  Fraig_NodeVecPush( p->vCones, pEntF );
686  if ( p->vCones->nSize == 1 )
687  continue;
688  for ( k = 0; k < p->vCones->nSize; k++ )
689  for ( m = k+1; m < p->vCones->nSize; m++ )
690  {
691  if ( Fraig_CompareSimInfo( p->vCones->pArray[k], p->vCones->pArray[m], p->iWordStart, 0 ) )
692  printf( "Nodes %d and %d have the same D simulation info.\n",
693  p->vCones->pArray[k]->Num, p->vCones->pArray[m]->Num );
694  nPairs++;
695  }
696  }
697 // printf( "\nThe total of %d node pairs have been verified.\n", nPairs );
698 }
699 
700 /**Function*************************************************************
701 
702  Synopsis [Doubles the size of simulation info.]
703 
704  Description []
705 
706  SideEffects []
707 
708  SeeAlso []
709 
710 ***********************************************************************/
712 {
713  Fraig_MemFixed_t * mmSimsNew; // new memory manager for simulation info
714  Fraig_Node_t * pNode;
715  unsigned * pSimsNew;
716  unsigned uSignOld;
717  int i;
718 
719  // allocate a new memory manager
720  p->nWordsDyna *= 2;
721  mmSimsNew = Fraig_MemFixedStart( sizeof(unsigned) * (p->nWordsRand + p->nWordsDyna) );
722 
723  // set the new data for the constant node
724  pNode = p->pConst1;
725  pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
726  pNode->puSimD = pNode->puSimR + p->nWordsRand;
727  memset( pNode->puSimR, 0, sizeof(unsigned) * p->nWordsRand );
728  memset( pNode->puSimD, 0, sizeof(unsigned) * p->nWordsDyna );
729 
730  // copy the simulation info of the PIs
731  for ( i = 0; i < p->vInputs->nSize; i++ )
732  {
733  pNode = p->vInputs->pArray[i];
734  // copy the simulation info
735  pSimsNew = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
736  memmove( pSimsNew, pNode->puSimR, sizeof(unsigned) * (p->nWordsRand + p->iWordStart) );
737  // attach the new info
738  pNode->puSimR = pSimsNew;
739  pNode->puSimD = pNode->puSimR + p->nWordsRand;
740  // signatures remain without changes
741  }
742 
743  // replace the manager to free up some memory
744  Fraig_MemFixedStop( p->mmSims, 0 );
745  p->mmSims = mmSimsNew;
746 
747  // resimulate the internal nodes (this should lead to the same signatures)
748  for ( i = 1; i < p->vNodes->nSize; i++ )
749  {
750  pNode = p->vNodes->pArray[i];
751  if ( !Fraig_NodeIsAnd(pNode) )
752  continue;
753  // allocate memory for the simulation info
754  pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
755  pNode->puSimD = pNode->puSimR + p->nWordsRand;
756  // derive random simulation info
757  uSignOld = pNode->uHashR;
758  pNode->uHashR = 0;
759  Fraig_NodeSimulate( pNode, 0, p->nWordsRand, 1 );
760  assert( uSignOld == pNode->uHashR );
761  // derive dynamic simulation info
762  uSignOld = pNode->uHashD;
763  pNode->uHashD = 0;
764  Fraig_NodeSimulate( pNode, 0, p->iWordStart, 0 );
765  assert( uSignOld == pNode->uHashD );
766  }
767 
768  // realloc temporary storage
769  p->pSimsReal = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
770  memset( p->pSimsReal, 0, sizeof(unsigned) * p->nWordsDyna );
771  p->pSimsTemp = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
772  p->pSimsDiff = (unsigned *)Fraig_MemFixedEntryFetch( mmSimsNew );
773 }
774 
775 
776 /**Function*************************************************************
777 
778  Synopsis [Generated trivial counter example.]
779 
780  Description []
781 
782  SideEffects []
783 
784  SeeAlso []
785 
786 ***********************************************************************/
788 {
789  int * pModel;
790  pModel = ABC_ALLOC( int, p->vInputs->nSize );
791  memset( pModel, 0, sizeof(int) * p->vInputs->nSize );
792  return pModel;
793 }
794 
795 
796 /**Function*************************************************************
797 
798  Synopsis [Saves the counter example.]
799 
800  Description []
801 
802  SideEffects []
803 
804  SeeAlso []
805 
806 ***********************************************************************/
808 {
809  int Value0, Value1;
810  if ( Fraig_NodeIsTravIdCurrent( p, pNode ) )
811  return pNode->fMark3;
812  Fraig_NodeSetTravIdCurrent( p, pNode );
813  Value0 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p1) );
814  Value1 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p2) );
815  Value0 ^= Fraig_IsComplement(pNode->p1);
816  Value1 ^= Fraig_IsComplement(pNode->p2);
817  pNode->fMark3 = Value0 & Value1;
818  return pNode->fMark3;
819 }
820 
821 /**Function*************************************************************
822 
823  Synopsis [Simulates one bit.]
824 
825  Description []
826 
827  SideEffects []
828 
829  SeeAlso []
830 
831 ***********************************************************************/
832 int Fraig_ManSimulateBitNode( Fraig_Man_t * p, Fraig_Node_t * pNode, int * pModel )
833 {
834  int fCompl, RetValue, i;
835  // set the PI values
837  for ( i = 0; i < p->vInputs->nSize; i++ )
838  {
839  Fraig_NodeSetTravIdCurrent( p, p->vInputs->pArray[i] );
840  p->vInputs->pArray[i]->fMark3 = pModel[i];
841  }
842  // perform the traversal
843  fCompl = Fraig_IsComplement(pNode);
844  RetValue = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode) );
845  return fCompl ^ RetValue;
846 }
847 
848 
849 /**Function*************************************************************
850 
851  Synopsis [Saves the counter example.]
852 
853  Description []
854 
855  SideEffects []
856 
857  SeeAlso []
858 
859 ***********************************************************************/
861 {
862  int * pModel;
863  int iPattern;
864  int i, fCompl;
865 
866  // the node can be complemented
867  fCompl = Fraig_IsComplement(pNode);
868  // because we compare with constant 0, p->pConst1 should also be complemented
869  fCompl = !fCompl;
870 
871  // derive the model
872  pModel = Fraig_ManAllocCounterExample( p );
873  iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->nWordsRand, 1 );
874  if ( iPattern >= 0 )
875  {
876  for ( i = 0; i < p->vInputs->nSize; i++ )
877  if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimR, iPattern ) )
878  pModel[i] = 1;
879 /*
880 printf( "SAT solver's pattern:\n" );
881 for ( i = 0; i < p->vInputs->nSize; i++ )
882  printf( "%d", pModel[i] );
883 printf( "\n" );
884 */
885  assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) );
886  return pModel;
887  }
888  iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->iWordStart, 0 );
889  if ( iPattern >= 0 )
890  {
891  for ( i = 0; i < p->vInputs->nSize; i++ )
892  if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimD, iPattern ) )
893  pModel[i] = 1;
894 /*
895 printf( "SAT solver's pattern:\n" );
896 for ( i = 0; i < p->vInputs->nSize; i++ )
897  printf( "%d", pModel[i] );
898 printf( "\n" );
899 */
900  assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) );
901  return pModel;
902  }
903  ABC_FREE( pModel );
904  return NULL;
905 }
906 
907 
908 ////////////////////////////////////////////////////////////////////////
909 /// END OF FILE ///
910 ////////////////////////////////////////////////////////////////////////
911 
912 
914 
char * memset()
int * Fraig_ManAllocCounterExample(Fraig_Man_t *p)
Definition: fraigFeed.c:787
int Fraig_FeedBackCompress(Fraig_Man_t *p)
Definition: fraigFeed.c:278
#define FRAIG_FULL
Definition: fraigInt.h:71
#define FRAIG_WORDS_STORE
Definition: fraigInt.h:67
#define Fraig_BitStringHasBit(p, i)
Definition: fraigInt.h:81
void Fraig_NodeSetTravIdCurrent(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition: fraigUtil.c:996
void Fraig_NodeVecPush(Fraig_NodeVec_t *p, Fraig_Node_t *Entry)
Definition: fraigVec.c:189
void Fraig_NodeSimulate(Fraig_Node_t *pNode, int iWordStart, int iWordStop, int fUseRand)
Definition: fraigNode.c:226
typedefABC_NAMESPACE_HEADER_START struct Fraig_ManStruct_t_ Fraig_Man_t
INCLUDES ///.
Definition: fraig.h:40
int Fraig_ManSimulateBitNode(Fraig_Man_t *p, Fraig_Node_t *pNode, int *pModel)
Definition: fraigFeed.c:832
static Llb_Mgr_t * p
Definition: llb3Image.c:950
static void Fraig_FeedBackVerify(Fraig_Man_t *p, Fraig_Node_t *pOld, Fraig_Node_t *pNew)
Definition: fraigFeed.c:252
void Fraig_MemFixedEntryRecycle(Fraig_MemFixed_t *p, char *pEntry)
Definition: fraigMem.c:182
DECLARATIONS ///.
Definition: fraigMem.c:28
void Fraig_ManIncrementTravId(Fraig_Man_t *pMan)
Definition: fraigUtil.c:980
int Fraig_CompareSimInfo(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int iWordLast, int fUseRand)
Definition: fraigTable.c:351
Fraig_Node_t ** pBins
Definition: fraigInt.h:273
static void Fraig_ReallocateSimulationInfo(Fraig_Man_t *p)
Definition: fraigFeed.c:711
void Msat_IntVecClear(Msat_IntVec_t *p)
Definition: msatVec.c:335
static int Fraig_FeedBackInsert(Fraig_Man_t *p, int nVarsPi)
Definition: fraigFeed.c:167
static void Fraig_FeedBackCheckTable(Fraig_Man_t *p)
Definition: fraigFeed.c:636
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int Fraig_ManSimulateBitNode_rec(Fraig_Man_t *p, Fraig_Node_t *pNode)
Definition: fraigFeed.c:807
unsigned * puSimD
Definition: fraigInt.h:248
static abctime Abc_Clock()
Definition: abc_global.h:279
Fraig_Node_t * p2
Definition: fraigInt.h:233
unsigned fFeedUse
Definition: fraigInt.h:225
int nWords
Definition: abcNpn.c:127
#define Fraig_TableBinForEachEntryD(pBin, pEnt)
Definition: fraigInt.h:323
static int Fraig_GetSmallestColumn(int *pHits, int nHits)
Definition: fraigFeed.c:555
char * memmove()
int Fraig_FindFirstDiff(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int fCompl, int iWordLast, int fUseRand)
Definition: fraigTable.c:390
int Msat_IntVecReadSize(Msat_IntVec_t *p)
Definition: msatVec.c:233
void Msat_IntVecPush(Msat_IntVec_t *p, int Entry)
Definition: msatVec.c:351
unsigned * puSimR
Definition: fraigInt.h:247
#define Fraig_TableBinForEachEntryF(pBin, pEnt)
Definition: fraigInt.h:312
void Fraig_FeedBackInit(Fraig_Man_t *p)
FUNCTION DEFINITIONS ///.
Definition: fraigFeed.c:57
#define FRAIG_RANDOM_UNSIGNED
Definition: fraigInt.h:76
#define Fraig_BitStringSetBit(p, i)
Definition: fraigInt.h:79
void Fraig_NodeVecFree(Fraig_NodeVec_t *p)
Definition: fraigVec.c:66
Fraig_NodeVec_t * Fraig_NodeVecAlloc(int nCap)
DECLARATIONS ///.
Definition: fraigVec.c:43
int Fraig_CompareSimInfoUnderMask(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int iWordLast, int fUseRand, unsigned *puMask)
Definition: fraigTable.c:451
static void Fraig_FeedBackCheckTableF0(Fraig_Man_t *p)
Definition: fraigFeed.c:674
static void Fraig_FeedBackCovering(Fraig_Man_t *p, Msat_IntVec_t *vPats)
Definition: fraigFeed.c:386
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
if(last==0)
Definition: sparse_int.h:34
Fraig_Node_t * p1
Definition: fraigInt.h:232
static ABC_NAMESPACE_IMPL_START int Fraig_FeedBackPrepare(Fraig_Man_t *p, int *pModel, Msat_IntVec_t *vVars)
DECLARATIONS ///.
Definition: fraigFeed.c:125
int Msat_IntVecReadEntry(Msat_IntVec_t *p, int i)
Definition: msatVec.c:249
int Fraig_NodeIsAnd(Fraig_Node_t *p)
Definition: fraigApi.c:153
int Fraig_NodeIsTravIdCurrent(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition: fraigUtil.c:1012
#define FRAIG_NUM_WORDS(n)
Definition: fraigInt.h:72
static Fraig_NodeVec_t * Fraig_FeedBackCoveringStart(Fraig_Man_t *pMan)
Definition: fraigFeed.c:449
int * Fraig_ManSaveCounterExample(Fraig_Man_t *p, Fraig_Node_t *pNode)
Definition: fraigFeed.c:860
Msat_IntVec_t * Msat_IntVecAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: msatVec.c:48
static void Fraig_CancelCoveredColumns(Fraig_NodeVec_t *vColumns, int *pHits, int iPat)
Definition: fraigFeed.c:612
#define Fraig_BitStringXorBit(p, i)
Definition: fraigInt.h:80
#define Fraig_IsComplement(p)
GLOBAL VARIABLES ///.
Definition: fraig.h:107
#define MSAT_LITSIGN(l)
Definition: msat.h:58
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define FRAIG_MASK(n)
Definition: fraigInt.h:70
int Fraig_BitStringCountOnes(unsigned *pString, int nWords)
Definition: fraigUtil.c:288
unsigned fFeedVal
Definition: fraigInt.h:226
#define ABC_FREE(obj)
Definition: abc_global.h:232
Fraig_Node_t ** pArray
Definition: fraigInt.h:267
#define Fraig_Regular(p)
Definition: fraig.h:108
char * Fraig_MemFixedEntryFetch(Fraig_MemFixed_t *p)
Definition: fraigMem.c:131
int * Msat_IntVecReadArray(Msat_IntVec_t *p)
Definition: msatVec.c:217
void Fraig_MemFixedStop(Fraig_MemFixed_t *p, int fVerbose)
Definition: fraigMem.c:102
int Fraig_TableRehashF0(Fraig_Man_t *pMan, int fLinkEquiv)
Definition: fraigTable.c:604
int Fraig_NodeIsVar(Fraig_Node_t *p)
Definition: fraigApi.c:152
#define assert(ex)
Definition: util_old.h:213
void Fraig_FeedBack(Fraig_Man_t *p, int *pModel, Msat_IntVec_t *vVars, Fraig_Node_t *pOld, Fraig_Node_t *pNew)
Definition: fraigFeed.c:80
ABC_INT64_T abctime
Definition: abc_global.h:278
Fraig_MemFixed_t * Fraig_MemFixedStart(int nEntrySize)
FUNCTION DEFINITIONS ///.
Definition: fraigMem.c:63
int s_FraigPrimes[FRAIG_MAX_PRIMES]
DECLARATIONS ///.
Definition: fraigPrime.c:30
static int Fraig_GetHittingPattern(unsigned *pSims, int nWords)
Definition: fraigFeed.c:587