abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddBddCorr.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddBddCorr.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Correlation between BDDs.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_bddCorrelation()
12  <li> Cudd_bddCorrelationWeights()
13  </ul>
14  Static procedures included in this module:
15  <ul>
16  <li> bddCorrelationAux()
17  <li> bddCorrelationWeightsAux()
18  <li> CorrelCompare()
19  <li> CorrelHash()
20  <li> CorrelCleanUp()
21  </ul>
22  ]
23 
24  Author [Fabio Somenzi]
25 
26  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
27 
28  All rights reserved.
29 
30  Redistribution and use in source and binary forms, with or without
31  modification, are permitted provided that the following conditions
32  are met:
33 
34  Redistributions of source code must retain the above copyright
35  notice, this list of conditions and the following disclaimer.
36 
37  Redistributions in binary form must reproduce the above copyright
38  notice, this list of conditions and the following disclaimer in the
39  documentation and/or other materials provided with the distribution.
40 
41  Neither the name of the University of Colorado nor the names of its
42  contributors may be used to endorse or promote products derived from
43  this software without specific prior written permission.
44 
45  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
48  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
49  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
50  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
51  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
53  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
55  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56  POSSIBILITY OF SUCH DAMAGE.]
57 
58 ******************************************************************************/
59 
60 #include "misc/util/util_hack.h"
61 #include "cuddInt.h"
62 
64 
65 
66 
67 
68 /*---------------------------------------------------------------------------*/
69 /* Constant declarations */
70 /*---------------------------------------------------------------------------*/
71 
72 
73 /*---------------------------------------------------------------------------*/
74 /* Stucture declarations */
75 /*---------------------------------------------------------------------------*/
76 
77 
78 /*---------------------------------------------------------------------------*/
79 /* Type declarations */
80 /*---------------------------------------------------------------------------*/
81 
82 typedef struct hashEntry {
85 } HashEntry;
86 
87 
88 /*---------------------------------------------------------------------------*/
89 /* Variable declarations */
90 /*---------------------------------------------------------------------------*/
91 
92 #ifndef lint
93 static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.14 2004/08/13 18:04:46 fabio Exp $";
94 #endif
95 
96 #ifdef CORREL_STATS
97 static int num_calls;
98 #endif
99 
100 /*---------------------------------------------------------------------------*/
101 /* Macro declarations */
102 /*---------------------------------------------------------------------------*/
103 
104 #ifdef __cplusplus
105 extern "C" {
106 #endif
107 
108 /**AutomaticStart*************************************************************/
109 
110 /*---------------------------------------------------------------------------*/
111 /* Static function prototypes */
112 /*---------------------------------------------------------------------------*/
113 
114 static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st__table *table);
115 static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st__table *table);
116 static int CorrelCompare (const char *key1, const char *key2);
117 static int CorrelHash (const char *key, int modulus);
118 static enum st__retval CorrelCleanUp (char *key, char *value, char *arg);
119 
120 /**AutomaticEnd***************************************************************/
121 
122 #ifdef __cplusplus
123 }
124 #endif
125 
126 
127 /*---------------------------------------------------------------------------*/
128 /* Definition of exported functions */
129 /*---------------------------------------------------------------------------*/
130 
131 
132 /**Function********************************************************************
133 
134  Synopsis [Computes the correlation of f and g.]
135 
136  Description [Computes the correlation of f and g. If f == g, their
137  correlation is 1. If f == g', their correlation is 0. Returns the
138  fraction of minterms in the ON-set of the EXNOR of f and g. If it
139  runs out of memory, returns (double)CUDD_OUT_OF_MEM.]
140 
141  SideEffects [None]
142 
143  SeeAlso [Cudd_bddCorrelationWeights]
144 
145 ******************************************************************************/
146 double
148  DdManager * manager,
149  DdNode * f,
150  DdNode * g)
151 {
152 
153  st__table *table;
154  double correlation;
155 
156 #ifdef CORREL_STATS
157  num_calls = 0;
158 #endif
159 
161  if (table == NULL) return((double)CUDD_OUT_OF_MEM);
162  correlation = bddCorrelationAux(manager,f,g,table);
163  st__foreach(table, CorrelCleanUp, NIL(char));
164  st__free_table(table);
165  return(correlation);
166 
167 } /* end of Cudd_bddCorrelation */
168 
169 
170 /**Function********************************************************************
171 
172  Synopsis [Computes the correlation of f and g for given input
173  probabilities.]
174 
175  Description [Computes the correlation of f and g for given input
176  probabilities. On input, prob\[i\] is supposed to contain the
177  probability of the i-th input variable to be 1.
178  If f == g, their correlation is 1. If f == g', their
179  correlation is 0. Returns the probability that f and g have the same
180  value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The
181  correlation of f and the constant one gives the probability of f.]
182 
183  SideEffects [None]
184 
185  SeeAlso [Cudd_bddCorrelation]
186 
187 ******************************************************************************/
188 double
190  DdManager * manager,
191  DdNode * f,
192  DdNode * g,
193  double * prob)
194 {
195 
196  st__table *table;
197  double correlation;
198 
199 #ifdef CORREL_STATS
200  num_calls = 0;
201 #endif
202 
204  if (table == NULL) return((double)CUDD_OUT_OF_MEM);
205  correlation = bddCorrelationWeightsAux(manager,f,g,prob,table);
206  st__foreach(table, CorrelCleanUp, NIL(char));
207  st__free_table(table);
208  return(correlation);
209 
210 } /* end of Cudd_bddCorrelationWeights */
211 
212 
213 /*---------------------------------------------------------------------------*/
214 /* Definition of internal functions */
215 /*---------------------------------------------------------------------------*/
216 
217 
218 /*---------------------------------------------------------------------------*/
219 /* Definition of static functions */
220 /*---------------------------------------------------------------------------*/
221 
222 
223 /**Function********************************************************************
224 
225  Synopsis [Performs the recursive step of Cudd_bddCorrelation.]
226 
227  Description [Performs the recursive step of Cudd_bddCorrelation.
228  Returns the fraction of minterms in the ON-set of the EXNOR of f and
229  g.]
230 
231  SideEffects [None]
232 
233  SeeAlso [bddCorrelationWeightsAux]
234 
235 ******************************************************************************/
236 static double
238  DdManager * dd,
239  DdNode * f,
240  DdNode * g,
241  st__table * table)
242 {
243  DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
244  double min, *pmin, min1, min2, *dummy;
245  HashEntry *entry;
246  unsigned int topF, topG;
247 
248  statLine(dd);
249 #ifdef CORREL_STATS
250  num_calls++;
251 #endif
252 
253  /* Terminal cases: only work for BDDs. */
254  if (f == g) return(1.0);
255  if (f == Cudd_Not(g)) return(0.0);
256 
257  /* Standardize call using the following properties:
258  ** (f EXNOR g) = (g EXNOR f)
259  ** (f' EXNOR g') = (f EXNOR g).
260  */
261  if (cuddF2L(f) > cuddF2L(g)) {
262  DdNode *tmp = f;
263  f = g; g = tmp;
264  }
265  if (Cudd_IsComplement(f)) {
266  f = Cudd_Not(f);
267  g = Cudd_Not(g);
268  }
269  /* From now on, f is regular. */
270 
271  entry = ABC_ALLOC(HashEntry,1);
272  if (entry == NULL) {
274  return(CUDD_OUT_OF_MEM);
275  }
276  entry->f = f; entry->g = g;
277 
278  /* We do not use the fact that
279  ** correlation(f,g') = 1 - correlation(f,g)
280  ** to minimize the risk of cancellation.
281  */
282  if ( st__lookup(table, (const char *)entry, (char **)&dummy)) {
283  min = *dummy;
284  ABC_FREE(entry);
285  return(min);
286  }
287 
288  G = Cudd_Regular(g);
289  topF = cuddI(dd,f->index); topG = cuddI(dd,G->index);
290  if (topF <= topG) { Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; }
291  if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; }
292 
293  if (g != G) {
294  Gv = Cudd_Not(Gv);
295  Gnv = Cudd_Not(Gnv);
296  }
297 
298  min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0;
299  if (min1 == (double)CUDD_OUT_OF_MEM) {
300  ABC_FREE(entry);
301  return(CUDD_OUT_OF_MEM);
302  }
303  min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0;
304  if (min2 == (double)CUDD_OUT_OF_MEM) {
305  ABC_FREE(entry);
306  return(CUDD_OUT_OF_MEM);
307  }
308  min = (min1+min2);
309 
310  pmin = ABC_ALLOC(double,1);
311  if (pmin == NULL) {
313  return((double)CUDD_OUT_OF_MEM);
314  }
315  *pmin = min;
316 
317  if ( st__insert(table,(char *)entry, (char *)pmin) == st__OUT_OF_MEM) {
318  ABC_FREE(entry);
319  ABC_FREE(pmin);
320  return((double)CUDD_OUT_OF_MEM);
321  }
322  return(min);
323 
324 } /* end of bddCorrelationAux */
325 
326 
327 /**Function********************************************************************
328 
329  Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.]
330 
331  Description []
332 
333  SideEffects [None]
334 
335  SeeAlso [bddCorrelationAux]
336 
337 ******************************************************************************/
338 static double
340  DdManager * dd,
341  DdNode * f,
342  DdNode * g,
343  double * prob,
344  st__table * table)
345 {
346  DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
347  double min, *pmin, min1, min2, *dummy;
348  HashEntry *entry;
349  int topF, topG, index;
350 
351  statLine(dd);
352 #ifdef CORREL_STATS
353  num_calls++;
354 #endif
355 
356  /* Terminal cases: only work for BDDs. */
357  if (f == g) return(1.0);
358  if (f == Cudd_Not(g)) return(0.0);
359 
360  /* Standardize call using the following properties:
361  ** (f EXNOR g) = (g EXNOR f)
362  ** (f' EXNOR g') = (f EXNOR g).
363  */
364  if (cuddF2L(f) > cuddF2L(g)) {
365  DdNode *tmp = f;
366  f = g; g = tmp;
367  }
368  if (Cudd_IsComplement(f)) {
369  f = Cudd_Not(f);
370  g = Cudd_Not(g);
371  }
372  /* From now on, f is regular. */
373 
374  entry = ABC_ALLOC(HashEntry,1);
375  if (entry == NULL) {
377  return((double)CUDD_OUT_OF_MEM);
378  }
379  entry->f = f; entry->g = g;
380 
381  /* We do not use the fact that
382  ** correlation(f,g') = 1 - correlation(f,g)
383  ** to minimize the risk of cancellation.
384  */
385  if ( st__lookup(table, (const char *)entry, (char **)&dummy)) {
386  min = *dummy;
387  ABC_FREE(entry);
388  return(min);
389  }
390 
391  G = Cudd_Regular(g);
392  topF = cuddI(dd,f->index); topG = cuddI(dd,G->index);
393  if (topF <= topG) {
394  Fv = cuddT(f); Fnv = cuddE(f);
395  index = f->index;
396  } else {
397  Fv = Fnv = f;
398  index = G->index;
399  }
400  if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; }
401 
402  if (g != G) {
403  Gv = Cudd_Not(Gv);
404  Gnv = Cudd_Not(Gnv);
405  }
406 
407  min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index];
408  if (min1 == (double)CUDD_OUT_OF_MEM) {
409  ABC_FREE(entry);
410  return((double)CUDD_OUT_OF_MEM);
411  }
412  min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]);
413  if (min2 == (double)CUDD_OUT_OF_MEM) {
414  ABC_FREE(entry);
415  return((double)CUDD_OUT_OF_MEM);
416  }
417  min = (min1+min2);
418 
419  pmin = ABC_ALLOC(double,1);
420  if (pmin == NULL) {
422  return((double)CUDD_OUT_OF_MEM);
423  }
424  *pmin = min;
425 
426  if ( st__insert(table,(char *)entry, (char *)pmin) == st__OUT_OF_MEM) {
427  ABC_FREE(entry);
428  ABC_FREE(pmin);
429  return((double)CUDD_OUT_OF_MEM);
430  }
431  return(min);
432 
433 } /* end of bddCorrelationWeightsAux */
434 
435 
436 /**Function********************************************************************
437 
438  Synopsis [Compares two hash table entries.]
439 
440  Description [Compares two hash table entries. Returns 0 if they are
441  identical; 1 otherwise.]
442 
443  SideEffects [None]
444 
445 ******************************************************************************/
446 static int
448  const char * key1,
449  const char * key2)
450 {
451  HashEntry *entry1;
452  HashEntry *entry2;
453 
454  entry1 = (HashEntry *) key1;
455  entry2 = (HashEntry *) key2;
456  if (entry1->f != entry2->f || entry1->g != entry2->g) return(1);
457 
458  return(0);
459 
460 } /* end of CorrelCompare */
461 
462 
463 /**Function********************************************************************
464 
465  Synopsis [Hashes a hash table entry.]
466 
467  Description [Hashes a hash table entry. It is patterned after
468  st__strhash. Returns a value between 0 and modulus.]
469 
470  SideEffects [None]
471 
472 ******************************************************************************/
473 static int
475  const char * key,
476  int modulus)
477 {
478  HashEntry *entry;
479  int val = 0;
480 
481  entry = (HashEntry *) key;
482 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
483  val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g));
484 #else
485  val = ((int) entry->f)*997 + ((int) entry->g);
486 #endif
487 
488  return ((val < 0) ? -val : val) % modulus;
489 
490 } /* end of CorrelHash */
491 
492 
493 /**Function********************************************************************
494 
495  Synopsis [Frees memory associated with hash table.]
496 
497  Description [Frees memory associated with hash table. Returns
498  st__CONTINUE.]
499 
500  SideEffects [None]
501 
502 ******************************************************************************/
503 static enum st__retval
505  char * key,
506  char * value,
507  char * arg)
508 {
509  double *d;
510  HashEntry *entry;
511 
512  entry = (HashEntry *) key;
513  ABC_FREE(entry);
514  d = (double *)value;
515  ABC_FREE(d);
516  return st__CONTINUE;
517 
518 } /* end of CorrelCleanUp */
519 
520 
522 
523 
static double bddCorrelationAux(DdManager *dd, DdNode *f, DdNode *g, st__table *table)
Definition: cuddBddCorr.c:237
void st__free_table(st__table *table)
Definition: st.c:81
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
static int CorrelCompare(const char *key1, const char *key2)
Definition: cuddBddCorr.c:447
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
static double bddCorrelationWeightsAux(DdManager *dd, DdNode *f, DdNode *g, double *prob, st__table *table)
Definition: cuddBddCorr.c:339
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * f
Definition: cuddBddCorr.c:83
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define statLine(dd)
Definition: cuddInt.h:1037
double Cudd_bddCorrelationWeights(DdManager *manager, DdNode *f, DdNode *g, double *prob)
Definition: cuddBddCorr.c:189
#define NIL(type)
Definition: avl.h:25
static int * entry
Definition: cuddGroup.c:122
st__retval
Definition: st.h:73
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode * g
Definition: cuddBddCorr.c:84
Definition: st.h:52
static enum st__retval CorrelCleanUp(char *key, char *value, char *arg)
Definition: cuddBddCorr.c:504
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddF2L(f)
Definition: cuddInt.h:718
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
double Cudd_bddCorrelation(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddCorr.c:147
#define cuddT(node)
Definition: cuddInt.h:636
#define st__OUT_OF_MEM
Definition: st.h:113
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define cuddI(dd, index)
Definition: cuddInt.h:686
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
enum keys key
#define cuddE(node)
Definition: cuddInt.h:652
int value
static int CorrelHash(const char *key, int modulus)
Definition: cuddBddCorr.c:474
ABC_NAMESPACE_IMPL_START struct hashEntry HashEntry
static char rcsid[] DD_UNUSED
Definition: cuddBddCorr.c:93
Cudd_ErrorType errorCode
Definition: cuddInt.h:447