abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddAndAbs.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddAndAbs.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Combined AND and existential abstraction for BDDs]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_bddAndAbstract()
12  <li> Cudd_bddAndAbstractLimit()
13  </ul>
14  Internal procedures included in this module:
15  <ul>
16  <li> cuddBddAndAbstractRecur()
17  </ul>]
18 
19  Author [Fabio Somenzi]
20 
21  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
22 
23  All rights reserved.
24 
25  Redistribution and use in source and binary forms, with or without
26  modification, are permitted provided that the following conditions
27  are met:
28 
29  Redistributions of source code must retain the above copyright
30  notice, this list of conditions and the following disclaimer.
31 
32  Redistributions in binary form must reproduce the above copyright
33  notice, this list of conditions and the following disclaimer in the
34  documentation and/or other materials provided with the distribution.
35 
36  Neither the name of the University of Colorado nor the names of its
37  contributors may be used to endorse or promote products derived from
38  this software without specific prior written permission.
39 
40  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
43  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
44  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
45  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
46  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
48  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
50  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51  POSSIBILITY OF SUCH DAMAGE.]
52 
53 ******************************************************************************/
54 
55 #include "misc/util/util_hack.h"
56 #include "cuddInt.h"
57 
59 
60 
61 
62 
63 /*---------------------------------------------------------------------------*/
64 /* Constant declarations */
65 /*---------------------------------------------------------------------------*/
66 
67 
68 /*---------------------------------------------------------------------------*/
69 /* Stucture declarations */
70 /*---------------------------------------------------------------------------*/
71 
72 
73 /*---------------------------------------------------------------------------*/
74 /* Type declarations */
75 /*---------------------------------------------------------------------------*/
76 
77 
78 /*---------------------------------------------------------------------------*/
79 /* Variable declarations */
80 /*---------------------------------------------------------------------------*/
81 
82 #ifndef lint
83 static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.19 2004/08/13 18:04:46 fabio Exp $";
84 #endif
85 
86 
87 /*---------------------------------------------------------------------------*/
88 /* Macro declarations */
89 /*---------------------------------------------------------------------------*/
90 
91 
92 /**AutomaticStart*************************************************************/
93 
94 /*---------------------------------------------------------------------------*/
95 /* Static function prototypes */
96 /*---------------------------------------------------------------------------*/
97 
98 
99 /**AutomaticEnd***************************************************************/
100 
101 
102 /*---------------------------------------------------------------------------*/
103 /* Definition of exported functions */
104 /*---------------------------------------------------------------------------*/
105 
106 
107 /**Function********************************************************************
108 
109  Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
110  variables in cube.]
111 
112  Description [Takes the AND of two BDDs and simultaneously abstracts
113  the variables in cube. The variables are existentially abstracted.
114  Returns a pointer to the result is successful; NULL otherwise.
115  Cudd_bddAndAbstract implements the semiring matrix multiplication
116  algorithm for the boolean semiring.]
117 
118  SideEffects [None]
119 
120  SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd]
121 
122 ******************************************************************************/
123 DdNode *
125  DdManager * manager,
126  DdNode * f,
127  DdNode * g,
128  DdNode * cube)
129 {
130  DdNode *res;
131 
132  do {
133  manager->reordered = 0;
134  res = cuddBddAndAbstractRecur(manager, f, g, cube);
135  } while (manager->reordered == 1);
136  return(res);
137 
138 } /* end of Cudd_bddAndAbstract */
139 
140 
141 /**Function********************************************************************
142 
143  Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
144  variables in cube. Returns NULL if too many nodes are required.]
145 
146  Description [Takes the AND of two BDDs and simultaneously abstracts
147  the variables in cube. The variables are existentially abstracted.
148  Returns a pointer to the result is successful; NULL otherwise.
149  In particular, if the number of new nodes created exceeds
150  <code>limit</code>, this function returns NULL.]
151 
152  SideEffects [None]
153 
154  SeeAlso [Cudd_bddAndAbstract]
155 
156 ******************************************************************************/
157 DdNode *
159  DdManager * manager,
160  DdNode * f,
161  DdNode * g,
162  DdNode * cube,
163  unsigned int limit)
164 {
165  DdNode *res;
166  unsigned int saveLimit = manager->maxLive;
167 
168  manager->maxLive = (manager->keys - manager->dead) +
169  (manager->keysZ - manager->deadZ) + limit;
170  do {
171  manager->reordered = 0;
172  res = cuddBddAndAbstractRecur(manager, f, g, cube);
173  } while (manager->reordered == 1);
174  manager->maxLive = saveLimit;
175  return(res);
176 
177 } /* end of Cudd_bddAndAbstractLimit */
178 
179 
180 /*---------------------------------------------------------------------------*/
181 /* Definition of internal functions */
182 /*---------------------------------------------------------------------------*/
183 
184 
185 /**Function********************************************************************
186 
187  Synopsis [Takes the AND of two BDDs and simultaneously abstracts the
188  variables in cube.]
189 
190  Description [Takes the AND of two BDDs and simultaneously abstracts
191  the variables in cube. The variables are existentially abstracted.
192  Returns a pointer to the result is successful; NULL otherwise.]
193 
194  SideEffects [None]
195 
196  SeeAlso [Cudd_bddAndAbstract]
197 
198 ******************************************************************************/
199 DdNode *
201  DdManager * manager,
202  DdNode * f,
203  DdNode * g,
204  DdNode * cube)
205 {
206  DdNode *F, *ft, *fe, *G, *gt, *ge;
207  DdNode *one, *zero, *r, *t, *e;
208  unsigned int topf, topg, topcube, top, index;
209 
210  statLine(manager);
211  one = DD_ONE(manager);
212  zero = Cudd_Not(one);
213 
214  /* Terminal cases. */
215  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
216  if (f == one && g == one) return(one);
217 
218  if (cube == one) {
219  return(cuddBddAndRecur(manager, f, g));
220  }
221  if (f == one || f == g) {
222  return(cuddBddExistAbstractRecur(manager, g, cube));
223  }
224  if (g == one) {
225  return(cuddBddExistAbstractRecur(manager, f, cube));
226  }
227  /* At this point f, g, and cube are not constant. */
228 
229  if (f > g) { /* Try to increase cache efficiency. */
230  DdNode *tmp = f;
231  f = g;
232  g = tmp;
233  }
234 
235  /* Here we can skip the use of cuddI, because the operands are known
236  ** to be non-constant.
237  */
238  F = Cudd_Regular(f);
239  G = Cudd_Regular(g);
240  topf = manager->perm[F->index];
241  topg = manager->perm[G->index];
242  top = ddMin(topf, topg);
243  topcube = manager->perm[cube->index];
244 
245  while (topcube < top) {
246  cube = cuddT(cube);
247  if (cube == one) {
248  return(cuddBddAndRecur(manager, f, g));
249  }
250  topcube = manager->perm[cube->index];
251  }
252  /* Now, topcube >= top. */
253 
254  /* Check cache. */
255  if (F->ref != 1 || G->ref != 1) {
256  r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube);
257  if (r != NULL) {
258  return(r);
259  }
260  }
261 
262  if ( manager->TimeStop && Abc_Clock() > manager->TimeStop )
263  return NULL;
264 
265  if (topf == top) {
266  index = F->index;
267  ft = cuddT(F);
268  fe = cuddE(F);
269  if (Cudd_IsComplement(f)) {
270  ft = Cudd_Not(ft);
271  fe = Cudd_Not(fe);
272  }
273  } else {
274  index = G->index;
275  ft = fe = f;
276  }
277 
278  if (topg == top) {
279  gt = cuddT(G);
280  ge = cuddE(G);
281  if (Cudd_IsComplement(g)) {
282  gt = Cudd_Not(gt);
283  ge = Cudd_Not(ge);
284  }
285  } else {
286  gt = ge = g;
287  }
288 
289  if (topcube == top) { /* quantify */
290  DdNode *Cube = cuddT(cube);
291  t = cuddBddAndAbstractRecur(manager, ft, gt, Cube);
292  if (t == NULL) return(NULL);
293  /* Special case: 1 OR anything = 1. Hence, no need to compute
294  ** the else branch if t is 1. Likewise t + t * anything == t.
295  ** Notice that t == fe implies that fe does not depend on the
296  ** variables in Cube. Likewise for t == ge.
297  */
298  if (t == one || t == fe || t == ge) {
299  if (F->ref != 1 || G->ref != 1)
301  f, g, cube, t);
302  return(t);
303  }
304  cuddRef(t);
305  /* Special case: t + !t * anything == t + anything. */
306  if (t == Cudd_Not(fe)) {
307  e = cuddBddExistAbstractRecur(manager, ge, Cube);
308  } else if (t == Cudd_Not(ge)) {
309  e = cuddBddExistAbstractRecur(manager, fe, Cube);
310  } else {
311  e = cuddBddAndAbstractRecur(manager, fe, ge, Cube);
312  }
313  if (e == NULL) {
314  Cudd_IterDerefBdd(manager, t);
315  return(NULL);
316  }
317  if (t == e) {
318  r = t;
319  cuddDeref(t);
320  } else {
321  cuddRef(e);
322  r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
323  if (r == NULL) {
324  Cudd_IterDerefBdd(manager, t);
325  Cudd_IterDerefBdd(manager, e);
326  return(NULL);
327  }
328  r = Cudd_Not(r);
329  cuddRef(r);
330  Cudd_DelayedDerefBdd(manager, t);
331  Cudd_DelayedDerefBdd(manager, e);
332  cuddDeref(r);
333  }
334  } else {
335  t = cuddBddAndAbstractRecur(manager, ft, gt, cube);
336  if (t == NULL) return(NULL);
337  cuddRef(t);
338  e = cuddBddAndAbstractRecur(manager, fe, ge, cube);
339  if (e == NULL) {
340  Cudd_IterDerefBdd(manager, t);
341  return(NULL);
342  }
343  if (t == e) {
344  r = t;
345  cuddDeref(t);
346  } else {
347  cuddRef(e);
348  if (Cudd_IsComplement(t)) {
349  r = cuddUniqueInter(manager, (int) index,
350  Cudd_Not(t), Cudd_Not(e));
351  if (r == NULL) {
352  Cudd_IterDerefBdd(manager, t);
353  Cudd_IterDerefBdd(manager, e);
354  return(NULL);
355  }
356  r = Cudd_Not(r);
357  } else {
358  r = cuddUniqueInter(manager,(int)index,t,e);
359  if (r == NULL) {
360  Cudd_IterDerefBdd(manager, t);
361  Cudd_IterDerefBdd(manager, e);
362  return(NULL);
363  }
364  }
365  cuddDeref(e);
366  cuddDeref(t);
367  }
368  }
369 
370  if (F->ref != 1 || G->ref != 1)
371  cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
372  return (r);
373 
374 } /* end of cuddBddAndAbstractRecur */
375 
376 
377 /*---------------------------------------------------------------------------*/
378 /* Definition of static functions */
379 /*---------------------------------------------------------------------------*/
380 
381 
383 
384 
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
abctime TimeStop
Definition: cuddInt.h:489
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
unsigned int deadZ
Definition: cuddInt.h:372
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode * cuddBddAndAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddAndAbs.c:200
static abctime Abc_Clock()
Definition: abc_global.h:279
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * Cudd_bddAndAbstractLimit(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit)
Definition: cuddAndAbs.c:158
int reordered
Definition: cuddInt.h:409
unsigned int dead
Definition: cuddInt.h:371
#define Cudd_IsComplement(node)
Definition: cudd.h:425
unsigned int maxLive
Definition: cuddInt.h:373
unsigned int keys
Definition: cuddInt.h:369
static DdNode * one
Definition: cuddDecomp.c:112
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddAndAbs.c:83
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define DD_BDD_AND_ABSTRACT_TAG
Definition: cuddInt.h:173
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
void Cudd_DelayedDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:274
DdNode * Cudd_bddAndAbstract(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddAndAbs.c:124
#define DD_ONE(dd)
Definition: cuddInt.h:911
unsigned int keysZ
Definition: cuddInt.h:370
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369