emergency commit
[cl-cudd.git] / distr / cudd / cuddZddCount.c
blob13514689d77ea13c644f1781ce9d91510193db40
1 /**CFile***********************************************************************
3 FileName [cuddZddCount.c]
5 PackageName [cudd]
7 Synopsis [Procedures to count the number of minterms of a ZDD.]
9 Description [External procedures included in this module:
10 <ul>
11 <li> Cudd_zddCount();
12 <li> Cudd_zddCountDouble();
13 </ul>
14 Internal procedures included in this module:
15 <ul>
16 </ul>
17 Static procedures included in this module:
18 <ul>
19 <li> cuddZddCountStep();
20 <li> cuddZddCountDoubleStep();
21 <li> st_zdd_count_dbl_free()
22 <li> st_zdd_countfree()
23 </ul>
26 SeeAlso []
28 Author [Hyong-Kyoon Shin, In-Ho Moon]
30 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
32 All rights reserved.
34 Redistribution and use in source and binary forms, with or without
35 modification, are permitted provided that the following conditions
36 are met:
38 Redistributions of source code must retain the above copyright
39 notice, this list of conditions and the following disclaimer.
41 Redistributions in binary form must reproduce the above copyright
42 notice, this list of conditions and the following disclaimer in the
43 documentation and/or other materials provided with the distribution.
45 Neither the name of the University of Colorado nor the names of its
46 contributors may be used to endorse or promote products derived from
47 this software without specific prior written permission.
49 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
52 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
53 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
54 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
55 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
57 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 POSSIBILITY OF SUCH DAMAGE.]
62 ******************************************************************************/
64 #include "util.h"
65 #include "cuddInt.h"
67 /*---------------------------------------------------------------------------*/
68 /* Constant declarations */
69 /*---------------------------------------------------------------------------*/
72 /*---------------------------------------------------------------------------*/
73 /* Stucture declarations */
74 /*---------------------------------------------------------------------------*/
77 /*---------------------------------------------------------------------------*/
78 /* Type declarations */
79 /*---------------------------------------------------------------------------*/
82 /*---------------------------------------------------------------------------*/
83 /* Variable declarations */
84 /*---------------------------------------------------------------------------*/
86 #ifndef lint
87 static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.14 2004/08/13 18:04:53 fabio Exp $";
88 #endif
90 /*---------------------------------------------------------------------------*/
91 /* Macro declarations */
92 /*---------------------------------------------------------------------------*/
94 #ifdef __cplusplus
95 extern "C" {
96 #endif
98 /**AutomaticStart*************************************************************/
100 /*---------------------------------------------------------------------------*/
101 /* Static function prototypes */
102 /*---------------------------------------------------------------------------*/
104 static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty);
105 static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty);
106 static enum st_retval st_zdd_countfree (char *key, char *value, char *arg);
107 static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg);
109 /**AutomaticEnd***************************************************************/
111 #ifdef __cplusplus
113 #endif
115 /*---------------------------------------------------------------------------*/
116 /* Definition of exported functions */
117 /*---------------------------------------------------------------------------*/
120 /**Function********************************************************************
122 Synopsis [Counts the number of minterms in a ZDD.]
124 Description [Returns an integer representing the number of minterms
125 in a ZDD.]
127 SideEffects [None]
129 SeeAlso [Cudd_zddCountDouble]
131 ******************************************************************************/
133 Cudd_zddCount(
134 DdManager * zdd,
135 DdNode * P)
137 st_table *table;
138 int res;
139 DdNode *base, *empty;
141 base = DD_ONE(zdd);
142 empty = DD_ZERO(zdd);
143 table = st_init_table(st_ptrcmp, st_ptrhash);
144 if (table == NULL) return(CUDD_OUT_OF_MEM);
145 res = cuddZddCountStep(P, table, base, empty);
146 if (res == CUDD_OUT_OF_MEM) {
147 zdd->errorCode = CUDD_MEMORY_OUT;
149 st_foreach(table, st_zdd_countfree, NIL(char));
150 st_free_table(table);
152 return(res);
154 } /* end of Cudd_zddCount */
157 /**Function********************************************************************
159 Synopsis [Counts the number of minterms of a ZDD.]
161 Description [Counts the number of minterms of a ZDD. The result is
162 returned as a double. If the procedure runs out of memory, it
163 returns (double) CUDD_OUT_OF_MEM. This procedure is used in
164 Cudd_zddCountMinterm.]
166 SideEffects [None]
168 SeeAlso [Cudd_zddCountMinterm Cudd_zddCount]
170 ******************************************************************************/
171 double
172 Cudd_zddCountDouble(
173 DdManager * zdd,
174 DdNode * P)
176 st_table *table;
177 double res;
178 DdNode *base, *empty;
180 base = DD_ONE(zdd);
181 empty = DD_ZERO(zdd);
182 table = st_init_table(st_ptrcmp, st_ptrhash);
183 if (table == NULL) return((double)CUDD_OUT_OF_MEM);
184 res = cuddZddCountDoubleStep(P, table, base, empty);
185 if (res == (double)CUDD_OUT_OF_MEM) {
186 zdd->errorCode = CUDD_MEMORY_OUT;
188 st_foreach(table, st_zdd_count_dbl_free, NIL(char));
189 st_free_table(table);
191 return(res);
193 } /* end of Cudd_zddCountDouble */
196 /*---------------------------------------------------------------------------*/
197 /* Definition of internal functions */
198 /*---------------------------------------------------------------------------*/
201 /*---------------------------------------------------------------------------*/
202 /* Definition of static functions */
203 /*---------------------------------------------------------------------------*/
206 /**Function********************************************************************
208 Synopsis [Performs the recursive step of Cudd_zddCount.]
210 Description []
212 SideEffects [None]
214 SeeAlso []
216 ******************************************************************************/
217 static int
218 cuddZddCountStep(
219 DdNode * P,
220 st_table * table,
221 DdNode * base,
222 DdNode * empty)
224 int res;
225 int *dummy;
227 if (P == empty)
228 return(0);
229 if (P == base)
230 return(1);
232 /* Check cache. */
233 if (st_lookup(table, P, &dummy)) {
234 res = *dummy;
235 return(res);
238 res = cuddZddCountStep(cuddE(P), table, base, empty) +
239 cuddZddCountStep(cuddT(P), table, base, empty);
241 dummy = ALLOC(int, 1);
242 if (dummy == NULL) {
243 return(CUDD_OUT_OF_MEM);
245 *dummy = res;
246 if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
247 FREE(dummy);
248 return(CUDD_OUT_OF_MEM);
251 return(res);
253 } /* end of cuddZddCountStep */
256 /**Function********************************************************************
258 Synopsis [Performs the recursive step of Cudd_zddCountDouble.]
260 Description []
262 SideEffects [None]
264 SeeAlso []
266 ******************************************************************************/
267 static double
268 cuddZddCountDoubleStep(
269 DdNode * P,
270 st_table * table,
271 DdNode * base,
272 DdNode * empty)
274 double res;
275 double *dummy;
277 if (P == empty)
278 return((double)0.0);
279 if (P == base)
280 return((double)1.0);
282 /* Check cache */
283 if (st_lookup(table, P, &dummy)) {
284 res = *dummy;
285 return(res);
288 res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) +
289 cuddZddCountDoubleStep(cuddT(P), table, base, empty);
291 dummy = ALLOC(double, 1);
292 if (dummy == NULL) {
293 return((double)CUDD_OUT_OF_MEM);
295 *dummy = res;
296 if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
297 FREE(dummy);
298 return((double)CUDD_OUT_OF_MEM);
301 return(res);
303 } /* end of cuddZddCountDoubleStep */
306 /**Function********************************************************************
308 Synopsis [Frees the memory associated with the computed table of
309 Cudd_zddCount.]
311 Description []
313 SideEffects [None]
315 SeeAlso []
317 ******************************************************************************/
318 static enum st_retval
319 st_zdd_countfree(
320 char * key,
321 char * value,
322 char * arg)
324 int *d;
326 d = (int *)value;
327 FREE(d);
328 return(ST_CONTINUE);
330 } /* end of st_zdd_countfree */
333 /**Function********************************************************************
335 Synopsis [Frees the memory associated with the computed table of
336 Cudd_zddCountDouble.]
338 Description []
340 SideEffects [None]
342 SeeAlso []
344 ******************************************************************************/
345 static enum st_retval
346 st_zdd_count_dbl_free(
347 char * key,
348 char * value,
349 char * arg)
351 double *d;
353 d = (double *)value;
354 FREE(d);
355 return(ST_CONTINUE);
357 } /* end of st_zdd_count_dbl_free */