abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddAddAbs.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddAddAbs.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Quantification functions for ADDs.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_addExistAbstract()
12  <li> Cudd_addUnivAbstract()
13  <li> Cudd_addOrAbstract()
14  </ul>
15  Internal procedures included in this module:
16  <ul>
17  <li> cuddAddExistAbstractRecur()
18  <li> cuddAddUnivAbstractRecur()
19  <li> cuddAddOrAbstractRecur()
20  </ul>
21  Static procedures included in this module:
22  <ul>
23  <li> addCheckPositiveCube()
24  </ul>]
25 
26  Author [Fabio Somenzi]
27 
28  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
29 
30  All rights reserved.
31 
32  Redistribution and use in source and binary forms, with or without
33  modification, are permitted provided that the following conditions
34  are met:
35 
36  Redistributions of source code must retain the above copyright
37  notice, this list of conditions and the following disclaimer.
38 
39  Redistributions in binary form must reproduce the above copyright
40  notice, this list of conditions and the following disclaimer in the
41  documentation and/or other materials provided with the distribution.
42 
43  Neither the name of the University of Colorado nor the names of its
44  contributors may be used to endorse or promote products derived from
45  this software without specific prior written permission.
46 
47  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
50  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
51  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
52  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
53  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
55  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58  POSSIBILITY OF SUCH DAMAGE.]
59 
60 ******************************************************************************/
61 
62 #include "misc/util/util_hack.h"
63 #include "cuddInt.h"
64 
66 
67 
68 
69 /*---------------------------------------------------------------------------*/
70 /* Constant declarations */
71 /*---------------------------------------------------------------------------*/
72 
73 
74 /*---------------------------------------------------------------------------*/
75 /* Stucture declarations */
76 /*---------------------------------------------------------------------------*/
77 
78 
79 /*---------------------------------------------------------------------------*/
80 /* Type declarations */
81 /*---------------------------------------------------------------------------*/
82 
83 
84 /*---------------------------------------------------------------------------*/
85 /* Variable declarations */
86 /*---------------------------------------------------------------------------*/
87 
88 #ifndef lint
89 static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.15 2004/08/13 18:04:45 fabio Exp $";
90 #endif
91 
92 static DdNode *two;
93 
94 /*---------------------------------------------------------------------------*/
95 /* Macro declarations */
96 /*---------------------------------------------------------------------------*/
97 
98 
99 /**AutomaticStart*************************************************************/
100 
101 /*---------------------------------------------------------------------------*/
102 /* Static function prototypes */
103 /*---------------------------------------------------------------------------*/
104 
105 static int addCheckPositiveCube (DdManager *manager, DdNode *cube);
106 
107 /**AutomaticEnd***************************************************************/
108 
109 
110 /*---------------------------------------------------------------------------*/
111 /* Definition of exported functions */
112 /*---------------------------------------------------------------------------*/
113 
114 /**Function********************************************************************
115 
116  Synopsis [Existentially Abstracts all the variables in cube from f.]
117 
118  Description [Abstracts all the variables in cube from f by summing
119  over all possible values taken by the variables. Returns the
120  abstracted ADD.]
121 
122  SideEffects [None]
123 
124  SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract
125  Cudd_addOrAbstract]
126 
127 ******************************************************************************/
128 DdNode *
130  DdManager * manager,
131  DdNode * f,
132  DdNode * cube)
133 {
134  DdNode *res;
135 
136  two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2);
137  if (two == NULL) return(NULL);
138  cuddRef(two);
139 
140  if (addCheckPositiveCube(manager, cube) == 0) {
141  (void) fprintf(manager->err,"Error: Can only abstract cubes");
142  return(NULL);
143  }
144 
145  do {
146  manager->reordered = 0;
147  res = cuddAddExistAbstractRecur(manager, f, cube);
148  } while (manager->reordered == 1);
149 
150  if (res == NULL) {
151  Cudd_RecursiveDeref(manager,two);
152  return(NULL);
153  }
154  cuddRef(res);
155  Cudd_RecursiveDeref(manager,two);
156  cuddDeref(res);
157 
158  return(res);
159 
160 } /* end of Cudd_addExistAbstract */
161 
162 
163 /**Function********************************************************************
164 
165  Synopsis [Universally Abstracts all the variables in cube from f.]
166 
167  Description [Abstracts all the variables in cube from f by taking
168  the product over all possible values taken by the variable. Returns
169  the abstracted ADD if successful; NULL otherwise.]
170 
171  SideEffects [None]
172 
173  SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract
174  Cudd_addOrAbstract]
175 
176 ******************************************************************************/
177 DdNode *
179  DdManager * manager,
180  DdNode * f,
181  DdNode * cube)
182 {
183  DdNode *res;
184 
185  if (addCheckPositiveCube(manager, cube) == 0) {
186  (void) fprintf(manager->err,"Error: Can only abstract cubes");
187  return(NULL);
188  }
189 
190  do {
191  manager->reordered = 0;
192  res = cuddAddUnivAbstractRecur(manager, f, cube);
193  } while (manager->reordered == 1);
194 
195  return(res);
196 
197 } /* end of Cudd_addUnivAbstract */
198 
199 
200 /**Function********************************************************************
201 
202  Synopsis [Disjunctively abstracts all the variables in cube from the
203  0-1 ADD f.]
204 
205  Description [Abstracts all the variables in cube from the 0-1 ADD f
206  by taking the disjunction over all possible values taken by the
207  variables. Returns the abstracted ADD if successful; NULL
208  otherwise.]
209 
210  SideEffects [None]
211 
212  SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
213 
214 ******************************************************************************/
215 DdNode *
217  DdManager * manager,
218  DdNode * f,
219  DdNode * cube)
220 {
221  DdNode *res;
222 
223  if (addCheckPositiveCube(manager, cube) == 0) {
224  (void) fprintf(manager->err,"Error: Can only abstract cubes");
225  return(NULL);
226  }
227 
228  do {
229  manager->reordered = 0;
230  res = cuddAddOrAbstractRecur(manager, f, cube);
231  } while (manager->reordered == 1);
232  return(res);
233 
234 } /* end of Cudd_addOrAbstract */
235 
236 
237 /*---------------------------------------------------------------------------*/
238 /* Definition of internal functions */
239 /*---------------------------------------------------------------------------*/
240 
241 
242 /**Function********************************************************************
243 
244  Synopsis [Performs the recursive step of Cudd_addExistAbstract.]
245 
246  Description [Performs the recursive step of Cudd_addExistAbstract.
247  Returns the ADD obtained by abstracting the variables of cube from f,
248  if successful; NULL otherwise.]
249 
250  SideEffects [None]
251 
252  SeeAlso []
253 
254 ******************************************************************************/
255 DdNode *
257  DdManager * manager,
258  DdNode * f,
259  DdNode * cube)
260 {
261  DdNode *T, *E, *res, *res1, *res2, *zero;
262 
263  statLine(manager);
264  zero = DD_ZERO(manager);
265 
266  /* Cube is guaranteed to be a cube at this point. */
267  if (f == zero || cuddIsConstant(cube)) {
268  return(f);
269  }
270 
271  /* Abstract a variable that does not appear in f => multiply by 2. */
272  if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
273  res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube));
274  if (res1 == NULL) return(NULL);
275  cuddRef(res1);
276  /* Use the "internal" procedure to be alerted in case of
277  ** dynamic reordering. If dynamic reordering occurs, we
278  ** have to abort the entire abstraction.
279  */
280  res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two);
281  if (res == NULL) {
282  Cudd_RecursiveDeref(manager,res1);
283  return(NULL);
284  }
285  cuddRef(res);
286  Cudd_RecursiveDeref(manager,res1);
287  cuddDeref(res);
288  return(res);
289  }
290 
291  if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) {
292  return(res);
293  }
294 
295  T = cuddT(f);
296  E = cuddE(f);
297 
298  /* If the two indices are the same, so are their levels. */
299  if (f->index == cube->index) {
300  res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube));
301  if (res1 == NULL) return(NULL);
302  cuddRef(res1);
303  res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube));
304  if (res2 == NULL) {
305  Cudd_RecursiveDeref(manager,res1);
306  return(NULL);
307  }
308  cuddRef(res2);
309  res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2);
310  if (res == NULL) {
311  Cudd_RecursiveDeref(manager,res1);
312  Cudd_RecursiveDeref(manager,res2);
313  return(NULL);
314  }
315  cuddRef(res);
316  Cudd_RecursiveDeref(manager,res1);
317  Cudd_RecursiveDeref(manager,res2);
318  cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
319  cuddDeref(res);
320  return(res);
321  } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
322  res1 = cuddAddExistAbstractRecur(manager, T, cube);
323  if (res1 == NULL) return(NULL);
324  cuddRef(res1);
325  res2 = cuddAddExistAbstractRecur(manager, E, cube);
326  if (res2 == NULL) {
327  Cudd_RecursiveDeref(manager,res1);
328  return(NULL);
329  }
330  cuddRef(res2);
331  res = (res1 == res2) ? res1 :
332  cuddUniqueInter(manager, (int) f->index, res1, res2);
333  if (res == NULL) {
334  Cudd_RecursiveDeref(manager,res1);
335  Cudd_RecursiveDeref(manager,res2);
336  return(NULL);
337  }
338  cuddDeref(res1);
339  cuddDeref(res2);
340  cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
341  return(res);
342  }
343 
344 } /* end of cuddAddExistAbstractRecur */
345 
346 
347 /**Function********************************************************************
348 
349  Synopsis [Performs the recursive step of Cudd_addUnivAbstract.]
350 
351  Description [Performs the recursive step of Cudd_addUnivAbstract.
352  Returns the ADD obtained by abstracting the variables of cube from f,
353  if successful; NULL otherwise.]
354 
355  SideEffects [None]
356 
357  SeeAlso []
358 
359 ******************************************************************************/
360 DdNode *
362  DdManager * manager,
363  DdNode * f,
364  DdNode * cube)
365 {
366  DdNode *T, *E, *res, *res1, *res2, *one, *zero;
367 
368  statLine(manager);
369  one = DD_ONE(manager);
370  zero = DD_ZERO(manager);
371 
372  /* Cube is guaranteed to be a cube at this point.
373  ** zero and one are the only constatnts c such that c*c=c.
374  */
375  if (f == zero || f == one || cube == one) {
376  return(f);
377  }
378 
379  /* Abstract a variable that does not appear in f. */
380  if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
381  res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube));
382  if (res1 == NULL) return(NULL);
383  cuddRef(res1);
384  /* Use the "internal" procedure to be alerted in case of
385  ** dynamic reordering. If dynamic reordering occurs, we
386  ** have to abort the entire abstraction.
387  */
388  res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1);
389  if (res == NULL) {
390  Cudd_RecursiveDeref(manager,res1);
391  return(NULL);
392  }
393  cuddRef(res);
394  Cudd_RecursiveDeref(manager,res1);
395  cuddDeref(res);
396  return(res);
397  }
398 
399  if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) {
400  return(res);
401  }
402 
403  T = cuddT(f);
404  E = cuddE(f);
405 
406  /* If the two indices are the same, so are their levels. */
407  if (f->index == cube->index) {
408  res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube));
409  if (res1 == NULL) return(NULL);
410  cuddRef(res1);
411  res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube));
412  if (res2 == NULL) {
413  Cudd_RecursiveDeref(manager,res1);
414  return(NULL);
415  }
416  cuddRef(res2);
417  res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2);
418  if (res == NULL) {
419  Cudd_RecursiveDeref(manager,res1);
420  Cudd_RecursiveDeref(manager,res2);
421  return(NULL);
422  }
423  cuddRef(res);
424  Cudd_RecursiveDeref(manager,res1);
425  Cudd_RecursiveDeref(manager,res2);
426  cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
427  cuddDeref(res);
428  return(res);
429  } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
430  res1 = cuddAddUnivAbstractRecur(manager, T, cube);
431  if (res1 == NULL) return(NULL);
432  cuddRef(res1);
433  res2 = cuddAddUnivAbstractRecur(manager, E, cube);
434  if (res2 == NULL) {
435  Cudd_RecursiveDeref(manager,res1);
436  return(NULL);
437  }
438  cuddRef(res2);
439  res = (res1 == res2) ? res1 :
440  cuddUniqueInter(manager, (int) f->index, res1, res2);
441  if (res == NULL) {
442  Cudd_RecursiveDeref(manager,res1);
443  Cudd_RecursiveDeref(manager,res2);
444  return(NULL);
445  }
446  cuddDeref(res1);
447  cuddDeref(res2);
448  cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
449  return(res);
450  }
451 
452 } /* end of cuddAddUnivAbstractRecur */
453 
454 
455 /**Function********************************************************************
456 
457  Synopsis [Performs the recursive step of Cudd_addOrAbstract.]
458 
459  Description [Performs the recursive step of Cudd_addOrAbstract.
460  Returns the ADD obtained by abstracting the variables of cube from f,
461  if successful; NULL otherwise.]
462 
463  SideEffects [None]
464 
465  SeeAlso []
466 
467 ******************************************************************************/
468 DdNode *
470  DdManager * manager,
471  DdNode * f,
472  DdNode * cube)
473 {
474  DdNode *T, *E, *res, *res1, *res2, *one;
475 
476  statLine(manager);
477  one = DD_ONE(manager);
478 
479  /* Cube is guaranteed to be a cube at this point. */
480  if (cuddIsConstant(f) || cube == one) {
481  return(f);
482  }
483 
484  /* Abstract a variable that does not appear in f. */
485  if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
486  res = cuddAddOrAbstractRecur(manager, f, cuddT(cube));
487  return(res);
488  }
489 
490  if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) {
491  return(res);
492  }
493 
494  T = cuddT(f);
495  E = cuddE(f);
496 
497  /* If the two indices are the same, so are their levels. */
498  if (f->index == cube->index) {
499  res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube));
500  if (res1 == NULL) return(NULL);
501  cuddRef(res1);
502  if (res1 != one) {
503  res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube));
504  if (res2 == NULL) {
505  Cudd_RecursiveDeref(manager,res1);
506  return(NULL);
507  }
508  cuddRef(res2);
509  res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2);
510  if (res == NULL) {
511  Cudd_RecursiveDeref(manager,res1);
512  Cudd_RecursiveDeref(manager,res2);
513  return(NULL);
514  }
515  cuddRef(res);
516  Cudd_RecursiveDeref(manager,res1);
517  Cudd_RecursiveDeref(manager,res2);
518  } else {
519  res = res1;
520  }
521  cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
522  cuddDeref(res);
523  return(res);
524  } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
525  res1 = cuddAddOrAbstractRecur(manager, T, cube);
526  if (res1 == NULL) return(NULL);
527  cuddRef(res1);
528  res2 = cuddAddOrAbstractRecur(manager, E, cube);
529  if (res2 == NULL) {
530  Cudd_RecursiveDeref(manager,res1);
531  return(NULL);
532  }
533  cuddRef(res2);
534  res = (res1 == res2) ? res1 :
535  cuddUniqueInter(manager, (int) f->index, res1, res2);
536  if (res == NULL) {
537  Cudd_RecursiveDeref(manager,res1);
538  Cudd_RecursiveDeref(manager,res2);
539  return(NULL);
540  }
541  cuddDeref(res1);
542  cuddDeref(res2);
543  cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
544  return(res);
545  }
546 
547 } /* end of cuddAddOrAbstractRecur */
548 
549 
550 
551 /*---------------------------------------------------------------------------*/
552 /* Definition of static functions */
553 /*---------------------------------------------------------------------------*/
554 
555 
556 /**Function********************************************************************
557 
558  Synopsis [Checks whether cube is an ADD representing the product
559  of positive literals.]
560 
561  Description [Checks whether cube is an ADD representing the product of
562  positive literals. Returns 1 in case of success; 0 otherwise.]
563 
564  SideEffects [None]
565 
566  SeeAlso []
567 
568 ******************************************************************************/
569 static int
571  DdManager * manager,
572  DdNode * cube)
573 {
574  if (Cudd_IsComplement(cube)) return(0);
575  if (cube == DD_ONE(manager)) return(1);
576  if (cuddIsConstant(cube)) return(0);
577  if (cuddE(cube) == DD_ZERO(manager)) {
578  return(addCheckPositiveCube(manager, cuddT(cube)));
579  }
580  return(0);
581 
582 } /* end of addCheckPositiveCube */
583 
584 
586 
587 
588 
#define cuddRef(n)
Definition: cuddInt.h:584
static DdNode * two
Definition: cuddAddAbs.c:92
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddAddUnivAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:361
DdNode * Cudd_addOr(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:581
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
FILE * err
Definition: cuddInt.h:442
DdNode * cuddAddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:256
DdNode * Cudd_addOrAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:216
DdNode * Cudd_addUnivAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:178
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
int reordered
Definition: cuddInt.h:409
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * Cudd_addPlus(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:168
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * Cudd_addExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:129
#define cuddT(node)
Definition: cuddInt.h:636
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define cuddI(dd, index)
Definition: cuddInt.h:686
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
static int addCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddAddAbs.c:570
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddAddOrAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:469
#define cuddE(node)
Definition: cuddInt.h:652
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddAddAbs.c:89
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * Cudd_addTimes(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:208
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927