abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cloud.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [cloudCore.c]
4 
5  PackageName [Fast application-specific BDD package.]
6 
7  Synopsis [The package core.]
8 
9  Author [Alan Mishchenko <alanmi@ece.pdx.edu>]
10 
11  Affiliation [ECE Department. Portland State University, Portland, Oregon.]
12 
13  Date [Ver. 1.0. Started - June 10, 2002.]
14 
15  Revision [$Id: cloudCore.c,v 1.0 2002/06/10 03:00:00 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include <string.h>
20 #include "cloud.h"
21 
23 
24 
25 // the number of operators using cache
26 static int CacheOperNum = 4;
27 
28 // the ratio of cache size to the unique table size for each operator
29 static int CacheLogRatioDefault[4] = {
30  2, // CLOUD_OPER_AND,
31  8, // CLOUD_OPER_XOR,
32  8, // CLOUD_OPER_BDIFF,
33  8 // CLOUD_OPER_LEQ
34 };
35 
36 // the ratio of cache size to the unique table size for each operator
37 static int CacheSize[4] = {
38  2, // CLOUD_OPER_AND,
39  2, // CLOUD_OPER_XOR,
40  2, // CLOUD_OPER_BDIFF,
41  2 // CLOUD_OPER_LEQ
42 };
43 
44 ////////////////////////////////////////////////////////////////////////
45 /// FUNCTION DECLARATIONS ///
46 ////////////////////////////////////////////////////////////////////////
47 
48 // static functions
49 static CloudNode * cloudMakeNode( CloudManager * dd, CloudVar v, CloudNode * t, CloudNode * e );
50 static void cloudCacheAllocate( CloudManager * dd, CloudOper oper );
51 
52 ////////////////////////////////////////////////////////////////////////
53 /// FUNCTION DEFINITIONS ///
54 ////////////////////////////////////////////////////////////////////////
55 
56 /**Function********************************************************************
57 
58  Synopsis [Starts the cloud manager.]
59 
60  Description [The first arguments is the number of elementary variables used.
61  The second arguments is the number of bits of the unsigned integer used to
62  represent nodes in the unique table. If the second argument is 0, the package
63  assumes 23 to represent nodes, which is equivalent to 2^23 = 8,388,608 nodes.]
64 
65  SideEffects []
66 
67  SeeAlso []
68 
69 ******************************************************************************/
70 CloudManager * Cloud_Init( int nVars, int nBits )
71 {
72  CloudManager * dd;
73  int i;
74  abctime clk1, clk2;
75 
76  assert( nVars <= 100000 );
77  assert( nBits < 32 );
78 
79  // assign the defaults
80  if ( nBits == 0 )
81  nBits = CLOUD_NODE_BITS;
82 
83  // start the manager
84  dd = ABC_CALLOC( CloudManager, 1 );
85  dd->nMemUsed += sizeof(CloudManager);
86 
87  // variables
88  dd->nVars = nVars; // the number of variables allocated
89  // bits
90  dd->bitsNode = nBits; // the number of bits used for the node
91  for ( i = 0; i < CacheOperNum; i++ )
92  dd->bitsCache[i] = nBits - CacheLogRatioDefault[i];
93  // shifts
94  dd->shiftUnique = 8*sizeof(unsigned) - (nBits + 1); // gets node index in the hash table
95  for ( i = 0; i < CacheOperNum; i++ )
96  dd->shiftCache[i] = 8*sizeof(unsigned) - dd->bitsCache[i];
97  // nodes
98  dd->nNodesAlloc = (1 << (nBits + 1)); // 2 ^ (nBits + 1)
99  dd->nNodesLimit = (1 << nBits); // 2 ^ nBits
100 
101  // unique table
102 clk1 = Abc_Clock();
103  dd->tUnique = ABC_CALLOC( CloudNode, dd->nNodesAlloc );
104  dd->nMemUsed += sizeof(CloudNode) * dd->nNodesAlloc;
105 clk2 = Abc_Clock();
106 //ABC_PRT( "calloc() time", clk2 - clk1 );
107 
108  // set up the constant node (the only node that is not in the hash table)
109  dd->nSignCur = 1;
110  dd->tUnique[0].s = dd->nSignCur;
111  dd->tUnique[0].v = CLOUD_CONST_INDEX;
112  dd->tUnique[0].e = NULL;
113  dd->tUnique[0].t = NULL;
114  dd->one = dd->tUnique;
115  dd->zero = Cloud_Not(dd->one);
116  dd->nNodesCur = 1;
117 
118  // special nodes
119  dd->pNodeStart = dd->tUnique + 1;
120  dd->pNodeEnd = dd->tUnique + dd->nNodesAlloc;
121 
122  // set up the elementary variables
123  dd->vars = ABC_ALLOC( CloudNode *, dd->nVars );
124  dd->nMemUsed += sizeof(CloudNode *) * dd->nVars;
125  for ( i = 0; i < dd->nVars; i++ )
126  dd->vars[i] = cloudMakeNode( dd, i, dd->one, dd->zero );
127 
128  return dd;
129 };
130 
131 /**Function********************************************************************
132 
133  Synopsis [Stops the cloud manager.]
134 
135  Description [The first arguments tells show many elementary variables are used.
136  The second arguments tells how many bits of the unsigned integer are used
137  to represent regular nodes in the unique table.]
138 
139  SideEffects []
140 
141  SeeAlso []
142 
143 ******************************************************************************/
145 {
146  int i;
147  ABC_FREE( dd->ppNodes );
148  ABC_FREE( dd->tUnique );
149  ABC_FREE( dd->vars );
150  for ( i = 0; i < 4; i++ )
151  ABC_FREE( dd->tCaches[i] );
152  ABC_FREE( dd );
153 }
154 
155 /**Function********************************************************************
156 
157  Synopsis [Prepares the manager for another run.]
158 
159  Description []
160 
161  SideEffects []
162 
163  SeeAlso []
164 
165 ******************************************************************************/
167 {
168  int i;
169  assert( dd->one->s == dd->nSignCur );
170  dd->nSignCur++;
171  dd->one->s++;
172  for ( i = 0; i < dd->nVars; i++ )
173  dd->vars[i]->s++;
174  dd->nNodesCur = 1 + dd->nVars;
175 }
176 
177 /**Function********************************************************************
178 
179  Synopsis [This optional function allocates operation cache of the given size.]
180 
181  Description [Cache for each operation is allocated independently when the first
182  operation of the given type is performed. The user can allocate cache of his/her
183  preferred size by calling Cloud_CacheAllocate before the first operation of the
184  given type is performed, but this call is optional. Argument "logratio" gives
185  the binary logarithm of the ratio of the size of the unique table to that of cache.
186  For example, if "logratio" is equal to 3, and the unique table will be 2^3=8 times
187  larger than cache; so, if unique table is 2^23 = 8,388,608 nodes, the cache size
188  will be 2^3=8 times smaller and equal to 2^20 = 1,048,576 entries.]
189 
190  SideEffects []
191 
192  SeeAlso []
193 
194 ******************************************************************************/
195 void Cloud_CacheAllocate( CloudManager * dd, CloudOper oper, int logratio )
196 {
197  assert( logratio > 0 ); // cache cannot be larger than the unique table
198  assert( logratio < dd->bitsNode ); // cache cannot be smaller than 2 entries
199 
200  if ( logratio )
201  {
202  dd->bitsCache[oper] = dd->bitsNode - logratio;
203  dd->shiftCache[oper] = 8*sizeof(unsigned) - dd->bitsCache[oper];
204  }
205  cloudCacheAllocate( dd, oper );
206 }
207 
208 /**Function********************************************************************
209 
210  Synopsis [Internal cache allocation.]
211 
212  Description []
213 
214  SideEffects []
215 
216  SeeAlso []
217 
218 ******************************************************************************/
220 {
221  int nCacheEntries = (1 << dd->bitsCache[oper]);
222 
223  if ( CacheSize[oper] == 1 )
224  {
225  dd->tCaches[oper] = (CloudCacheEntry2 *)ABC_CALLOC( CloudCacheEntry1, nCacheEntries );
226  dd->nMemUsed += sizeof(CloudCacheEntry1) * nCacheEntries;
227  }
228  else if ( CacheSize[oper] == 2 )
229  {
230  dd->tCaches[oper] = (CloudCacheEntry2 *)ABC_CALLOC( CloudCacheEntry2, nCacheEntries );
231  dd->nMemUsed += sizeof(CloudCacheEntry2) * nCacheEntries;
232  }
233  else if ( CacheSize[oper] == 3 )
234  {
235  dd->tCaches[oper] = (CloudCacheEntry2 *)ABC_CALLOC( CloudCacheEntry3, nCacheEntries );
236  dd->nMemUsed += sizeof(CloudCacheEntry3) * nCacheEntries;
237  }
238 }
239 
240 
241 
242 /**Function********************************************************************
243 
244  Synopsis [Returns or creates a new node]
245 
246  Description [Checks the unique table for the existance of the node. If the node is
247  present, returns the node. If the node is absent, creates a new node.]
248 
249  SideEffects []
250 
251  SeeAlso []
252 
253 ******************************************************************************/
255 {
256  CloudNode * pRes;
257  CLOUD_ASSERT(t);
258  CLOUD_ASSERT(e);
259  assert( v < Cloud_V(t) && v < Cloud_V(e) ); // variable should be above in the order
260  if ( Cloud_IsComplement(t) )
261  {
262  pRes = cloudMakeNode( dd, v, Cloud_Not(t), Cloud_Not(e) );
263  if ( pRes != NULL )
264  pRes = Cloud_Not(pRes);
265  }
266  else
267  pRes = cloudMakeNode( dd, v, t, e );
268  return pRes;
269 }
270 
271 /**Function********************************************************************
272 
273  Synopsis [Returns or creates a new node]
274 
275  Description [Checks the unique table for the existance of the node. If the node is
276  present, returns the node. If the node is absent, creates a new node.]
277 
278  SideEffects []
279 
280  SeeAlso []
281 
282 ******************************************************************************/
284 {
285  CloudNode * entryUnique;
286 
287  CLOUD_ASSERT(t);
288  CLOUD_ASSERT(e);
289 
290  assert( ((int)v) >= 0 && ((int)v) < dd->nVars ); // the variable must be in the range
291  assert( v < Cloud_V(t) && v < Cloud_V(e) ); // variable should be above in the order
292  assert( !Cloud_IsComplement(t) ); // the THEN edge must not be complemented
293 
294  // make sure we are not searching for the constant node
295  assert( t && e );
296 
297  // get the unique entry
298  entryUnique = dd->tUnique + cloudHashCudd3(v, t, e, dd->shiftUnique);
299  while ( entryUnique->s == dd->nSignCur )
300  {
301  // compare the node
302  if ( entryUnique->v == v && entryUnique->t == t && entryUnique->e == e )
303  { // the node is found
304  dd->nUniqueHits++;
305  return entryUnique; // returns the node
306  }
307  // increment the hash value modulus the hash table size
308  if ( ++entryUnique - dd->tUnique == dd->nNodesAlloc )
309  entryUnique = dd->tUnique + 1;
310  // increment the number of steps through the table
311  dd->nUniqueSteps++;
312  }
313  dd->nUniqueMisses++;
314 
315  // check if the new node can be created
316  if ( ++dd->nNodesCur == dd->nNodesLimit )
317  { // initiate the restart
318  printf( "Cloud needs restart!\n" );
319 // fflush( stdout );
320 // exit(1);
321  return NULL;
322  }
323  // create the node
324  entryUnique->s = dd->nSignCur;
325  entryUnique->v = v;
326  entryUnique->t = t;
327  entryUnique->e = e;
328  return entryUnique; // returns the node
329 }
330 
331 
332 /**Function********************************************************************
333 
334  Synopsis [Performs the AND or two BDDs]
335 
336  Description []
337 
338  SideEffects []
339 
340  SeeAlso []
341 
342 ******************************************************************************/
344 {
345  CloudNode * F, * G, * r;
346  CloudCacheEntry2 * cacheEntry;
347  CloudNode * fv, * fnv, * gv, * gnv, * t, * e;
348  CloudVar var;
349 
350  assert( f <= g );
351 
352  // terminal cases
353  F = Cloud_Regular(f);
354  G = Cloud_Regular(g);
355  if ( F == G )
356  {
357  if ( f == g )
358  return f;
359  else
360  return dd->zero;
361  }
362  if ( F == dd->one )
363  {
364  if ( f == dd->one )
365  return g;
366  else
367  return f;
368  }
369 
370  // check cache
371  cacheEntry = dd->tCaches[CLOUD_OPER_AND] + cloudHashCudd2(f, g, dd->shiftCache[CLOUD_OPER_AND]);
372 // cacheEntry = dd->tCaches[CLOUD_OPER_AND] + cloudHashBuddy2(f, g, dd->shiftCache[CLOUD_OPER_AND]);
373  r = cloudCacheLookup2( cacheEntry, dd->nSignCur, f, g );
374  if ( r != NULL )
375  {
376  dd->nCacheHits++;
377  return r;
378  }
379  dd->nCacheMisses++;
380 
381 
382  // compute cofactors
383  if ( cloudV(F) <= cloudV(G) )
384  {
385  var = cloudV(F);
386  if ( Cloud_IsComplement(f) )
387  {
388  fnv = Cloud_Not(cloudE(F));
389  fv = Cloud_Not(cloudT(F));
390  }
391  else
392  {
393  fnv = cloudE(F);
394  fv = cloudT(F);
395  }
396  }
397  else
398  {
399  var = cloudV(G);
400  fv = fnv = f;
401  }
402 
403  if ( cloudV(G) <= cloudV(F) )
404  {
405  if ( Cloud_IsComplement(g) )
406  {
407  gnv = Cloud_Not(cloudE(G));
408  gv = Cloud_Not(cloudT(G));
409  }
410  else
411  {
412  gnv = cloudE(G);
413  gv = cloudT(G);
414  }
415  }
416  else
417  {
418  gv = gnv = g;
419  }
420 
421  if ( fv <= gv )
422  t = cloudBddAnd( dd, fv, gv );
423  else
424  t = cloudBddAnd( dd, gv, fv );
425 
426  if ( t == NULL )
427  return NULL;
428 
429  if ( fnv <= gnv )
430  e = cloudBddAnd( dd, fnv, gnv );
431  else
432  e = cloudBddAnd( dd, gnv, fnv );
433 
434  if ( e == NULL )
435  return NULL;
436 
437  if ( t == e )
438  r = t;
439  else
440  {
441  if ( Cloud_IsComplement(t) )
442  {
443  r = cloudMakeNode( dd, var, Cloud_Not(t), Cloud_Not(e) );
444  if ( r == NULL )
445  return NULL;
446  r = Cloud_Not(r);
447  }
448  else
449  {
450  r = cloudMakeNode( dd, var, t, e );
451  if ( r == NULL )
452  return NULL;
453  }
454  }
455  cloudCacheInsert2( cacheEntry, dd->nSignCur, f, g, r );
456  return r;
457 }
458 
459 /**Function********************************************************************
460 
461  Synopsis [Performs the AND or two BDDs]
462 
463  Description []
464 
465  SideEffects []
466 
467  SeeAlso []
468 
469 ******************************************************************************/
470 static inline CloudNode * cloudBddAnd_gate( CloudManager * dd, CloudNode * f, CloudNode * g )
471 {
472  if ( f <= g )
473  return cloudBddAnd(dd,f,g);
474  else
475  return cloudBddAnd(dd,g,f);
476 }
477 
478 /**Function********************************************************************
479 
480  Synopsis [Performs the AND or two BDDs]
481 
482  Description []
483 
484  SideEffects []
485 
486  SeeAlso []
487 
488 ******************************************************************************/
490 {
491  if ( Cloud_Regular(f) == NULL || Cloud_Regular(g) == NULL )
492  return NULL;
493  CLOUD_ASSERT(f);
494  CLOUD_ASSERT(g);
495  if ( dd->tCaches[CLOUD_OPER_AND] == NULL )
497  return cloudBddAnd_gate( dd, f, g );
498 }
499 
500 /**Function********************************************************************
501 
502  Synopsis [Performs the OR or two BDDs]
503 
504  Description []
505 
506  SideEffects []
507 
508  SeeAlso []
509 
510 ******************************************************************************/
512 {
513  CloudNode * res;
514  if ( Cloud_Regular(f) == NULL || Cloud_Regular(g) == NULL )
515  return NULL;
516  CLOUD_ASSERT(f);
517  CLOUD_ASSERT(g);
518  if ( dd->tCaches[CLOUD_OPER_AND] == NULL )
520  res = cloudBddAnd_gate( dd, Cloud_Not(f), Cloud_Not(g) );
521  res = Cloud_NotCond( res, res != NULL );
522  return res;
523 }
524 
525 /**Function********************************************************************
526 
527  Synopsis [Performs the XOR or two BDDs]
528 
529  Description []
530 
531  SideEffects []
532 
533  SeeAlso []
534 
535 ******************************************************************************/
537 {
538  CloudNode * t0, * t1, * r;
539  if ( Cloud_Regular(f) == NULL || Cloud_Regular(g) == NULL )
540  return NULL;
541  CLOUD_ASSERT(f);
542  CLOUD_ASSERT(g);
543  if ( dd->tCaches[CLOUD_OPER_AND] == NULL )
545  t0 = cloudBddAnd_gate( dd, f, Cloud_Not(g) );
546  if ( t0 == NULL )
547  return NULL;
548  t1 = cloudBddAnd_gate( dd, Cloud_Not(f), g );
549  if ( t1 == NULL )
550  return NULL;
551  r = Cloud_bddOr( dd, t0, t1 );
552  return r;
553 }
554 
555 
556 
557 /**Function********************************************************************
558 
559  Synopsis [Performs a DFS from f, clearing the LSB of the next
560  pointers.]
561 
562  Description []
563 
564  SideEffects [None]
565 
566  SeeAlso [cloudSupport cloudDagSize]
567 
568 ******************************************************************************/
569 static void cloudClearMark( CloudManager * dd, CloudNode * n )
570 {
571  if ( !cloudNodeIsMarked(n) )
572  return;
573  // clear visited flag
574  cloudNodeUnmark(n);
575  if ( cloudIsConstant(n) )
576  return;
577  cloudClearMark( dd, cloudT(n) );
579 }
580 
581 /**Function********************************************************************
582 
583  Synopsis [Performs the recursive step of Cloud_Support.]
584 
585  Description [Performs the recursive step of Cloud_Support. Performs a
586  DFS from f. The support is accumulated in supp as a side effect. Uses
587  the LSB of the then pointer as visited flag.]
588 
589  SideEffects [None]
590 
591  SeeAlso []
592 
593 ******************************************************************************/
594 static void cloudSupport( CloudManager * dd, CloudNode * n, int * support )
595 {
596  if ( cloudIsConstant(n) || cloudNodeIsMarked(n) )
597  return;
598  // set visited flag
599  cloudNodeMark(n);
600  support[cloudV(n)] = 1;
601  cloudSupport( dd, cloudT(n), support );
602  cloudSupport( dd, Cloud_Regular(cloudE(n)), support );
603 }
604 
605 /**Function********************************************************************
606 
607  Synopsis [Finds the variables on which a DD depends.]
608 
609  Description [Finds the variables on which a DD depends.
610  Returns a BDD consisting of the product of the variables if
611  successful; NULL otherwise.]
612 
613  SideEffects [None]
614 
615  SeeAlso []
616 
617 ******************************************************************************/
619 {
620  CloudNode * res;
621  int * support, i;
622 
623  CLOUD_ASSERT(n);
624 
625  // allocate and initialize support array for cloudSupport
626  support = ABC_CALLOC( int, dd->nVars );
627 
628  // compute support and clean up markers
629  cloudSupport( dd, Cloud_Regular(n), support );
630  cloudClearMark( dd, Cloud_Regular(n) );
631 
632  // transform support from array to cube
633  res = dd->one;
634  for ( i = dd->nVars - 1; i >= 0; i-- ) // for each level bottom-up
635  if ( support[i] == 1 )
636  {
637  res = Cloud_bddAnd( dd, res, dd->vars[i] );
638  if ( res == NULL )
639  break;
640  }
641  ABC_FREE( support );
642  return res;
643 }
644 
645 /**Function********************************************************************
646 
647  Synopsis [Counts the variables on which a DD depends.]
648 
649  Description [Counts the variables on which a DD depends.
650  Returns the number of the variables if successful; Cloud_OUT_OF_MEM
651  otherwise.]
652 
653  SideEffects [None]
654 
655  SeeAlso []
656 
657 ******************************************************************************/
659 {
660  int * support, i, count;
661 
662  CLOUD_ASSERT(n);
663 
664  // allocate and initialize support array for cloudSupport
665  support = ABC_CALLOC( int, dd->nVars );
666 
667  // compute support and clean up markers
668  cloudSupport( dd, Cloud_Regular(n), support );
669  cloudClearMark( dd, Cloud_Regular(n) );
670 
671  // count support variables
672  count = 0;
673  for ( i = 0; i < dd->nVars; i++ )
674  {
675  if ( support[i] == 1 )
676  count++;
677  }
678 
679  ABC_FREE( support );
680  return count;
681 }
682 
683 
684 /**Function********************************************************************
685 
686  Synopsis [Performs the recursive step of Cloud_DagSize.]
687 
688  Description [Performs the recursive step of Cloud_DagSize. Returns the
689  number of nodes in the graph rooted at n.]
690 
691  SideEffects [None]
692 
693 ******************************************************************************/
694 static int cloudDagSize( CloudManager * dd, CloudNode * n )
695 {
696  int tval, eval;
697  if ( cloudNodeIsMarked(n) )
698  return 0;
699  // set visited flag
700  cloudNodeMark(n);
701  if ( cloudIsConstant(n) )
702  return 1;
703  tval = cloudDagSize( dd, cloudT(n) );
704  eval = cloudDagSize( dd, Cloud_Regular(cloudE(n)) );
705  return tval + eval + 1;
706 
707 }
708 
709 /**Function********************************************************************
710 
711  Synopsis [Counts the number of nodes in a DD.]
712 
713  Description [Counts the number of nodes in a DD. Returns the number
714  of nodes in the graph rooted at node.]
715 
716  SideEffects []
717 
718  SeeAlso []
719 
720 ******************************************************************************/
722 {
723  int res;
724  res = cloudDagSize( dd, Cloud_Regular( n ) );
725  cloudClearMark( dd, Cloud_Regular( n ) );
726  return res;
727 
728 }
729 
730 
731 /**Function********************************************************************
732 
733  Synopsis [Performs the recursive step of Cloud_DagSize.]
734 
735  Description [Performs the recursive step of Cloud_DagSize. Returns the
736  number of nodes in the graph rooted at n.]
737 
738  SideEffects [None]
739 
740 ******************************************************************************/
741 static int Cloud_DagCollect_rec( CloudManager * dd, CloudNode * n, int * pCounter )
742 {
743  int tval, eval;
744  if ( cloudNodeIsMarked(n) )
745  return 0;
746  // set visited flag
747  cloudNodeMark(n);
748  if ( cloudIsConstant(n) )
749  {
750  dd->ppNodes[(*pCounter)++] = n;
751  return 1;
752  }
753  tval = Cloud_DagCollect_rec( dd, cloudT(n), pCounter );
754  eval = Cloud_DagCollect_rec( dd, Cloud_Regular(cloudE(n)), pCounter );
755  dd->ppNodes[(*pCounter)++] = n;
756  return tval + eval + 1;
757 
758 }
759 
760 /**Function********************************************************************
761 
762  Synopsis [Counts the number of nodes in a DD.]
763 
764  Description [Counts the number of nodes in a DD. Returns the number
765  of nodes in the graph rooted at node.]
766 
767  SideEffects []
768 
769  SeeAlso []
770 
771 ******************************************************************************/
773 {
774  int res, Counter = 0;
775  if ( dd->ppNodes == NULL )
776  dd->ppNodes = ABC_ALLOC( CloudNode *, dd->nNodesLimit );
777  res = Cloud_DagCollect_rec( dd, Cloud_Regular( n ), &Counter );
778  cloudClearMark( dd, Cloud_Regular( n ) );
779  assert( res == Counter );
780  return res;
781 
782 }
783 
784 /**Function********************************************************************
785 
786  Synopsis [Counts the number of nodes in an array of DDs.]
787 
788  Description [Counts the number of nodes in a DD. Returns the number
789  of nodes in the graph rooted at node.]
790 
791  SideEffects []
792 
793  SeeAlso []
794 
795 ******************************************************************************/
796 int Cloud_SharingSize( CloudManager * dd, CloudNode ** pn, int nn )
797 {
798  int res, i;
799  res = 0;
800  for ( i = 0; i < nn; i++ )
801  res += cloudDagSize( dd, Cloud_Regular( pn[i] ) );
802  for ( i = 0; i < nn; i++ )
803  cloudClearMark( dd, Cloud_Regular( pn[i] ) );
804  return res;
805 }
806 
807 
808 /**Function********************************************************************
809 
810  Synopsis [Returns one cube contained in the given BDD.]
811 
812  Description []
813 
814  SideEffects []
815 
816 ******************************************************************************/
818 {
819  CloudNode * bFunc0, * bFunc1, * res;
820 
821  if ( Cloud_IsConstant(bFunc) )
822  return bFunc;
823 
824  // cofactor
825  if ( Cloud_IsComplement(bFunc) )
826  {
827  bFunc0 = Cloud_Not( cloudE(bFunc) );
828  bFunc1 = Cloud_Not( cloudT(bFunc) );
829  }
830  else
831  {
832  bFunc0 = cloudE(bFunc);
833  bFunc1 = cloudT(bFunc);
834  }
835 
836  // try to find the cube with the negative literal
837  res = Cloud_GetOneCube( dd, bFunc0 );
838  if ( res == NULL )
839  return NULL;
840 
841  if ( res != dd->zero )
842  {
843  res = Cloud_bddAnd( dd, res, Cloud_Not(dd->vars[Cloud_V(bFunc)]) );
844  }
845  else
846  {
847  // try to find the cube with the positive literal
848  res = Cloud_GetOneCube( dd, bFunc1 );
849  if ( res == NULL )
850  return NULL;
851  assert( res != dd->zero );
852  res = Cloud_bddAnd( dd, res, dd->vars[Cloud_V(bFunc)] );
853  }
854  return res;
855 }
856 
857 /**Function********************************************************************
858 
859  Synopsis [Prints the BDD as a set of disjoint cubes to the standard output.]
860 
861  Description []
862 
863  SideEffects []
864 
865 ******************************************************************************/
867 {
868  CloudNode * Cube;
869  int fFirst = 1;
870 
871  if ( Func == dd->zero )
872  printf( "Constant 0." );
873  else if ( Func == dd->one )
874  printf( "Constant 1." );
875  else
876  {
877  while ( 1 )
878  {
879  Cube = Cloud_GetOneCube( dd, Func );
880  if ( Cube == NULL || Cube == dd->zero )
881  break;
882  if ( fFirst ) fFirst = 0;
883  else printf( " + " );
884  Cloud_bddPrintCube( dd, Cube );
885  Func = Cloud_bddAnd( dd, Func, Cloud_Not(Cube) );
886  }
887  }
888  printf( "\n" );
889 }
890 
891 /**Function********************************************************************
892 
893  Synopsis [Prints one cube.]
894 
895  Description []
896 
897  SideEffects []
898 
899 ******************************************************************************/
901 {
902  CloudNode * bCube0, * bCube1;
903 
904  assert( !Cloud_IsConstant(bCube) );
905  while ( 1 )
906  {
907  // get the node structure
908  if ( Cloud_IsConstant(bCube) )
909  break;
910 
911  // cofactor the cube
912  if ( Cloud_IsComplement(bCube) )
913  {
914  bCube0 = Cloud_Not( cloudE(bCube) );
915  bCube1 = Cloud_Not( cloudT(bCube) );
916  }
917  else
918  {
919  bCube0 = cloudE(bCube);
920  bCube1 = cloudT(bCube);
921  }
922 
923  if ( bCube0 != dd->zero )
924  {
925  assert( bCube1 == dd->zero );
926  printf( "[%d]'", cloudV(bCube) );
927  bCube = bCube0;
928  }
929  else
930  {
931  assert( bCube1 != dd->zero );
932  printf( "[%d]", cloudV(bCube) );
933  bCube = bCube1;
934  }
935  }
936 }
937 
938 
939 /**Function********************************************************************
940 
941  Synopsis [Prints info.]
942 
943  Description []
944 
945  SideEffects []
946 
947  SeeAlso []
948 
949 ******************************************************************************/
951 {
952  if ( dd == NULL ) return;
953  printf( "The number of unique table nodes allocated = %12d.\n", dd->nNodesAlloc );
954  printf( "The number of unique table nodes present = %12d.\n", dd->nNodesCur );
955  printf( "The number of unique table hits = %12d.\n", dd->nUniqueHits );
956  printf( "The number of unique table misses = %12d.\n", dd->nUniqueMisses );
957  printf( "The number of unique table steps = %12d.\n", dd->nUniqueSteps );
958  printf( "The number of cache hits = %12d.\n", dd->nCacheHits );
959  printf( "The number of cache misses = %12d.\n", dd->nCacheMisses );
960  printf( "The current signature = %12d.\n", dd->nSignCur );
961  printf( "The total memory in use = %12d.\n", dd->nMemUsed );
962 }
963 
964 /**Function********************************************************************
965 
966  Synopsis [Prints the state of the hash table.]
967 
968  Description []
969 
970  SideEffects []
971 
972  SeeAlso []
973 
974 ******************************************************************************/
976 {
977  int i;
978 
979  for ( i = 0; i < dd->nNodesAlloc; i++ )
980  if ( dd->tUnique[i].v == CLOUD_CONST_INDEX )
981  printf( "-" );
982  else
983  printf( "+" );
984  printf( "\n" );
985 }
986 
987 
988 ////////////////////////////////////////////////////////////////////////
989 /// END OF FILE ///
990 ////////////////////////////////////////////////////////////////////////
991 
993 
#define cloudHashCudd2(f, g, s)
Definition: cloud.h:181
unsigned CloudVar
Definition: cloud.h:53
void Cloud_Quit(CloudManager *dd)
Definition: cloud.c:144
typedefABC_NAMESPACE_HEADER_START struct cloudManager CloudManager
Definition: cloud.h:52
void Cloud_PrintInfo(CloudManager *dd)
Definition: cloud.c:950
CloudVar v
Definition: cloud.h:139
CloudManager * Cloud_Init(int nVars, int nBits)
FUNCTION DEFINITIONS ///.
Definition: cloud.c:70
#define Cloud_NotCond(p, c)
Definition: cloud.h:187
static int cloudDagSize(CloudManager *dd, CloudNode *n)
Definition: cloud.c:694
#define Cloud_IsComplement(p)
Definition: cloud.h:188
CloudNode * cloudBddAnd(CloudManager *dd, CloudNode *f, CloudNode *g)
Definition: cloud.c:343
CloudNode * Cloud_GetOneCube(CloudManager *dd, CloudNode *bFunc)
Definition: cloud.c:817
static ABC_NAMESPACE_IMPL_START int CacheOperNum
Definition: cloud.c:26
static int CacheSize[4]
Definition: cloud.c:37
int var(Lit p)
Definition: SolverTypes.h:62
int Cloud_SupportSize(CloudManager *dd, CloudNode *n)
Definition: cloud.c:658
#define CLOUD_ASSERT(p)
Definition: cloud.h:216
#define CLOUD_NODE_BITS
Definition: cloud.h:167
CloudNode * e
Definition: cloud.h:140
#define CLOUD_CONST_INDEX
Definition: cloud.h:169
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
void Cloud_CacheAllocate(CloudManager *dd, CloudOper oper, int logratio)
Definition: cloud.c:195
#define Cloud_Not(p)
Definition: cloud.h:186
static void cloudClearMark(CloudManager *dd, CloudNode *n)
Definition: cloud.c:569
CloudOper
Definition: cloud.h:61
#define Cloud_Regular(p)
Definition: cloud.h:185
static abctime Abc_Clock()
Definition: abc_global.h:279
#define cloudNodeMark(p)
Definition: cloud.h:202
void Cloud_Restart(CloudManager *dd)
Definition: cloud.c:166
CloudNode * Cloud_bddAnd(CloudManager *dd, CloudNode *f, CloudNode *g)
Definition: cloud.c:489
struct cloudCacheEntry2 CloudCacheEntry2
Definition: cloud.h:57
for(p=first;p->value< newval;p=p->next)
#define cloudV(p)
Definition: cloud.h:198
static int Cloud_DagCollect_rec(CloudManager *dd, CloudNode *n, int *pCounter)
Definition: cloud.c:741
CloudNode * Cloud_bddOr(CloudManager *dd, CloudNode *f, CloudNode *g)
Definition: cloud.c:511
void Cloud_bddPrintCube(CloudManager *dd, CloudNode *bCube)
Definition: cloud.c:900
CloudSign s
Definition: cloud.h:138
static int CacheLogRatioDefault[4]
Definition: cloud.c:29
CloudNode * Cloud_bddXor(CloudManager *dd, CloudNode *f, CloudNode *g)
Definition: cloud.c:536
struct cloudCacheEntry3 CloudCacheEntry3
Definition: cloud.h:58
#define cloudIsConstant(p)
Definition: cloud.h:191
#define cloudNodeUnmark(p)
Definition: cloud.h:203
struct cloudNode CloudNode
Definition: cloud.h:55
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
int Cloud_SharingSize(CloudManager *dd, CloudNode **pn, int nn)
Definition: cloud.c:796
CloudNode * Cloud_MakeNode(CloudManager *dd, CloudVar v, CloudNode *t, CloudNode *e)
Definition: cloud.c:254
static int Counter
CloudNode * t
Definition: cloud.h:141
void Cloud_PrintHashTable(CloudManager *dd)
Definition: cloud.c:975
#define Cloud_V(p)
Definition: cloud.h:194
static void cloudCacheAllocate(CloudManager *dd, CloudOper oper)
Definition: cloud.c:219
static void cloudSupport(CloudManager *dd, CloudNode *n, int *support)
Definition: cloud.c:594
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define cloudHashCudd3(f, g, h, s)
Definition: cloud.h:182
#define Cloud_IsConstant(p)
Definition: cloud.h:190
CloudNode * Cloud_Support(CloudManager *dd, CloudNode *n)
Definition: cloud.c:618
void Cloud_bddPrint(CloudManager *dd, CloudNode *Func)
Definition: cloud.c:866
#define cloudCacheLookup2(p, sign, f, g)
Definition: cloud.h:208
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
int Cloud_DagSize(CloudManager *dd, CloudNode *n)
Definition: cloud.c:721
#define cloudE(p)
Definition: cloud.h:199
#define assert(ex)
Definition: util_old.h:213
#define cloudNodeIsMarked(p)
Definition: cloud.h:204
struct cloudCacheEntry1 CloudCacheEntry1
Definition: cloud.h:56
ABC_INT64_T abctime
Definition: abc_global.h:278
#define cloudCacheInsert2(p, sign, f, g, r)
Definition: cloud.h:212
static CloudNode * cloudMakeNode(CloudManager *dd, CloudVar v, CloudNode *t, CloudNode *e)
FUNCTION DECLARATIONS ///.
Definition: cloud.c:283
int Cloud_DagCollect(CloudManager *dd, CloudNode *n)
Definition: cloud.c:772
static CloudNode * cloudBddAnd_gate(CloudManager *dd, CloudNode *f, CloudNode *g)
Definition: cloud.c:470
#define cloudT(p)
Definition: cloud.h:200