1 /**CFile***********************************************************************
3 FileName [cuddBddCorr.c]
7 Synopsis [Correlation between BDDs.]
9 Description [External procedures included in this module:
11 <li> Cudd_bddCorrelation()
12 <li> Cudd_bddCorrelationWeights()
14 Static procedures included in this module:
16 <li> bddCorrelationAux()
17 <li> bddCorrelationWeightsAux()
24 Author [Fabio Somenzi]
26 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
30 Redistribution and use in source and binary forms, with or without
31 modification, are permitted provided that the following conditions
34 Redistributions of source code must retain the above copyright
35 notice, this list of conditions and the following disclaimer.
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.
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.
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.]
58 ******************************************************************************/
64 /*---------------------------------------------------------------------------*/
65 /* Constant declarations */
66 /*---------------------------------------------------------------------------*/
69 /*---------------------------------------------------------------------------*/
70 /* Stucture declarations */
71 /*---------------------------------------------------------------------------*/
74 /*---------------------------------------------------------------------------*/
75 /* Type declarations */
76 /*---------------------------------------------------------------------------*/
78 typedef struct hashEntry
{
84 /*---------------------------------------------------------------------------*/
85 /* Variable declarations */
86 /*---------------------------------------------------------------------------*/
89 static char rcsid
[] DD_UNUSED
= "$Id: cuddBddCorr.c,v 1.14 2004/08/13 18:04:46 fabio Exp $";
96 /*---------------------------------------------------------------------------*/
97 /* Macro declarations */
98 /*---------------------------------------------------------------------------*/
104 /**AutomaticStart*************************************************************/
106 /*---------------------------------------------------------------------------*/
107 /* Static function prototypes */
108 /*---------------------------------------------------------------------------*/
110 static double bddCorrelationAux (DdManager
*dd
, DdNode
*f
, DdNode
*g
, st_table
*table
);
111 static double bddCorrelationWeightsAux (DdManager
*dd
, DdNode
*f
, DdNode
*g
, double *prob
, st_table
*table
);
112 static int CorrelCompare (const char *key1
, const char *key2
);
113 static int CorrelHash (char *key
, int modulus
);
114 static enum st_retval
CorrelCleanUp (char *key
, char *value
, char *arg
);
116 /**AutomaticEnd***************************************************************/
123 /*---------------------------------------------------------------------------*/
124 /* Definition of exported functions */
125 /*---------------------------------------------------------------------------*/
128 /**Function********************************************************************
130 Synopsis [Computes the correlation of f and g.]
132 Description [Computes the correlation of f and g. If f == g, their
133 correlation is 1. If f == g', their correlation is 0. Returns the
134 fraction of minterms in the ON-set of the EXNOR of f and g. If it
135 runs out of memory, returns (double)CUDD_OUT_OF_MEM.]
139 SeeAlso [Cudd_bddCorrelationWeights]
141 ******************************************************************************/
156 table
= st_init_table(CorrelCompare
,CorrelHash
);
157 if (table
== NULL
) return((double)CUDD_OUT_OF_MEM
);
158 correlation
= bddCorrelationAux(manager
,f
,g
,table
);
159 st_foreach(table
, CorrelCleanUp
, NIL(char));
160 st_free_table(table
);
163 } /* end of Cudd_bddCorrelation */
166 /**Function********************************************************************
168 Synopsis [Computes the correlation of f and g for given input
171 Description [Computes the correlation of f and g for given input
172 probabilities. On input, prob\[i\] is supposed to contain the
173 probability of the i-th input variable to be 1.
174 If f == g, their correlation is 1. If f == g', their
175 correlation is 0. Returns the probability that f and g have the same
176 value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The
177 correlation of f and the constant one gives the probability of f.]
181 SeeAlso [Cudd_bddCorrelation]
183 ******************************************************************************/
185 Cudd_bddCorrelationWeights(
199 table
= st_init_table(CorrelCompare
,CorrelHash
);
200 if (table
== NULL
) return((double)CUDD_OUT_OF_MEM
);
201 correlation
= bddCorrelationWeightsAux(manager
,f
,g
,prob
,table
);
202 st_foreach(table
, CorrelCleanUp
, NIL(char));
203 st_free_table(table
);
206 } /* end of Cudd_bddCorrelationWeights */
209 /*---------------------------------------------------------------------------*/
210 /* Definition of internal functions */
211 /*---------------------------------------------------------------------------*/
214 /*---------------------------------------------------------------------------*/
215 /* Definition of static functions */
216 /*---------------------------------------------------------------------------*/
219 /**Function********************************************************************
221 Synopsis [Performs the recursive step of Cudd_bddCorrelation.]
223 Description [Performs the recursive step of Cudd_bddCorrelation.
224 Returns the fraction of minterms in the ON-set of the EXNOR of f and
229 SeeAlso [bddCorrelationWeightsAux]
231 ******************************************************************************/
239 DdNode
*Fv
, *Fnv
, *G
, *Gv
, *Gnv
;
240 double min
, *pmin
, min1
, min2
, *dummy
;
242 unsigned int topF
, topG
;
249 /* Terminal cases: only work for BDDs. */
250 if (f
== g
) return(1.0);
251 if (f
== Cudd_Not(g
)) return(0.0);
253 /* Standardize call using the following properties:
254 ** (f EXNOR g) = (g EXNOR f)
255 ** (f' EXNOR g') = (f EXNOR g).
261 if (Cudd_IsComplement(f
)) {
265 /* From now on, f is regular. */
267 entry
= ALLOC(HashEntry
,1);
269 dd
->errorCode
= CUDD_MEMORY_OUT
;
270 return(CUDD_OUT_OF_MEM
);
272 entry
->f
= f
; entry
->g
= g
;
274 /* We do not use the fact that
275 ** correlation(f,g') = 1 - correlation(f,g)
276 ** to minimize the risk of cancellation.
278 if (st_lookup(table
, entry
, &dummy
)) {
285 topF
= cuddI(dd
,f
->index
); topG
= cuddI(dd
,G
->index
);
286 if (topF
<= topG
) { Fv
= cuddT(f
); Fnv
= cuddE(f
); } else { Fv
= Fnv
= f
; }
287 if (topG
<= topF
) { Gv
= cuddT(G
); Gnv
= cuddE(G
); } else { Gv
= Gnv
= G
; }
294 min1
= bddCorrelationAux(dd
, Fv
, Gv
, table
) / 2.0;
295 if (min1
== (double)CUDD_OUT_OF_MEM
) {
297 return(CUDD_OUT_OF_MEM
);
299 min2
= bddCorrelationAux(dd
, Fnv
, Gnv
, table
) / 2.0;
300 if (min2
== (double)CUDD_OUT_OF_MEM
) {
302 return(CUDD_OUT_OF_MEM
);
306 pmin
= ALLOC(double,1);
308 dd
->errorCode
= CUDD_MEMORY_OUT
;
309 return((double)CUDD_OUT_OF_MEM
);
313 if (st_insert(table
,(char *)entry
, (char *)pmin
) == ST_OUT_OF_MEM
) {
316 return((double)CUDD_OUT_OF_MEM
);
320 } /* end of bddCorrelationAux */
323 /**Function********************************************************************
325 Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.]
331 SeeAlso [bddCorrelationAux]
333 ******************************************************************************/
335 bddCorrelationWeightsAux(
342 DdNode
*Fv
, *Fnv
, *G
, *Gv
, *Gnv
;
343 double min
, *pmin
, min1
, min2
, *dummy
;
345 int topF
, topG
, index
;
352 /* Terminal cases: only work for BDDs. */
353 if (f
== g
) return(1.0);
354 if (f
== Cudd_Not(g
)) return(0.0);
356 /* Standardize call using the following properties:
357 ** (f EXNOR g) = (g EXNOR f)
358 ** (f' EXNOR g') = (f EXNOR g).
364 if (Cudd_IsComplement(f
)) {
368 /* From now on, f is regular. */
370 entry
= ALLOC(HashEntry
,1);
372 dd
->errorCode
= CUDD_MEMORY_OUT
;
373 return((double)CUDD_OUT_OF_MEM
);
375 entry
->f
= f
; entry
->g
= g
;
377 /* We do not use the fact that
378 ** correlation(f,g') = 1 - correlation(f,g)
379 ** to minimize the risk of cancellation.
381 if (st_lookup(table
, entry
, &dummy
)) {
388 topF
= cuddI(dd
,f
->index
); topG
= cuddI(dd
,G
->index
);
390 Fv
= cuddT(f
); Fnv
= cuddE(f
);
396 if (topG
<= topF
) { Gv
= cuddT(G
); Gnv
= cuddE(G
); } else { Gv
= Gnv
= G
; }
403 min1
= bddCorrelationWeightsAux(dd
, Fv
, Gv
, prob
, table
) * prob
[index
];
404 if (min1
== (double)CUDD_OUT_OF_MEM
) {
406 return((double)CUDD_OUT_OF_MEM
);
408 min2
= bddCorrelationWeightsAux(dd
, Fnv
, Gnv
, prob
, table
) * (1.0 - prob
[index
]);
409 if (min2
== (double)CUDD_OUT_OF_MEM
) {
411 return((double)CUDD_OUT_OF_MEM
);
415 pmin
= ALLOC(double,1);
417 dd
->errorCode
= CUDD_MEMORY_OUT
;
418 return((double)CUDD_OUT_OF_MEM
);
422 if (st_insert(table
,(char *)entry
, (char *)pmin
) == ST_OUT_OF_MEM
) {
425 return((double)CUDD_OUT_OF_MEM
);
429 } /* end of bddCorrelationWeightsAux */
432 /**Function********************************************************************
434 Synopsis [Compares two hash table entries.]
436 Description [Compares two hash table entries. Returns 0 if they are
437 identical; 1 otherwise.]
441 ******************************************************************************/
450 entry1
= (HashEntry
*) key1
;
451 entry2
= (HashEntry
*) key2
;
452 if (entry1
->f
!= entry2
->f
|| entry1
->g
!= entry2
->g
) return(1);
456 } /* end of CorrelCompare */
459 /**Function********************************************************************
461 Synopsis [Hashes a hash table entry.]
463 Description [Hashes a hash table entry. It is patterned after
464 st_strhash. Returns a value between 0 and modulus.]
468 ******************************************************************************/
477 entry
= (HashEntry
*) key
;
478 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
479 val
= ((int) ((long)entry
->f
))*997 + ((int) ((long)entry
->g
));
481 val
= ((int) entry
->f
)*997 + ((int) entry
->g
);
484 return ((val
< 0) ? -val
: val
) % modulus
;
486 } /* end of CorrelHash */
489 /**Function********************************************************************
491 Synopsis [Frees memory associated with hash table.]
493 Description [Frees memory associated with hash table. Returns
498 ******************************************************************************/
499 static enum st_retval
508 entry
= (HashEntry
*) key
;
514 } /* end of CorrelCleanUp */