abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddClip.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddClip.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Clipping functions.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_bddClippingAnd()
12  <li> Cudd_bddClippingAndAbstract()
13  </ul>
14  Internal procedures included in this module:
15  <ul>
16  <li> cuddBddClippingAnd()
17  <li> cuddBddClippingAndAbstract()
18  </ul>
19  Static procedures included in this module:
20  <ul>
21  <li> cuddBddClippingAndRecur()
22  <li> cuddBddClipAndAbsRecur()
23  </ul>
24 
25  SeeAlso []
26 
27  Author [Fabio Somenzi]
28 
29  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
30 
31  All rights reserved.
32 
33  Redistribution and use in source and binary forms, with or without
34  modification, are permitted provided that the following conditions
35  are met:
36 
37  Redistributions of source code must retain the above copyright
38  notice, this list of conditions and the following disclaimer.
39 
40  Redistributions in binary form must reproduce the above copyright
41  notice, this list of conditions and the following disclaimer in the
42  documentation and/or other materials provided with the distribution.
43 
44  Neither the name of the University of Colorado nor the names of its
45  contributors may be used to endorse or promote products derived from
46  this software without specific prior written permission.
47 
48  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
54  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
56  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
58  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59  POSSIBILITY OF SUCH DAMAGE.]
60 
61 ******************************************************************************/
62 
63 #include "misc/util/util_hack.h"
64 #include "cuddInt.h"
65 
67 
68 
69 
70 
71 /*---------------------------------------------------------------------------*/
72 /* Constant declarations */
73 /*---------------------------------------------------------------------------*/
74 
75 
76 /*---------------------------------------------------------------------------*/
77 /* Stucture declarations */
78 /*---------------------------------------------------------------------------*/
79 
80 
81 /*---------------------------------------------------------------------------*/
82 /* Type declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 /*---------------------------------------------------------------------------*/
86 /* Variable declarations */
87 /*---------------------------------------------------------------------------*/
88 
89 #ifndef lint
90 static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.8 2004/08/13 18:04:47 fabio Exp $";
91 #endif
92 
93 /*---------------------------------------------------------------------------*/
94 /* Macro declarations */
95 /*---------------------------------------------------------------------------*/
96 
97 
98 /**AutomaticStart*************************************************************/
99 
100 /*---------------------------------------------------------------------------*/
101 /* Static function prototypes */
102 /*---------------------------------------------------------------------------*/
103 
104 static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction);
105 static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction);
106 
107 /**AutomaticEnd***************************************************************/
108 
109 
110 /*---------------------------------------------------------------------------*/
111 /* Definition of exported functions */
112 /*---------------------------------------------------------------------------*/
113 
114 
115 /**Function********************************************************************
116 
117  Synopsis [Approximates the conjunction of two BDDs f and g.]
118 
119  Description [Approximates the conjunction of two BDDs f and g. Returns a
120  pointer to the resulting BDD if successful; NULL if the intermediate
121  result blows up.]
122 
123  SideEffects [None]
124 
125  SeeAlso [Cudd_bddAnd]
126 
127 ******************************************************************************/
128 DdNode *
130  DdManager * dd /* manager */,
131  DdNode * f /* first conjunct */,
132  DdNode * g /* second conjunct */,
133  int maxDepth /* maximum recursion depth */,
134  int direction /* under (0) or over (1) approximation */)
135 {
136  DdNode *res;
137 
138  do {
139  dd->reordered = 0;
140  res = cuddBddClippingAnd(dd,f,g,maxDepth,direction);
141  } while (dd->reordered == 1);
142  return(res);
143 
144 } /* end of Cudd_bddClippingAnd */
145 
146 
147 /**Function********************************************************************
148 
149  Synopsis [Approximates the conjunction of two BDDs f and g and
150  simultaneously abstracts the variables in cube.]
151 
152  Description [Approximates the conjunction of two BDDs f and g and
153  simultaneously abstracts the variables in cube. The variables are
154  existentially abstracted. Returns a pointer to the resulting BDD if
155  successful; NULL if the intermediate result blows up.]
156 
157  SideEffects [None]
158 
159  SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd]
160 
161 ******************************************************************************/
162 DdNode *
164  DdManager * dd /* manager */,
165  DdNode * f /* first conjunct */,
166  DdNode * g /* second conjunct */,
167  DdNode * cube /* cube of variables to be abstracted */,
168  int maxDepth /* maximum recursion depth */,
169  int direction /* under (0) or over (1) approximation */)
170 {
171  DdNode *res;
172 
173  do {
174  dd->reordered = 0;
175  res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction);
176  } while (dd->reordered == 1);
177  return(res);
178 
179 } /* end of Cudd_bddClippingAndAbstract */
180 
181 
182 /*---------------------------------------------------------------------------*/
183 /* Definition of internal functions */
184 /*---------------------------------------------------------------------------*/
185 
186 
187 /**Function********************************************************************
188 
189  Synopsis [Approximates the conjunction of two BDDs f and g.]
190 
191  Description [Approximates the conjunction of two BDDs f and g. Returns a
192  pointer to the resulting BDD if successful; NULL if the intermediate
193  result blows up.]
194 
195  SideEffects [None]
196 
197  SeeAlso [Cudd_bddClippingAnd]
198 
199 ******************************************************************************/
200 DdNode *
202  DdManager * dd /* manager */,
203  DdNode * f /* first conjunct */,
204  DdNode * g /* second conjunct */,
205  int maxDepth /* maximum recursion depth */,
206  int direction /* under (0) or over (1) approximation */)
207 {
208  DdNode *res;
209 
210  res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction);
211 
212  return(res);
213 
214 } /* end of cuddBddClippingAnd */
215 
216 
217 /**Function********************************************************************
218 
219  Synopsis [Approximates the conjunction of two BDDs f and g and
220  simultaneously abstracts the variables in cube.]
221 
222  Description [Approximates the conjunction of two BDDs f and g and
223  simultaneously abstracts the variables in cube. Returns a
224  pointer to the resulting BDD if successful; NULL if the intermediate
225  result blows up.]
226 
227  SideEffects [None]
228 
229  SeeAlso [Cudd_bddClippingAndAbstract]
230 
231 ******************************************************************************/
232 DdNode *
234  DdManager * dd /* manager */,
235  DdNode * f /* first conjunct */,
236  DdNode * g /* second conjunct */,
237  DdNode * cube /* cube of variables to be abstracted */,
238  int maxDepth /* maximum recursion depth */,
239  int direction /* under (0) or over (1) approximation */)
240 {
241  DdNode *res;
242 
243  res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction);
244 
245  return(res);
246 
247 } /* end of cuddBddClippingAndAbstract */
248 
249 
250 /*---------------------------------------------------------------------------*/
251 /* Definition of static functions */
252 /*---------------------------------------------------------------------------*/
253 
254 
255 /**Function********************************************************************
256 
257  Synopsis [Implements the recursive step of Cudd_bddClippingAnd.]
258 
259  Description [Implements the recursive step of Cudd_bddClippingAnd by taking
260  the conjunction of two BDDs. Returns a pointer to the result is
261  successful; NULL otherwise.]
262 
263  SideEffects [None]
264 
265  SeeAlso [cuddBddClippingAnd]
266 
267 ******************************************************************************/
268 static DdNode *
270  DdManager * manager,
271  DdNode * f,
272  DdNode * g,
273  int distance,
274  int direction)
275 {
276  DdNode *F, *ft, *fe, *G, *gt, *ge;
277  DdNode *one, *zero, *r, *t, *e;
278  unsigned int topf, topg, index;
279  DD_CTFP cacheOp;
280 
281  statLine(manager);
282  one = DD_ONE(manager);
283  zero = Cudd_Not(one);
284 
285  /* Terminal cases. */
286  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
287  if (f == g || g == one) return(f);
288  if (f == one) return(g);
289  if (distance == 0) {
290  /* One last attempt at returning the right result. We sort of
291  ** cheat by calling Cudd_bddLeq. */
292  if (Cudd_bddLeq(manager,f,g)) return(f);
293  if (Cudd_bddLeq(manager,g,f)) return(g);
294  if (direction == 1) {
295  if (Cudd_bddLeq(manager,f,Cudd_Not(g)) ||
296  Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero);
297  }
298  return(Cudd_NotCond(one,(direction == 0)));
299  }
300 
301  /* At this point f and g are not constant. */
302  distance--;
303 
304  /* Check cache. Try to increase cache efficiency by sorting the
305  ** pointers. */
306  if (f > g) {
307  DdNode *tmp = f;
308  f = g; g = tmp;
309  }
310  F = Cudd_Regular(f);
311  G = Cudd_Regular(g);
312  cacheOp = (DD_CTFP)
313  (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd);
314  if (F->ref != 1 || G->ref != 1) {
315  r = cuddCacheLookup2(manager, cacheOp, f, g);
316  if (r != NULL) return(r);
317  }
318 
319  /* Here we can skip the use of cuddI, because the operands are known
320  ** to be non-constant.
321  */
322  topf = manager->perm[F->index];
323  topg = manager->perm[G->index];
324 
325  /* Compute cofactors. */
326  if (topf <= topg) {
327  index = F->index;
328  ft = cuddT(F);
329  fe = cuddE(F);
330  if (Cudd_IsComplement(f)) {
331  ft = Cudd_Not(ft);
332  fe = Cudd_Not(fe);
333  }
334  } else {
335  index = G->index;
336  ft = fe = f;
337  }
338 
339  if (topg <= topf) {
340  gt = cuddT(G);
341  ge = cuddE(G);
342  if (Cudd_IsComplement(g)) {
343  gt = Cudd_Not(gt);
344  ge = Cudd_Not(ge);
345  }
346  } else {
347  gt = ge = g;
348  }
349 
350  t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction);
351  if (t == NULL) return(NULL);
352  cuddRef(t);
353  e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction);
354  if (e == NULL) {
355  Cudd_RecursiveDeref(manager, t);
356  return(NULL);
357  }
358  cuddRef(e);
359 
360  if (t == e) {
361  r = t;
362  } else {
363  if (Cudd_IsComplement(t)) {
364  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
365  if (r == NULL) {
366  Cudd_RecursiveDeref(manager, t);
367  Cudd_RecursiveDeref(manager, e);
368  return(NULL);
369  }
370  r = Cudd_Not(r);
371  } else {
372  r = cuddUniqueInter(manager,(int)index,t,e);
373  if (r == NULL) {
374  Cudd_RecursiveDeref(manager, t);
375  Cudd_RecursiveDeref(manager, e);
376  return(NULL);
377  }
378  }
379  }
380  cuddDeref(e);
381  cuddDeref(t);
382  if (F->ref != 1 || G->ref != 1)
383  cuddCacheInsert2(manager, cacheOp, f, g, r);
384  return(r);
385 
386 } /* end of cuddBddClippingAndRecur */
387 
388 
389 /**Function********************************************************************
390 
391  Synopsis [Approximates the AND of two BDDs and simultaneously abstracts the
392  variables in cube.]
393 
394  Description [Approximates the AND of two BDDs and simultaneously
395  abstracts the variables in cube. The variables are existentially
396  abstracted. Returns a pointer to the result is successful; NULL
397  otherwise.]
398 
399  SideEffects [None]
400 
401  SeeAlso [Cudd_bddClippingAndAbstract]
402 
403 ******************************************************************************/
404 static DdNode *
406  DdManager * manager,
407  DdNode * f,
408  DdNode * g,
409  DdNode * cube,
410  int distance,
411  int direction)
412 {
413  DdNode *F, *ft, *fe, *G, *gt, *ge;
414  DdNode *one, *zero, *r, *t, *e, *Cube;
415  unsigned int topf, topg, topcube, top, index;
416  ptruint cacheTag;
417 
418  statLine(manager);
419  one = DD_ONE(manager);
420  zero = Cudd_Not(one);
421 
422  /* Terminal cases. */
423  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
424  if (f == one && g == one) return(one);
425  if (cube == one) {
426  return(cuddBddClippingAndRecur(manager, f, g, distance, direction));
427  }
428  if (f == one || f == g) {
429  return (cuddBddExistAbstractRecur(manager, g, cube));
430  }
431  if (g == one) {
432  return (cuddBddExistAbstractRecur(manager, f, cube));
433  }
434  if (distance == 0) return(Cudd_NotCond(one,(direction == 0)));
435 
436  /* At this point f, g, and cube are not constant. */
437  distance--;
438 
439  /* Check cache. */
440  if (f > g) { /* Try to increase cache efficiency. */
441  DdNode *tmp = f;
442  f = g; g = tmp;
443  }
444  F = Cudd_Regular(f);
445  G = Cudd_Regular(g);
446  cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG :
448  if (F->ref != 1 || G->ref != 1) {
449  r = cuddCacheLookup(manager, cacheTag,
450  f, g, cube);
451  if (r != NULL) {
452  return(r);
453  }
454  }
455 
456  /* Here we can skip the use of cuddI, because the operands are known
457  ** to be non-constant.
458  */
459  topf = manager->perm[F->index];
460  topg = manager->perm[G->index];
461  top = ddMin(topf, topg);
462  topcube = manager->perm[cube->index];
463 
464  if (topcube < top) {
465  return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube),
466  distance, direction));
467  }
468  /* Now, topcube >= top. */
469 
470  if (topf == top) {
471  index = F->index;
472  ft = cuddT(F);
473  fe = cuddE(F);
474  if (Cudd_IsComplement(f)) {
475  ft = Cudd_Not(ft);
476  fe = Cudd_Not(fe);
477  }
478  } else {
479  index = G->index;
480  ft = fe = f;
481  }
482 
483  if (topg == top) {
484  gt = cuddT(G);
485  ge = cuddE(G);
486  if (Cudd_IsComplement(g)) {
487  gt = Cudd_Not(gt);
488  ge = Cudd_Not(ge);
489  }
490  } else {
491  gt = ge = g;
492  }
493 
494  if (topcube == top) {
495  Cube = cuddT(cube);
496  } else {
497  Cube = cube;
498  }
499 
500  t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction);
501  if (t == NULL) return(NULL);
502 
503  /* Special case: 1 OR anything = 1. Hence, no need to compute
504  ** the else branch if t is 1.
505  */
506  if (t == one && topcube == top) {
507  if (F->ref != 1 || G->ref != 1)
508  cuddCacheInsert(manager, cacheTag, f, g, cube, one);
509  return(one);
510  }
511  cuddRef(t);
512 
513  e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction);
514  if (e == NULL) {
515  Cudd_RecursiveDeref(manager, t);
516  return(NULL);
517  }
518  cuddRef(e);
519 
520  if (topcube == top) { /* abstract */
521  r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e),
522  distance, (direction == 0));
523  if (r == NULL) {
524  Cudd_RecursiveDeref(manager, t);
525  Cudd_RecursiveDeref(manager, e);
526  return(NULL);
527  }
528  r = Cudd_Not(r);
529  cuddRef(r);
530  Cudd_RecursiveDeref(manager, t);
531  Cudd_RecursiveDeref(manager, e);
532  cuddDeref(r);
533  } else if (t == e) {
534  r = t;
535  cuddDeref(t);
536  cuddDeref(e);
537  } else {
538  if (Cudd_IsComplement(t)) {
539  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
540  if (r == NULL) {
541  Cudd_RecursiveDeref(manager, t);
542  Cudd_RecursiveDeref(manager, e);
543  return(NULL);
544  }
545  r = Cudd_Not(r);
546  } else {
547  r = cuddUniqueInter(manager,(int)index,t,e);
548  if (r == NULL) {
549  Cudd_RecursiveDeref(manager, t);
550  Cudd_RecursiveDeref(manager, e);
551  return(NULL);
552  }
553  }
554  cuddDeref(e);
555  cuddDeref(t);
556  }
557  if (F->ref != 1 || G->ref != 1)
558  cuddCacheInsert(manager, cacheTag, f, g, cube, r);
559  return (r);
560 
561 } /* end of cuddBddClipAndAbsRecur */
562 
563 
565 
566 
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
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddClip.c:90
DdNode * cuddBddClippingAndAbstract(DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)
Definition: cuddClip.c:233
#define Cudd_Regular(node)
Definition: cudd.h:397
#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG
Definition: cuddInt.h:178
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddBddClippingAnd(DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)
Definition: cuddClip.c:201
DdNode * Cudd_bddClippingAndAbstract(DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)
Definition: cuddClip.c:163
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
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
static DdNode * cuddBddClippingAndRecur(DdManager *manager, DdNode *f, DdNode *g, int distance, int direction)
Definition: cuddClip.c:269
#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
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
static DdNode * cuddBddClipAndAbsRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction)
Definition: cuddClip.c:405
#define DD_ONE(dd)
Definition: cuddInt.h:911
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 * Cudd_bddClippingAnd(DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)
Definition: cuddClip.c:129
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG
Definition: cuddInt.h:177