abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddPriority.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddPriority.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Priority functions.]
8 
9  Description [External procedures included in this file:
10  <ul>
11  <li> Cudd_PrioritySelect()
12  <li> Cudd_Xgty()
13  <li> Cudd_Xeqy()
14  <li> Cudd_addXeqy()
15  <li> Cudd_Dxygtdxz()
16  <li> Cudd_Dxygtdyz()
17  <li> Cudd_Inequality()
18  <li> Cudd_Disequality()
19  <li> Cudd_bddInterval()
20  <li> Cudd_CProjection()
21  <li> Cudd_addHamming()
22  <li> Cudd_MinHammingDist()
23  <li> Cudd_bddClosestCube()
24  </ul>
25  Internal procedures included in this module:
26  <ul>
27  <li> cuddCProjectionRecur()
28  <li> cuddBddClosestCube()
29  </ul>
30  Static procedures included in this module:
31  <ul>
32  <li> cuddMinHammingDistRecur()
33  <li> separateCube()
34  <li> createResult()
35  </ul>
36  ]
37 
38  SeeAlso []
39 
40  Author [Fabio Somenzi]
41 
42  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
43 
44  All rights reserved.
45 
46  Redistribution and use in source and binary forms, with or without
47  modification, are permitted provided that the following conditions
48  are met:
49 
50  Redistributions of source code must retain the above copyright
51  notice, this list of conditions and the following disclaimer.
52 
53  Redistributions in binary form must reproduce the above copyright
54  notice, this list of conditions and the following disclaimer in the
55  documentation and/or other materials provided with the distribution.
56 
57  Neither the name of the University of Colorado nor the names of its
58  contributors may be used to endorse or promote products derived from
59  this software without specific prior written permission.
60 
61  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
62  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
63  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
64  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
65  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
66  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
67  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
69  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
71  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
72  POSSIBILITY OF SUCH DAMAGE.]
73 
74 ******************************************************************************/
75 
76 #include "misc/util/util_hack.h"
77 #include "cuddInt.h"
78 
80 
81 
82 
83 
84 /*---------------------------------------------------------------------------*/
85 /* Constant declarations */
86 /*---------------------------------------------------------------------------*/
87 
88 #define DD_DEBUG 1
89 
90 /*---------------------------------------------------------------------------*/
91 /* Stucture declarations */
92 /*---------------------------------------------------------------------------*/
93 
94 
95 /*---------------------------------------------------------------------------*/
96 /* Type declarations */
97 /*---------------------------------------------------------------------------*/
98 
99 
100 /*---------------------------------------------------------------------------*/
101 /* Variable declarations */
102 /*---------------------------------------------------------------------------*/
103 
104 #ifndef lint
105 static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.33 2009/02/20 02:14:58 fabio Exp $";
106 #endif
107 
108 /*---------------------------------------------------------------------------*/
109 /* Macro declarations */
110 /*---------------------------------------------------------------------------*/
111 
112 
113 /**AutomaticStart*************************************************************/
114 
115 /*---------------------------------------------------------------------------*/
116 /* Static function prototypes */
117 /*---------------------------------------------------------------------------*/
118 static int cuddMinHammingDistRecur (DdNode * f, int *minterm, DdHashTable * table, int upperBound);
119 static DdNode * separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance);
120 static DdNode * createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance);
121 
122 /**AutomaticEnd***************************************************************/
123 
124 
125 /*---------------------------------------------------------------------------*/
126 /* Definition of exported functions */
127 /*---------------------------------------------------------------------------*/
128 
129 
130 /**Function********************************************************************
131 
132  Synopsis [Selects pairs from R using a priority function.]
133 
134  Description [Selects pairs from a relation R(x,y) (given as a BDD)
135  in such a way that a given x appears in one pair only. Uses a
136  priority function to determine which y should be paired to a given x.
137  Cudd_PrioritySelect returns a pointer to
138  the selected function if successful; NULL otherwise.
139  Three of the arguments--x, y, and z--are vectors of BDD variables.
140  The first two are the variables on which R depends. The third vectore
141  is a vector of auxiliary variables, used during the computation. This
142  vector is optional. If a NULL value is passed instead,
143  Cudd_PrioritySelect will create the working variables on the fly.
144  The sizes of x and y (and z if it is not NULL) should equal n.
145  The priority function Pi can be passed as a BDD, or can be built by
146  Cudd_PrioritySelect. If NULL is passed instead of a DdNode *,
147  parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the
148  priority function. (Pifunc is a pointer to a C function.) If Pi is not
149  NULL, then Pifunc is ignored. Pifunc should have the same interface as
150  the standard priority functions (e.g., Cudd_Dxygtdxz).
151  Cudd_PrioritySelect and Cudd_CProjection can sometimes be used
152  interchangeably. Specifically, calling Cudd_PrioritySelect with
153  Cudd_Xgty as Pifunc produces the same result as calling
154  Cudd_CProjection with the all-zero minterm as reference minterm.
155  However, depending on the application, one or the other may be
156  preferable:
157  <ul>
158  <li> When extracting representatives from an equivalence relation,
159  Cudd_CProjection has the advantage of nor requiring the auxiliary
160  variables.
161  <li> When computing matchings in general bipartite graphs,
162  Cudd_PrioritySelect normally obtains better results because it can use
163  more powerful matching schemes (e.g., Cudd_Dxygtdxz).
164  </ul>
165  ]
166 
167  SideEffects [If called with z == NULL, will create new variables in
168  the manager.]
169 
170  SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty
171  Cudd_bddAdjPermuteX Cudd_CProjection]
172 
173 ******************************************************************************/
174 DdNode *
176  DdManager * dd /* manager */,
177  DdNode * R /* BDD of the relation */,
178  DdNode ** x /* array of x variables */,
179  DdNode ** y /* array of y variables */,
180  DdNode ** z /* array of z variables (optional: may be NULL) */,
181  DdNode * Pi /* BDD of the priority function (optional: may be NULL) */,
182  int n /* size of x, y, and z */,
183  DD_PRFP Pifunc /* function used to build Pi if it is NULL */)
184 {
185  DdNode *res = NULL;
186  DdNode *zcube = NULL;
187  DdNode *Rxz, *Q;
188  int createdZ = 0;
189  int createdPi = 0;
190  int i;
191 
192  /* Create z variables if needed. */
193  if (z == NULL) {
194  if (Pi != NULL) return(NULL);
195  z = ABC_ALLOC(DdNode *,n);
196  if (z == NULL) {
198  return(NULL);
199  }
200  createdZ = 1;
201  for (i = 0; i < n; i++) {
202  if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame;
203  z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one));
204  if (z[i] == NULL) goto endgame;
205  }
206  }
207 
208  /* Create priority function BDD if needed. */
209  if (Pi == NULL) {
210  Pi = Pifunc(dd,n,x,y,z);
211  if (Pi == NULL) goto endgame;
212  createdPi = 1;
213  cuddRef(Pi);
214  }
215 
216  /* Initialize abstraction cube. */
217  zcube = DD_ONE(dd);
218  cuddRef(zcube);
219  for (i = n - 1; i >= 0; i--) {
220  DdNode *tmpp;
221  tmpp = Cudd_bddAnd(dd,z[i],zcube);
222  if (tmpp == NULL) goto endgame;
223  cuddRef(tmpp);
224  Cudd_RecursiveDeref(dd,zcube);
225  zcube = tmpp;
226  }
227 
228  /* Compute subset of (x,y) pairs. */
229  Rxz = Cudd_bddSwapVariables(dd,R,y,z,n);
230  if (Rxz == NULL) goto endgame;
231  cuddRef(Rxz);
232  Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube);
233  if (Q == NULL) {
234  Cudd_RecursiveDeref(dd,Rxz);
235  goto endgame;
236  }
237  cuddRef(Q);
238  Cudd_RecursiveDeref(dd,Rxz);
239  res = Cudd_bddAnd(dd,R,Cudd_Not(Q));
240  if (res == NULL) {
241  Cudd_RecursiveDeref(dd,Q);
242  goto endgame;
243  }
244  cuddRef(res);
245  Cudd_RecursiveDeref(dd,Q);
246 
247 endgame:
248  if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube);
249  if (createdZ) {
250  ABC_FREE(z);
251  }
252  if (createdPi) {
253  Cudd_RecursiveDeref(dd,Pi);
254  }
255  if (res != NULL) cuddDeref(res);
256  return(res);
257 
258 } /* Cudd_PrioritySelect */
259 
260 
261 /**Function********************************************************************
262 
263  Synopsis [Generates a BDD for the function x &gt; y.]
264 
265  Description [This function generates a BDD for the function x &gt; y.
266  Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
267  y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
268  The BDD is built bottom-up.
269  It has 3*N-1 internal nodes, if the variables are ordered as follows:
270  x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].
271  Argument z is not used by Cudd_Xgty: it is included to make it
272  call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.]
273 
274  SideEffects [None]
275 
276  SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz]
277 
278 ******************************************************************************/
279 DdNode *
281  DdManager * dd /* DD manager */,
282  int N /* number of x and y variables */,
283  DdNode ** z /* array of z variables: unused */,
284  DdNode ** x /* array of x variables */,
285  DdNode ** y /* array of y variables */)
286 {
287  DdNode *u, *v, *w;
288  int i;
289 
290  /* Build bottom part of BDD outside loop. */
291  u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1]));
292  if (u == NULL) return(NULL);
293  cuddRef(u);
294 
295  /* Loop to build the rest of the BDD. */
296  for (i = N-2; i >= 0; i--) {
297  v = Cudd_bddAnd(dd, y[i], Cudd_Not(u));
298  if (v == NULL) {
299  Cudd_RecursiveDeref(dd, u);
300  return(NULL);
301  }
302  cuddRef(v);
303  w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u);
304  if (w == NULL) {
305  Cudd_RecursiveDeref(dd, u);
306  Cudd_RecursiveDeref(dd, v);
307  return(NULL);
308  }
309  cuddRef(w);
310  Cudd_RecursiveDeref(dd, u);
311  u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w);
312  if (u == NULL) {
313  Cudd_RecursiveDeref(dd, v);
314  Cudd_RecursiveDeref(dd, w);
315  return(NULL);
316  }
317  cuddRef(u);
318  Cudd_RecursiveDeref(dd, v);
319  Cudd_RecursiveDeref(dd, w);
320 
321  }
322  cuddDeref(u);
323  return(u);
324 
325 } /* end of Cudd_Xgty */
326 
327 
328 /**Function********************************************************************
329 
330  Synopsis [Generates a BDD for the function x==y.]
331 
332  Description [This function generates a BDD for the function x==y.
333  Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
334  y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
335  The BDD is built bottom-up.
336  It has 3*N-1 internal nodes, if the variables are ordered as follows:
337  x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]
338 
339  SideEffects [None]
340 
341  SeeAlso [Cudd_addXeqy]
342 
343 ******************************************************************************/
344 DdNode *
346  DdManager * dd /* DD manager */,
347  int N /* number of x and y variables */,
348  DdNode ** x /* array of x variables */,
349  DdNode ** y /* array of y variables */)
350 {
351  DdNode *u, *v, *w;
352  int i;
353 
354  /* Build bottom part of BDD outside loop. */
355  u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1]));
356  if (u == NULL) return(NULL);
357  cuddRef(u);
358 
359  /* Loop to build the rest of the BDD. */
360  for (i = N-2; i >= 0; i--) {
361  v = Cudd_bddAnd(dd, y[i], u);
362  if (v == NULL) {
363  Cudd_RecursiveDeref(dd, u);
364  return(NULL);
365  }
366  cuddRef(v);
367  w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u);
368  if (w == NULL) {
369  Cudd_RecursiveDeref(dd, u);
370  Cudd_RecursiveDeref(dd, v);
371  return(NULL);
372  }
373  cuddRef(w);
374  Cudd_RecursiveDeref(dd, u);
375  u = Cudd_bddIte(dd, x[i], v, w);
376  if (u == NULL) {
377  Cudd_RecursiveDeref(dd, v);
378  Cudd_RecursiveDeref(dd, w);
379  return(NULL);
380  }
381  cuddRef(u);
382  Cudd_RecursiveDeref(dd, v);
383  Cudd_RecursiveDeref(dd, w);
384  }
385  cuddDeref(u);
386  return(u);
387 
388 } /* end of Cudd_Xeqy */
389 
390 
391 /**Function********************************************************************
392 
393  Synopsis [Generates an ADD for the function x==y.]
394 
395  Description [This function generates an ADD for the function x==y.
396  Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
397  y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
398  The ADD is built bottom-up.
399  It has 3*N-1 internal nodes, if the variables are ordered as follows:
400  x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]
401 
402  SideEffects [None]
403 
404  SeeAlso [Cudd_Xeqy]
405 
406 ******************************************************************************/
407 DdNode *
409  DdManager * dd /* DD manager */,
410  int N /* number of x and y variables */,
411  DdNode ** x /* array of x variables */,
412  DdNode ** y /* array of y variables */)
413 {
414  DdNode *one, *zero;
415  DdNode *u, *v, *w;
416  int i;
417 
418  one = DD_ONE(dd);
419  zero = DD_ZERO(dd);
420 
421  /* Build bottom part of ADD outside loop. */
422  v = Cudd_addIte(dd, y[N-1], one, zero);
423  if (v == NULL) return(NULL);
424  cuddRef(v);
425  w = Cudd_addIte(dd, y[N-1], zero, one);
426  if (w == NULL) {
427  Cudd_RecursiveDeref(dd, v);
428  return(NULL);
429  }
430  cuddRef(w);
431  u = Cudd_addIte(dd, x[N-1], v, w);
432  if (u == NULL) {
433  Cudd_RecursiveDeref(dd, v);
434  Cudd_RecursiveDeref(dd, w);
435  return(NULL);
436  }
437  cuddRef(u);
438  Cudd_RecursiveDeref(dd, v);
439  Cudd_RecursiveDeref(dd, w);
440 
441  /* Loop to build the rest of the ADD. */
442  for (i = N-2; i >= 0; i--) {
443  v = Cudd_addIte(dd, y[i], u, zero);
444  if (v == NULL) {
445  Cudd_RecursiveDeref(dd, u);
446  return(NULL);
447  }
448  cuddRef(v);
449  w = Cudd_addIte(dd, y[i], zero, u);
450  if (w == NULL) {
451  Cudd_RecursiveDeref(dd, u);
452  Cudd_RecursiveDeref(dd, v);
453  return(NULL);
454  }
455  cuddRef(w);
456  Cudd_RecursiveDeref(dd, u);
457  u = Cudd_addIte(dd, x[i], v, w);
458  if (w == NULL) {
459  Cudd_RecursiveDeref(dd, v);
460  Cudd_RecursiveDeref(dd, w);
461  return(NULL);
462  }
463  cuddRef(u);
464  Cudd_RecursiveDeref(dd, v);
465  Cudd_RecursiveDeref(dd, w);
466  }
467  cuddDeref(u);
468  return(u);
469 
470 } /* end of Cudd_addXeqy */
471 
472 
473 /**Function********************************************************************
474 
475  Synopsis [Generates a BDD for the function d(x,y) &gt; d(x,z).]
476 
477  Description [This function generates a BDD for the function d(x,y)
478  &gt; d(x,z);
479  x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\],
480  y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\],
481  with 0 the most significant bit.
482  The distance d(x,y) is defined as:
483  \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}).
484  The BDD is built bottom-up.
485  It has 7*N-3 internal nodes, if the variables are ordered as follows:
486  x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]
487 
488  SideEffects [None]
489 
490  SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX]
491 
492 ******************************************************************************/
493 DdNode *
495  DdManager * dd /* DD manager */,
496  int N /* number of x, y, and z variables */,
497  DdNode ** x /* array of x variables */,
498  DdNode ** y /* array of y variables */,
499  DdNode ** z /* array of z variables */)
500 {
501  DdNode *one, *zero;
502  DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
503  int i;
504 
505  one = DD_ONE(dd);
506  zero = Cudd_Not(one);
507 
508  /* Build bottom part of BDD outside loop. */
509  y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1]));
510  if (y1_ == NULL) return(NULL);
511  cuddRef(y1_);
512  y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one);
513  if (y2 == NULL) {
514  Cudd_RecursiveDeref(dd, y1_);
515  return(NULL);
516  }
517  cuddRef(y2);
518  x1 = Cudd_bddIte(dd, x[N-1], y1_, y2);
519  if (x1 == NULL) {
520  Cudd_RecursiveDeref(dd, y1_);
521  Cudd_RecursiveDeref(dd, y2);
522  return(NULL);
523  }
524  cuddRef(x1);
525  Cudd_RecursiveDeref(dd, y1_);
526  Cudd_RecursiveDeref(dd, y2);
527 
528  /* Loop to build the rest of the BDD. */
529  for (i = N-2; i >= 0; i--) {
530  z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1));
531  if (z1 == NULL) {
532  Cudd_RecursiveDeref(dd, x1);
533  return(NULL);
534  }
535  cuddRef(z1);
536  z2 = Cudd_bddIte(dd, z[i], x1, one);
537  if (z2 == NULL) {
538  Cudd_RecursiveDeref(dd, x1);
539  Cudd_RecursiveDeref(dd, z1);
540  return(NULL);
541  }
542  cuddRef(z2);
543  z3 = Cudd_bddIte(dd, z[i], one, x1);
544  if (z3 == NULL) {
545  Cudd_RecursiveDeref(dd, x1);
546  Cudd_RecursiveDeref(dd, z1);
547  Cudd_RecursiveDeref(dd, z2);
548  return(NULL);
549  }
550  cuddRef(z3);
551  z4 = Cudd_bddIte(dd, z[i], x1, zero);
552  if (z4 == NULL) {
553  Cudd_RecursiveDeref(dd, x1);
554  Cudd_RecursiveDeref(dd, z1);
555  Cudd_RecursiveDeref(dd, z2);
556  Cudd_RecursiveDeref(dd, z3);
557  return(NULL);
558  }
559  cuddRef(z4);
560  Cudd_RecursiveDeref(dd, x1);
561  y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1));
562  if (y1_ == NULL) {
563  Cudd_RecursiveDeref(dd, z1);
564  Cudd_RecursiveDeref(dd, z2);
565  Cudd_RecursiveDeref(dd, z3);
566  Cudd_RecursiveDeref(dd, z4);
567  return(NULL);
568  }
569  cuddRef(y1_);
570  y2 = Cudd_bddIte(dd, y[i], z4, z3);
571  if (y2 == NULL) {
572  Cudd_RecursiveDeref(dd, z1);
573  Cudd_RecursiveDeref(dd, z2);
574  Cudd_RecursiveDeref(dd, z3);
575  Cudd_RecursiveDeref(dd, z4);
576  Cudd_RecursiveDeref(dd, y1_);
577  return(NULL);
578  }
579  cuddRef(y2);
580  Cudd_RecursiveDeref(dd, z1);
581  Cudd_RecursiveDeref(dd, z2);
582  Cudd_RecursiveDeref(dd, z3);
583  Cudd_RecursiveDeref(dd, z4);
584  x1 = Cudd_bddIte(dd, x[i], y1_, y2);
585  if (x1 == NULL) {
586  Cudd_RecursiveDeref(dd, y1_);
587  Cudd_RecursiveDeref(dd, y2);
588  return(NULL);
589  }
590  cuddRef(x1);
591  Cudd_RecursiveDeref(dd, y1_);
592  Cudd_RecursiveDeref(dd, y2);
593  }
594  cuddDeref(x1);
595  return(Cudd_Not(x1));
596 
597 } /* end of Cudd_Dxygtdxz */
598 
599 
600 /**Function********************************************************************
601 
602  Synopsis [Generates a BDD for the function d(x,y) &gt; d(y,z).]
603 
604  Description [This function generates a BDD for the function d(x,y)
605  &gt; d(y,z);
606  x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\],
607  y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\],
608  with 0 the most significant bit.
609  The distance d(x,y) is defined as:
610  \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}).
611  The BDD is built bottom-up.
612  It has 7*N-3 internal nodes, if the variables are ordered as follows:
613  x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]
614 
615  SideEffects [None]
616 
617  SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX]
618 
619 ******************************************************************************/
620 DdNode *
622  DdManager * dd /* DD manager */,
623  int N /* number of x, y, and z variables */,
624  DdNode ** x /* array of x variables */,
625  DdNode ** y /* array of y variables */,
626  DdNode ** z /* array of z variables */)
627 {
628  DdNode *one, *zero;
629  DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
630  int i;
631 
632  one = DD_ONE(dd);
633  zero = Cudd_Not(one);
634 
635  /* Build bottom part of BDD outside loop. */
636  y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]);
637  if (y1_ == NULL) return(NULL);
638  cuddRef(y1_);
639  y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero);
640  if (y2 == NULL) {
641  Cudd_RecursiveDeref(dd, y1_);
642  return(NULL);
643  }
644  cuddRef(y2);
645  x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2));
646  if (x1 == NULL) {
647  Cudd_RecursiveDeref(dd, y1_);
648  Cudd_RecursiveDeref(dd, y2);
649  return(NULL);
650  }
651  cuddRef(x1);
652  Cudd_RecursiveDeref(dd, y1_);
653  Cudd_RecursiveDeref(dd, y2);
654 
655  /* Loop to build the rest of the BDD. */
656  for (i = N-2; i >= 0; i--) {
657  z1 = Cudd_bddIte(dd, z[i], x1, zero);
658  if (z1 == NULL) {
659  Cudd_RecursiveDeref(dd, x1);
660  return(NULL);
661  }
662  cuddRef(z1);
663  z2 = Cudd_bddIte(dd, z[i], x1, one);
664  if (z2 == NULL) {
665  Cudd_RecursiveDeref(dd, x1);
666  Cudd_RecursiveDeref(dd, z1);
667  return(NULL);
668  }
669  cuddRef(z2);
670  z3 = Cudd_bddIte(dd, z[i], one, x1);
671  if (z3 == NULL) {
672  Cudd_RecursiveDeref(dd, x1);
673  Cudd_RecursiveDeref(dd, z1);
674  Cudd_RecursiveDeref(dd, z2);
675  return(NULL);
676  }
677  cuddRef(z3);
678  z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1));
679  if (z4 == NULL) {
680  Cudd_RecursiveDeref(dd, x1);
681  Cudd_RecursiveDeref(dd, z1);
682  Cudd_RecursiveDeref(dd, z2);
683  Cudd_RecursiveDeref(dd, z3);
684  return(NULL);
685  }
686  cuddRef(z4);
687  Cudd_RecursiveDeref(dd, x1);
688  y1_ = Cudd_bddIte(dd, y[i], z2, z1);
689  if (y1_ == NULL) {
690  Cudd_RecursiveDeref(dd, z1);
691  Cudd_RecursiveDeref(dd, z2);
692  Cudd_RecursiveDeref(dd, z3);
693  Cudd_RecursiveDeref(dd, z4);
694  return(NULL);
695  }
696  cuddRef(y1_);
697  y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3));
698  if (y2 == NULL) {
699  Cudd_RecursiveDeref(dd, z1);
700  Cudd_RecursiveDeref(dd, z2);
701  Cudd_RecursiveDeref(dd, z3);
702  Cudd_RecursiveDeref(dd, z4);
703  Cudd_RecursiveDeref(dd, y1_);
704  return(NULL);
705  }
706  cuddRef(y2);
707  Cudd_RecursiveDeref(dd, z1);
708  Cudd_RecursiveDeref(dd, z2);
709  Cudd_RecursiveDeref(dd, z3);
710  Cudd_RecursiveDeref(dd, z4);
711  x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2));
712  if (x1 == NULL) {
713  Cudd_RecursiveDeref(dd, y1_);
714  Cudd_RecursiveDeref(dd, y2);
715  return(NULL);
716  }
717  cuddRef(x1);
718  Cudd_RecursiveDeref(dd, y1_);
719  Cudd_RecursiveDeref(dd, y2);
720  }
721  cuddDeref(x1);
722  return(Cudd_Not(x1));
723 
724 } /* end of Cudd_Dxygtdyz */
725 
726 
727 /**Function********************************************************************
728 
729  Synopsis [Generates a BDD for the function x - y &ge; c.]
730 
731  Description [This function generates a BDD for the function x -y &ge; c.
732  Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
733  y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
734  The BDD is built bottom-up.
735  It has a linear number of nodes if the variables are ordered as follows:
736  x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].]
737 
738  SideEffects [None]
739 
740  SeeAlso [Cudd_Xgty]
741 
742 ******************************************************************************/
743 DdNode *
745  DdManager * dd /* DD manager */,
746  int N /* number of x and y variables */,
747  int c /* right-hand side constant */,
748  DdNode ** x /* array of x variables */,
749  DdNode ** y /* array of y variables */)
750 {
751  /* The nodes at level i represent values of the difference that are
752  ** multiples of 2^i. We use variables with names starting with k
753  ** to denote the multipliers of 2^i in such multiples. */
754  int kTrue = c;
755  int kFalse = c - 1;
756  /* Mask used to compute the ceiling function. Since we divide by 2^i,
757  ** we want to know whether the dividend is a multiple of 2^i. If it is,
758  ** then ceiling and floor coincide; otherwise, they differ by one. */
759  int mask = 1;
760  int i;
761 
762  DdNode *f = NULL; /* the eventual result */
763  DdNode *one = DD_ONE(dd);
764  DdNode *zero = Cudd_Not(one);
765 
766  /* Two x-labeled nodes are created at most at each iteration. They are
767  ** stored, along with their k values, in these variables. At each level,
768  ** the old nodes are freed and the new nodes are copied into the old map.
769  */
770  DdNode *map[2] = {0};
771  int invalidIndex = 1 << (N-1);
772  int index[2] = {invalidIndex, invalidIndex};
773 
774  /* This should never happen. */
775  if (N < 0) return(NULL);
776 
777  /* If there are no bits, both operands are 0. The result depends on c. */
778  if (N == 0) {
779  if (c >= 0) return(one);
780  else return(zero);
781  }
782 
783  /* The maximum or the minimum difference comparing to c can generate the terminal case */
784  if ((1 << N) - 1 < c) return(zero);
785  else if ((-(1 << N) + 1) >= c) return(one);
786 
787  /* Build the result bottom up. */
788  for (i = 1; i <= N; i++) {
789  int kTrueLower, kFalseLower;
790  int leftChild, middleChild, rightChild;
791  DdNode *g0, *g1, *fplus, *fequal, *fminus;
792  int j;
793  DdNode *newMap[2] = {NULL};
794  int newIndex[2];
795 
796  kTrueLower = kTrue;
797  kFalseLower = kFalse;
798  /* kTrue = ceiling((c-1)/2^i) + 1 */
799  kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1;
800  mask = (mask << 1) | 1;
801  /* kFalse = floor(c/2^i) - 1 */
802  kFalse = (c >> i) - 1;
803  newIndex[0] = invalidIndex;
804  newIndex[1] = invalidIndex;
805 
806  for (j = kFalse + 1; j < kTrue; j++) {
807  /* Skip if node is not reachable from top of BDD. */
808  if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue;
809 
810  /* Find f- */
811  leftChild = (j << 1) - 1;
812  if (leftChild >= kTrueLower) {
813  fminus = one;
814  } else if (leftChild <= kFalseLower) {
815  fminus = zero;
816  } else {
817  assert(leftChild == index[0] || leftChild == index[1]);
818  if (leftChild == index[0]) {
819  fminus = map[0];
820  } else {
821  fminus = map[1];
822  }
823  }
824 
825  /* Find f= */
826  middleChild = j << 1;
827  if (middleChild >= kTrueLower) {
828  fequal = one;
829  } else if (middleChild <= kFalseLower) {
830  fequal = zero;
831  } else {
832  assert(middleChild == index[0] || middleChild == index[1]);
833  if (middleChild == index[0]) {
834  fequal = map[0];
835  } else {
836  fequal = map[1];
837  }
838  }
839 
840  /* Find f+ */
841  rightChild = (j << 1) + 1;
842  if (rightChild >= kTrueLower) {
843  fplus = one;
844  } else if (rightChild <= kFalseLower) {
845  fplus = zero;
846  } else {
847  assert(rightChild == index[0] || rightChild == index[1]);
848  if (rightChild == index[0]) {
849  fplus = map[0];
850  } else {
851  fplus = map[1];
852  }
853  }
854 
855  /* Build new nodes. */
856  g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus);
857  if (g1 == NULL) {
858  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
859  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
860  if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
861  if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
862  return(NULL);
863  }
864  cuddRef(g1);
865  g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal);
866  if (g0 == NULL) {
867  Cudd_IterDerefBdd(dd, g1);
868  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
869  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
870  if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
871  if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
872  return(NULL);
873  }
874  cuddRef(g0);
875  f = Cudd_bddIte(dd, x[N - i], g1, g0);
876  if (f == NULL) {
877  Cudd_IterDerefBdd(dd, g1);
878  Cudd_IterDerefBdd(dd, g0);
879  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
880  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
881  if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
882  if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
883  return(NULL);
884  }
885  cuddRef(f);
886  Cudd_IterDerefBdd(dd, g1);
887  Cudd_IterDerefBdd(dd, g0);
888 
889  /* Save newly computed node in map. */
890  assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex);
891  if (newIndex[0] == invalidIndex) {
892  newIndex[0] = j;
893  newMap[0] = f;
894  } else {
895  newIndex[1] = j;
896  newMap[1] = f;
897  }
898  }
899 
900  /* Copy new map to map. */
901  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
902  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
903  map[0] = newMap[0];
904  map[1] = newMap[1];
905  index[0] = newIndex[0];
906  index[1] = newIndex[1];
907  }
908 
909  cuddDeref(f);
910  return(f);
911 
912 } /* end of Cudd_Inequality */
913 
914 
915 /**Function********************************************************************
916 
917  Synopsis [Generates a BDD for the function x - y != c.]
918 
919  Description [This function generates a BDD for the function x -y != c.
920  Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and
921  y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit.
922  The BDD is built bottom-up.
923  It has a linear number of nodes if the variables are ordered as follows:
924  x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].]
925 
926  SideEffects [None]
927 
928  SeeAlso [Cudd_Xgty]
929 
930 ******************************************************************************/
931 DdNode *
933  DdManager * dd /* DD manager */,
934  int N /* number of x and y variables */,
935  int c /* right-hand side constant */,
936  DdNode ** x /* array of x variables */,
937  DdNode ** y /* array of y variables */)
938 {
939  /* The nodes at level i represent values of the difference that are
940  ** multiples of 2^i. We use variables with names starting with k
941  ** to denote the multipliers of 2^i in such multiples. */
942  int kTrueLb = c + 1;
943  int kTrueUb = c - 1;
944  int kFalse = c;
945  /* Mask used to compute the ceiling function. Since we divide by 2^i,
946  ** we want to know whether the dividend is a multiple of 2^i. If it is,
947  ** then ceiling and floor coincide; otherwise, they differ by one. */
948  int mask = 1;
949  int i;
950 
951  DdNode *f = NULL; /* the eventual result */
952  DdNode *one = DD_ONE(dd);
953  DdNode *zero = Cudd_Not(one);
954 
955  /* Two x-labeled nodes are created at most at each iteration. They are
956  ** stored, along with their k values, in these variables. At each level,
957  ** the old nodes are freed and the new nodes are copied into the old map.
958  */
959  DdNode *map[2] = {0};
960  int invalidIndex = 1 << (N-1);
961  int index[2] = {invalidIndex, invalidIndex};
962 
963  /* This should never happen. */
964  if (N < 0) return(NULL);
965 
966  /* If there are no bits, both operands are 0. The result depends on c. */
967  if (N == 0) {
968  if (c != 0) return(one);
969  else return(zero);
970  }
971 
972  /* The maximum or the minimum difference comparing to c can generate the terminal case */
973  if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one);
974 
975  /* Build the result bottom up. */
976  for (i = 1; i <= N; i++) {
977  int kTrueLbLower, kTrueUbLower;
978  int leftChild, middleChild, rightChild;
979  DdNode *g0, *g1, *fplus, *fequal, *fminus;
980  int j;
981  DdNode *newMap[2] = {NULL};
982  int newIndex[2];
983 
984  kTrueLbLower = kTrueLb;
985  kTrueUbLower = kTrueUb;
986  /* kTrueLb = floor((c-1)/2^i) + 2 */
987  kTrueLb = ((c-1) >> i) + 2;
988  /* kTrueUb = ceiling((c+1)/2^i) - 2 */
989  kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2;
990  mask = (mask << 1) | 1;
991  newIndex[0] = invalidIndex;
992  newIndex[1] = invalidIndex;
993 
994  for (j = kTrueUb + 1; j < kTrueLb; j++) {
995  /* Skip if node is not reachable from top of BDD. */
996  if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue;
997 
998  /* Find f- */
999  leftChild = (j << 1) - 1;
1000  if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) {
1001  fminus = one;
1002  } else if (i == 1 && leftChild == kFalse) {
1003  fminus = zero;
1004  } else {
1005  assert(leftChild == index[0] || leftChild == index[1]);
1006  if (leftChild == index[0]) {
1007  fminus = map[0];
1008  } else {
1009  fminus = map[1];
1010  }
1011  }
1012 
1013  /* Find f= */
1014  middleChild = j << 1;
1015  if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) {
1016  fequal = one;
1017  } else if (i == 1 && middleChild == kFalse) {
1018  fequal = zero;
1019  } else {
1020  assert(middleChild == index[0] || middleChild == index[1]);
1021  if (middleChild == index[0]) {
1022  fequal = map[0];
1023  } else {
1024  fequal = map[1];
1025  }
1026  }
1027 
1028  /* Find f+ */
1029  rightChild = (j << 1) + 1;
1030  if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) {
1031  fplus = one;
1032  } else if (i == 1 && rightChild == kFalse) {
1033  fplus = zero;
1034  } else {
1035  assert(rightChild == index[0] || rightChild == index[1]);
1036  if (rightChild == index[0]) {
1037  fplus = map[0];
1038  } else {
1039  fplus = map[1];
1040  }
1041  }
1042 
1043  /* Build new nodes. */
1044  g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus);
1045  if (g1 == NULL) {
1046  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
1047  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
1048  if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
1049  if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
1050  return(NULL);
1051  }
1052  cuddRef(g1);
1053  g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal);
1054  if (g0 == NULL) {
1055  Cudd_IterDerefBdd(dd, g1);
1056  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
1057  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
1058  if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
1059  if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
1060  return(NULL);
1061  }
1062  cuddRef(g0);
1063  f = Cudd_bddIte(dd, x[N - i], g1, g0);
1064  if (f == NULL) {
1065  Cudd_IterDerefBdd(dd, g1);
1066  Cudd_IterDerefBdd(dd, g0);
1067  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
1068  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
1069  if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
1070  if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
1071  return(NULL);
1072  }
1073  cuddRef(f);
1074  Cudd_IterDerefBdd(dd, g1);
1075  Cudd_IterDerefBdd(dd, g0);
1076 
1077  /* Save newly computed node in map. */
1078  assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex);
1079  if (newIndex[0] == invalidIndex) {
1080  newIndex[0] = j;
1081  newMap[0] = f;
1082  } else {
1083  newIndex[1] = j;
1084  newMap[1] = f;
1085  }
1086  }
1087 
1088  /* Copy new map to map. */
1089  if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
1090  if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
1091  map[0] = newMap[0];
1092  map[1] = newMap[1];
1093  index[0] = newIndex[0];
1094  index[1] = newIndex[1];
1095  }
1096 
1097  cuddDeref(f);
1098  return(f);
1099 
1100 } /* end of Cudd_Disequality */
1101 
1102 
1103 /**Function********************************************************************
1104 
1105  Synopsis [Generates a BDD for the function lowerB &le; x &le; upperB.]
1106 
1107  Description [This function generates a BDD for the function
1108  lowerB &le; x &le; upperB, where x is an N-bit number,
1109  x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!).
1110  The number of variables N should be sufficient to represent the bounds;
1111  otherwise, the bounds are truncated to their N least significant bits.
1112  Two BDDs are built bottom-up for lowerB &le; x and x &le; upperB, and they
1113  are finally conjoined.]
1114 
1115  SideEffects [None]
1116 
1117  SeeAlso [Cudd_Xgty]
1118 
1119 ******************************************************************************/
1120 DdNode *
1122  DdManager * dd /* DD manager */,
1123  int N /* number of x variables */,
1124  DdNode ** x /* array of x variables */,
1125  unsigned int lowerB /* lower bound */,
1126  unsigned int upperB /* upper bound */)
1127 {
1128  DdNode *one, *zero;
1129  DdNode *r, *rl, *ru;
1130  int i;
1131 
1132  one = DD_ONE(dd);
1133  zero = Cudd_Not(one);
1134 
1135  rl = one;
1136  cuddRef(rl);
1137  ru = one;
1138  cuddRef(ru);
1139 
1140  /* Loop to build the rest of the BDDs. */
1141  for (i = N-1; i >= 0; i--) {
1142  DdNode *vl, *vu;
1143  vl = Cudd_bddIte(dd, x[i],
1144  lowerB&1 ? rl : one,
1145  lowerB&1 ? zero : rl);
1146  if (vl == NULL) {
1147  Cudd_IterDerefBdd(dd, rl);
1148  Cudd_IterDerefBdd(dd, ru);
1149  return(NULL);
1150  }
1151  cuddRef(vl);
1152  Cudd_IterDerefBdd(dd, rl);
1153  rl = vl;
1154  lowerB >>= 1;
1155  vu = Cudd_bddIte(dd, x[i],
1156  upperB&1 ? ru : zero,
1157  upperB&1 ? one : ru);
1158  if (vu == NULL) {
1159  Cudd_IterDerefBdd(dd, rl);
1160  Cudd_IterDerefBdd(dd, ru);
1161  return(NULL);
1162  }
1163  cuddRef(vu);
1164  Cudd_IterDerefBdd(dd, ru);
1165  ru = vu;
1166  upperB >>= 1;
1167  }
1168 
1169  /* Conjoin the two bounds. */
1170  r = Cudd_bddAnd(dd, rl, ru);
1171  if (r == NULL) {
1172  Cudd_IterDerefBdd(dd, rl);
1173  Cudd_IterDerefBdd(dd, ru);
1174  return(NULL);
1175  }
1176  cuddRef(r);
1177  Cudd_IterDerefBdd(dd, rl);
1178  Cudd_IterDerefBdd(dd, ru);
1179  cuddDeref(r);
1180  return(r);
1181 
1182 } /* end of Cudd_bddInterval */
1183 
1184 
1185 /**Function********************************************************************
1186 
1187  Synopsis [Computes the compatible projection of R w.r.t. cube Y.]
1188 
1189  Description [Computes the compatible projection of relation R with
1190  respect to cube Y. Returns a pointer to the c-projection if
1191  successful; NULL otherwise. For a comparison between Cudd_CProjection
1192  and Cudd_PrioritySelect, see the documentation of the latter.]
1193 
1194  SideEffects [None]
1195 
1196  SeeAlso [Cudd_PrioritySelect]
1197 
1198 ******************************************************************************/
1199 DdNode *
1201  DdManager * dd,
1202  DdNode * R,
1203  DdNode * Y)
1204 {
1205  DdNode *res;
1206  DdNode *support;
1207 
1208  if (cuddCheckCube(dd,Y) == 0) {
1209  (void) fprintf(dd->err,
1210  "Error: The third argument of Cudd_CProjection should be a cube\n");
1212  return(NULL);
1213  }
1214 
1215  /* Compute the support of Y, which is used by the abstraction step
1216  ** in cuddCProjectionRecur.
1217  */
1218  support = Cudd_Support(dd,Y);
1219  if (support == NULL) return(NULL);
1220  cuddRef(support);
1221 
1222  do {
1223  dd->reordered = 0;
1224  res = cuddCProjectionRecur(dd,R,Y,support);
1225  } while (dd->reordered == 1);
1226 
1227  if (res == NULL) {
1228  Cudd_RecursiveDeref(dd,support);
1229  return(NULL);
1230  }
1231  cuddRef(res);
1232  Cudd_RecursiveDeref(dd,support);
1233  cuddDeref(res);
1234 
1235  return(res);
1236 
1237 } /* end of Cudd_CProjection */
1238 
1239 
1240 /**Function********************************************************************
1241 
1242  Synopsis [Computes the Hamming distance ADD.]
1243 
1244  Description [Computes the Hamming distance ADD. Returns an ADD that
1245  gives the Hamming distance between its two arguments if successful;
1246  NULL otherwise. The two vectors xVars and yVars identify the variables
1247  that form the two arguments.]
1248 
1249  SideEffects [None]
1250 
1251  SeeAlso []
1252 
1253 ******************************************************************************/
1254 DdNode *
1256  DdManager * dd,
1257  DdNode ** xVars,
1258  DdNode ** yVars,
1259  int nVars)
1260 {
1261  DdNode *result,*tempBdd;
1262  DdNode *tempAdd,*temp;
1263  int i;
1264 
1265  result = DD_ZERO(dd);
1266  cuddRef(result);
1267 
1268  for (i = 0; i < nVars; i++) {
1269  tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]);
1270  if (tempBdd == NULL) {
1271  Cudd_RecursiveDeref(dd,result);
1272  return(NULL);
1273  }
1274  cuddRef(tempBdd);
1275  tempAdd = Cudd_BddToAdd(dd,tempBdd);
1276  if (tempAdd == NULL) {
1277  Cudd_RecursiveDeref(dd,tempBdd);
1278  Cudd_RecursiveDeref(dd,result);
1279  return(NULL);
1280  }
1281  cuddRef(tempAdd);
1282  Cudd_RecursiveDeref(dd,tempBdd);
1283  temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result);
1284  if (temp == NULL) {
1285  Cudd_RecursiveDeref(dd,tempAdd);
1286  Cudd_RecursiveDeref(dd,result);
1287  return(NULL);
1288  }
1289  cuddRef(temp);
1290  Cudd_RecursiveDeref(dd,tempAdd);
1291  Cudd_RecursiveDeref(dd,result);
1292  result = temp;
1293  }
1294 
1295  cuddDeref(result);
1296  return(result);
1297 
1298 } /* end of Cudd_addHamming */
1299 
1300 
1301 /**Function********************************************************************
1302 
1303  Synopsis [Returns the minimum Hamming distance between f and minterm.]
1304 
1305  Description [Returns the minimum Hamming distance between the
1306  minterms of a function f and a reference minterm. The function is
1307  given as a BDD; the minterm is given as an array of integers, one
1308  for each variable in the manager. Returns the minimum distance if
1309  it is less than the upper bound; the upper bound if the minimum
1310  distance is at least as large; CUDD_OUT_OF_MEM in case of failure.]
1311 
1312  SideEffects [None]
1313 
1314  SeeAlso [Cudd_addHamming Cudd_bddClosestCube]
1315 
1316 ******************************************************************************/
1317 int
1319  DdManager *dd /* DD manager */,
1320  DdNode *f /* function to examine */,
1321  int *minterm /* reference minterm */,
1322  int upperBound /* distance above which an approximate answer is OK */)
1323 {
1324  DdHashTable *table;
1325  CUDD_VALUE_TYPE epsilon;
1326  int res;
1327 
1328  table = cuddHashTableInit(dd,1,2);
1329  if (table == NULL) {
1330  return(CUDD_OUT_OF_MEM);
1331  }
1332  epsilon = Cudd_ReadEpsilon(dd);
1334  res = cuddMinHammingDistRecur(f,minterm,table,upperBound);
1335  cuddHashTableQuit(table);
1336  Cudd_SetEpsilon(dd,epsilon);
1337 
1338  return(res);
1339 
1340 } /* end of Cudd_MinHammingDist */
1341 
1342 
1343 /**Function********************************************************************
1344 
1345  Synopsis [Finds a cube of f at minimum Hamming distance from g.]
1346 
1347  Description [Finds a cube of f at minimum Hamming distance from the
1348  minterms of g. All the minterms of the cube are at the minimum
1349  distance. If the distance is 0, the cube belongs to the
1350  intersection of f and g. Returns the cube if successful; NULL
1351  otherwise.]
1352 
1353  SideEffects [The distance is returned as a side effect.]
1354 
1355  SeeAlso [Cudd_MinHammingDist]
1356 
1357 ******************************************************************************/
1358 DdNode *
1360  DdManager *dd,
1361  DdNode * f,
1362  DdNode *g,
1363  int *distance)
1364 {
1365  DdNode *res, *acube;
1366  CUDD_VALUE_TYPE rdist;
1367 
1368  /* Compute the cube and distance as a single ADD. */
1369  do {
1370  dd->reordered = 0;
1371  res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0);
1372  } while (dd->reordered == 1);
1373  if (res == NULL) return(NULL);
1374  cuddRef(res);
1375 
1376  /* Unpack distance and cube. */
1377  do {
1378  dd->reordered = 0;
1379  acube = separateCube(dd, res, &rdist);
1380  } while (dd->reordered == 1);
1381  if (acube == NULL) {
1382  Cudd_RecursiveDeref(dd, res);
1383  return(NULL);
1384  }
1385  cuddRef(acube);
1386  Cudd_RecursiveDeref(dd, res);
1387 
1388  /* Convert cube from ADD to BDD. */
1389  do {
1390  dd->reordered = 0;
1391  res = cuddAddBddDoPattern(dd, acube);
1392  } while (dd->reordered == 1);
1393  if (res == NULL) {
1394  Cudd_RecursiveDeref(dd, acube);
1395  return(NULL);
1396  }
1397  cuddRef(res);
1398  Cudd_RecursiveDeref(dd, acube);
1399 
1400  *distance = (int) rdist;
1401  cuddDeref(res);
1402  return(res);
1403 
1404 } /* end of Cudd_bddClosestCube */
1405 
1406 
1407 /*---------------------------------------------------------------------------*/
1408 /* Definition of internal functions */
1409 /*---------------------------------------------------------------------------*/
1410 
1411 
1412 /**Function********************************************************************
1413 
1414  Synopsis [Performs the recursive step of Cudd_CProjection.]
1415 
1416  Description [Performs the recursive step of Cudd_CProjection. Returns
1417  the projection if successful; NULL otherwise.]
1418 
1419  SideEffects [None]
1420 
1421  SeeAlso [Cudd_CProjection]
1422 
1423 ******************************************************************************/
1424 DdNode *
1426  DdManager * dd,
1427  DdNode * R,
1428  DdNode * Y,
1429  DdNode * Ysupp)
1430 {
1431  DdNode *res, *res1, *res2, *resA;
1432  DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha;
1433  unsigned int topR, topY, top, index = 0;
1434  DdNode *one = DD_ONE(dd);
1435 
1436  statLine(dd);
1437  if (Y == one) return(R);
1438 
1439 #ifdef DD_DEBUG
1440  assert(!Cudd_IsConstant(Y));
1441 #endif
1442 
1443  if (R == Cudd_Not(one)) return(R);
1444 
1445  res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y);
1446  if (res != NULL) return(res);
1447 
1448  r = Cudd_Regular(R);
1449  topR = cuddI(dd,r->index);
1450  y = Cudd_Regular(Y);
1451  topY = cuddI(dd,y->index);
1452 
1453  top = ddMin(topR, topY);
1454 
1455  /* Compute the cofactors of R */
1456  if (topR == top) {
1457  index = r->index;
1458  RT = cuddT(r);
1459  RE = cuddE(r);
1460  if (r != R) {
1461  RT = Cudd_Not(RT); RE = Cudd_Not(RE);
1462  }
1463  } else {
1464  RT = RE = R;
1465  }
1466 
1467  if (topY > top) {
1468  /* Y does not depend on the current top variable.
1469  ** We just need to compute the results on the two cofactors of R
1470  ** and make them the children of a node labeled r->index.
1471  */
1472  res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp);
1473  if (res1 == NULL) return(NULL);
1474  cuddRef(res1);
1475  res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp);
1476  if (res2 == NULL) {
1477  Cudd_RecursiveDeref(dd,res1);
1478  return(NULL);
1479  }
1480  cuddRef(res2);
1481  res = cuddBddIteRecur(dd, dd->vars[index], res1, res2);
1482  if (res == NULL) {
1483  Cudd_RecursiveDeref(dd,res1);
1484  Cudd_RecursiveDeref(dd,res2);
1485  return(NULL);
1486  }
1487  /* If we have reached this point, res1 and res2 are now
1488  ** incorporated in res. cuddDeref is therefore sufficient.
1489  */
1490  cuddDeref(res1);
1491  cuddDeref(res2);
1492  } else {
1493  /* Compute the cofactors of Y */
1494  index = y->index;
1495  YT = cuddT(y);
1496  YE = cuddE(y);
1497  if (y != Y) {
1498  YT = Cudd_Not(YT); YE = Cudd_Not(YE);
1499  }
1500  if (YT == Cudd_Not(one)) {
1501  Alpha = Cudd_Not(dd->vars[index]);
1502  Yrest = YE;
1503  Ra = RE;
1504  Ran = RT;
1505  } else {
1506  Alpha = dd->vars[index];
1507  Yrest = YT;
1508  Ra = RT;
1509  Ran = RE;
1510  }
1511  Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp));
1512  if (Gamma == NULL) return(NULL);
1513  if (Gamma == one) {
1514  res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp));
1515  if (res1 == NULL) return(NULL);
1516  cuddRef(res1);
1517  res = cuddBddAndRecur(dd, Alpha, res1);
1518  if (res == NULL) {
1519  Cudd_RecursiveDeref(dd,res1);
1520  return(NULL);
1521  }
1522  cuddDeref(res1);
1523  } else if (Gamma == Cudd_Not(one)) {
1524  res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp));
1525  if (res1 == NULL) return(NULL);
1526  cuddRef(res1);
1527  res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1);
1528  if (res == NULL) {
1529  Cudd_RecursiveDeref(dd,res1);
1530  return(NULL);
1531  }
1532  cuddDeref(res1);
1533  } else {
1534  cuddRef(Gamma);
1535  resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp));
1536  if (resA == NULL) {
1537  Cudd_RecursiveDeref(dd,Gamma);
1538  return(NULL);
1539  }
1540  cuddRef(resA);
1541  res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA);
1542  if (res2 == NULL) {
1543  Cudd_RecursiveDeref(dd,Gamma);
1544  Cudd_RecursiveDeref(dd,resA);
1545  return(NULL);
1546  }
1547  cuddRef(res2);
1548  Cudd_RecursiveDeref(dd,Gamma);
1549  Cudd_RecursiveDeref(dd,resA);
1550  res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp));
1551  if (res1 == NULL) {
1552  Cudd_RecursiveDeref(dd,res2);
1553  return(NULL);
1554  }
1555  cuddRef(res1);
1556  res = cuddBddIteRecur(dd, Alpha, res1, res2);
1557  if (res == NULL) {
1558  Cudd_RecursiveDeref(dd,res1);
1559  Cudd_RecursiveDeref(dd,res2);
1560  return(NULL);
1561  }
1562  cuddDeref(res1);
1563  cuddDeref(res2);
1564  }
1565  }
1566 
1567  cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res);
1568 
1569  return(res);
1570 
1571 } /* end of cuddCProjectionRecur */
1572 
1573 
1574 /**Function********************************************************************
1575 
1576  Synopsis [Performs the recursive step of Cudd_bddClosestCube.]
1577 
1578  Description [Performs the recursive step of Cudd_bddClosestCube.
1579  Returns the cube if succesful; NULL otherwise. The procedure uses a
1580  four-way recursion to examine all four combinations of cofactors of
1581  <code>f</code> and <code>g</code> according to the following formula.
1582  <pre>
1583  H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
1584  </pre>
1585  Bounding is based on the following observations.
1586  <ul>
1587  <li> If we already found two points at distance 0, there is no point in
1588  continuing. Furthermore,
1589  <li> If F == not(G) then the best we can hope for is a minimum distance
1590  of 1. If we have already found two points at distance 1, there is
1591  no point in continuing. (Indeed, H(F,G) == 1 in this case. We
1592  have to continue, though, to find the cube.)
1593  </ul>
1594  The variable <code>bound</code> is set at the largest value of the distance
1595  that we are still interested in. Therefore, we desist when
1596  <pre>
1597  (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
1598  </pre>
1599  If we were maximally aggressive in using the bound, we would always
1600  set the bound to the minimum distance seen thus far minus one. That
1601  is, we would maintain the invariant
1602  <pre>
1603  bound < minD,
1604  </pre>
1605  except at the very beginning, when we have no value for
1606  <code>minD</code>.<p>
1607 
1608  However, we do not use <code>bound < minD</code> when examining the
1609  two negative cofactors, because we try to find a large cube at
1610  minimum distance. To do so, we try to find a cube in the negative
1611  cofactors at the same or smaller distance from the cube found in the
1612  positive cofactors.<p>
1613 
1614  When we compute <code>H(ft,ge)</code> and <code>H(fe,gt)</code> we
1615  know that we are going to add 1 to the result of the recursive call
1616  to account for the difference in the splitting variable. Therefore,
1617  we decrease the bound correspondingly.<p>
1618 
1619  Another important observation concerns the need of examining all
1620  four pairs of cofators only when both <code>f</code> and
1621  <code>g</code> depend on the top variable.<p>
1622 
1623  Suppose <code>gt == ge == g</code>. (That is, <code>g</code> does
1624  not depend on the top variable.) Then
1625  <pre>
1626  H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
1627  = min(H(ft,g), H(fe,g)) .
1628  </pre>
1629  Therefore, under these circumstances, we skip the two "cross" cases.<p>
1630 
1631  An interesting feature of this function is the scheme used for
1632  caching the results in the global computed table. Since we have a
1633  cube and a distance, we combine them to form an ADD. The
1634  combination replaces the zero child of the top node of the cube with
1635  the negative of the distance. (The use of the negative is to avoid
1636  ambiguity with 1.) The degenerate cases (zero and one) are treated
1637  specially because the distance is known (0 for one, and infinity for
1638  zero).]
1639 
1640  SideEffects [None]
1641 
1642  SeeAlso [Cudd_bddClosestCube]
1643 
1644 ******************************************************************************/
1645 DdNode *
1647  DdManager *dd,
1648  DdNode *f,
1649  DdNode *g,
1650  CUDD_VALUE_TYPE bound)
1651 {
1652  DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee;
1653  DdNode *ctt, *cee, *cte, *cet;
1654  CUDD_VALUE_TYPE minD, dtt, dee, dte, det;
1655  DdNode *one = DD_ONE(dd);
1656  DdNode *lzero = Cudd_Not(one);
1657  DdNode *azero = DD_ZERO(dd);
1658  unsigned int topf, topg, index;
1659 
1660  statLine(dd);
1661  if (bound < (int)(f == Cudd_Not(g))) return(azero);
1662  /* Terminal cases. */
1663  if (g == lzero || f == lzero) return(azero);
1664  if (f == one && g == one) return(one);
1665 
1666  /* Check cache. */
1667  F = Cudd_Regular(f);
1668  G = Cudd_Regular(g);
1669  if (F->ref != 1 || G->ref != 1) {
1670  res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g);
1671  if (res != NULL) return(res);
1672  }
1673 
1674  topf = cuddI(dd,F->index);
1675  topg = cuddI(dd,G->index);
1676 
1677  /* Compute cofactors. */
1678  if (topf <= topg) {
1679  index = F->index;
1680  ft = cuddT(F);
1681  fe = cuddE(F);
1682  if (Cudd_IsComplement(f)) {
1683  ft = Cudd_Not(ft);
1684  fe = Cudd_Not(fe);
1685  }
1686  } else {
1687  index = G->index;
1688  ft = fe = f;
1689  }
1690 
1691  if (topg <= topf) {
1692  gt = cuddT(G);
1693  ge = cuddE(G);
1694  if (Cudd_IsComplement(g)) {
1695  gt = Cudd_Not(gt);
1696  ge = Cudd_Not(ge);
1697  }
1698  } else {
1699  gt = ge = g;
1700  }
1701 
1702  tt = cuddBddClosestCube(dd,ft,gt,bound);
1703  if (tt == NULL) return(NULL);
1704  cuddRef(tt);
1705  ctt = separateCube(dd,tt,&dtt);
1706  if (ctt == NULL) {
1707  Cudd_RecursiveDeref(dd, tt);
1708  return(NULL);
1709  }
1710  cuddRef(ctt);
1711  Cudd_RecursiveDeref(dd, tt);
1712  minD = dtt;
1713  bound = ddMin(bound,minD);
1714 
1715  ee = cuddBddClosestCube(dd,fe,ge,bound);
1716  if (ee == NULL) {
1717  Cudd_RecursiveDeref(dd, ctt);
1718  return(NULL);
1719  }
1720  cuddRef(ee);
1721  cee = separateCube(dd,ee,&dee);
1722  if (cee == NULL) {
1723  Cudd_RecursiveDeref(dd, ctt);
1724  Cudd_RecursiveDeref(dd, ee);
1725  return(NULL);
1726  }
1727  cuddRef(cee);
1728  Cudd_RecursiveDeref(dd, ee);
1729  minD = ddMin(dtt, dee);
1730  if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1);
1731 
1732  if (minD > 0 && topf == topg) {
1733  DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1);
1734  if (te == NULL) {
1735  Cudd_RecursiveDeref(dd, ctt);
1736  Cudd_RecursiveDeref(dd, cee);
1737  return(NULL);
1738  }
1739  cuddRef(te);
1740  cte = separateCube(dd,te,&dte);
1741  if (cte == NULL) {
1742  Cudd_RecursiveDeref(dd, ctt);
1743  Cudd_RecursiveDeref(dd, cee);
1744  Cudd_RecursiveDeref(dd, te);
1745  return(NULL);
1746  }
1747  cuddRef(cte);
1748  Cudd_RecursiveDeref(dd, te);
1749  dte += 1.0;
1750  minD = ddMin(minD, dte);
1751  } else {
1752  cte = azero;
1753  cuddRef(cte);
1754  dte = CUDD_CONST_INDEX + 1.0;
1755  }
1756  if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1);
1757 
1758  if (minD > 0 && topf == topg) {
1759  DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1);
1760  if (et == NULL) {
1761  Cudd_RecursiveDeref(dd, ctt);
1762  Cudd_RecursiveDeref(dd, cee);
1763  Cudd_RecursiveDeref(dd, cte);
1764  return(NULL);
1765  }
1766  cuddRef(et);
1767  cet = separateCube(dd,et,&det);
1768  if (cet == NULL) {
1769  Cudd_RecursiveDeref(dd, ctt);
1770  Cudd_RecursiveDeref(dd, cee);
1771  Cudd_RecursiveDeref(dd, cte);
1772  Cudd_RecursiveDeref(dd, et);
1773  return(NULL);
1774  }
1775  cuddRef(cet);
1776  Cudd_RecursiveDeref(dd, et);
1777  det += 1.0;
1778  minD = ddMin(minD, det);
1779  } else {
1780  cet = azero;
1781  cuddRef(cet);
1782  det = CUDD_CONST_INDEX + 1.0;
1783  }
1784 
1785  if (minD == dtt) {
1786  if (dtt == dee && ctt == cee) {
1787  res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt);
1788  } else {
1789  res = createResult(dd,index,1,ctt,dtt);
1790  }
1791  } else if (minD == dee) {
1792  res = createResult(dd,index,0,cee,dee);
1793  } else if (minD == dte) {
1794 #ifdef DD_DEBUG
1795  assert(topf == topg);
1796 #endif
1797  res = createResult(dd,index,1,cte,dte);
1798  } else {
1799 #ifdef DD_DEBUG
1800  assert(topf == topg);
1801 #endif
1802  res = createResult(dd,index,0,cet,det);
1803  }
1804  if (res == NULL) {
1805  Cudd_RecursiveDeref(dd, ctt);
1806  Cudd_RecursiveDeref(dd, cee);
1807  Cudd_RecursiveDeref(dd, cte);
1808  Cudd_RecursiveDeref(dd, cet);
1809  return(NULL);
1810  }
1811  cuddRef(res);
1812  Cudd_RecursiveDeref(dd, ctt);
1813  Cudd_RecursiveDeref(dd, cee);
1814  Cudd_RecursiveDeref(dd, cte);
1815  Cudd_RecursiveDeref(dd, cet);
1816 
1817  /* Only cache results that are different from azero to avoid
1818  ** storing results that depend on the value of the bound. */
1819  if ((F->ref != 1 || G->ref != 1) && res != azero)
1820  cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res);
1821 
1822  cuddDeref(res);
1823  return(res);
1824 
1825 } /* end of cuddBddClosestCube */
1826 
1827 
1828 /*---------------------------------------------------------------------------*/
1829 /* Definition of static functions */
1830 /*---------------------------------------------------------------------------*/
1831 
1832 
1833 /**Function********************************************************************
1834 
1835  Synopsis [Performs the recursive step of Cudd_MinHammingDist.]
1836 
1837  Description [Performs the recursive step of Cudd_MinHammingDist.
1838  It is based on the following identity. Let H(f) be the
1839  minimum Hamming distance of the minterms of f from the reference
1840  minterm. Then:
1841  <xmp>
1842  H(f) = min(H(f0)+h0,H(f1)+h1)
1843  </xmp>
1844  where f0 and f1 are the two cofactors of f with respect to its top
1845  variable; h0 is 1 if the minterm assigns 1 to the top variable of f;
1846  h1 is 1 if the minterm assigns 0 to the top variable of f.
1847  The upper bound on the distance is used to bound the depth of the
1848  recursion.
1849  Returns the minimum distance unless it exceeds the upper bound or
1850  computation fails.]
1851 
1852  SideEffects [None]
1853 
1854  SeeAlso [Cudd_MinHammingDist]
1855 
1856 ******************************************************************************/
1857 static int
1859  DdNode * f,
1860  int *minterm,
1861  DdHashTable * table,
1862  int upperBound)
1863 {
1864  DdNode *F, *Ft, *Fe;
1865  double h, hT, hE;
1866  DdNode *zero, *res;
1867  DdManager *dd = table->manager;
1868 
1869  statLine(dd);
1870  if (upperBound == 0) return(0);
1871 
1872  F = Cudd_Regular(f);
1873 
1874  if (cuddIsConstant(F)) {
1875  zero = Cudd_Not(DD_ONE(dd));
1876  if (f == dd->background || f == zero) {
1877  return(upperBound);
1878  } else {
1879  return(0);
1880  }
1881  }
1882  if ((res = cuddHashTableLookup1(table,f)) != NULL) {
1883  h = cuddV(res);
1884  if (res->ref == 0) {
1885  dd->dead++;
1886  dd->constants.dead++;
1887  }
1888  return((int) h);
1889  }
1890 
1891  Ft = cuddT(F); Fe = cuddE(F);
1892  if (Cudd_IsComplement(f)) {
1893  Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe);
1894  }
1895  if (minterm[F->index] == 0) {
1896  DdNode *temp = Ft;
1897  Ft = Fe; Fe = temp;
1898  }
1899 
1900  hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound);
1901  if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
1902  if (hT == 0) {
1903  hE = upperBound;
1904  } else {
1905  hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1);
1906  if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
1907  }
1908  h = ddMin(hT, hE + 1);
1909 
1910  if (F->ref != 1) {
1911  ptrint fanout = (ptrint) F->ref;
1912  cuddSatDec(fanout);
1913  res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h);
1914  if (!cuddHashTableInsert1(table,f,res,fanout)) {
1915  cuddRef(res); Cudd_RecursiveDeref(dd, res);
1916  return(CUDD_OUT_OF_MEM);
1917  }
1918  }
1919 
1920  return((int) h);
1921 
1922 } /* end of cuddMinHammingDistRecur */
1923 
1924 
1925 /**Function********************************************************************
1926 
1927  Synopsis [Separates cube from distance.]
1928 
1929  Description [Separates cube from distance. Returns the cube if
1930  successful; NULL otherwise.]
1931 
1932  SideEffects [The distance is returned as a side effect.]
1933 
1934  SeeAlso [cuddBddClosestCube createResult]
1935 
1936 ******************************************************************************/
1937 static DdNode *
1939  DdManager *dd,
1940  DdNode *f,
1941  CUDD_VALUE_TYPE *distance)
1942 {
1943  DdNode *cube, *t;
1944 
1945  /* One and zero are special cases because the distance is implied. */
1946  if (Cudd_IsConstant(f)) {
1947  *distance = (f == DD_ONE(dd)) ? 0.0 :
1949  return(f);
1950  }
1951 
1952  /* Find out which branch points to the distance and replace the top
1953  ** node with one pointing to zero instead. */
1954  t = cuddT(f);
1955  if (Cudd_IsConstant(t) && cuddV(t) <= 0) {
1956 #ifdef DD_DEBUG
1957  assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd));
1958 #endif
1959  *distance = -cuddV(t);
1960  cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f));
1961  } else {
1962 #ifdef DD_DEBUG
1963  assert(!Cudd_IsConstant(t) || t == DD_ONE(dd));
1964 #endif
1965  *distance = -cuddV(cuddE(f));
1966  cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd));
1967  }
1968 
1969  return(cube);
1970 
1971 } /* end of separateCube */
1972 
1973 
1974 /**Function********************************************************************
1975 
1976  Synopsis [Builds a result for cache storage.]
1977 
1978  Description [Builds a result for cache storage. Returns a pointer
1979  to the resulting ADD if successful; NULL otherwise.]
1980 
1981  SideEffects [None]
1982 
1983  SeeAlso [cuddBddClosestCube separateCube]
1984 
1985 ******************************************************************************/
1986 static DdNode *
1988  DdManager *dd,
1989  unsigned int index,
1990  unsigned int phase,
1991  DdNode *cube,
1992  CUDD_VALUE_TYPE distance)
1993 {
1994  DdNode *res, *constant;
1995 
1996  /* Special case. The cube is either one or zero, and we do not
1997  ** add any variables. Hence, the result is also one or zero,
1998  ** and the distance remains implied by the value of the constant. */
1999  if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube);
2000 
2001  constant = cuddUniqueConst(dd,-distance);
2002  if (constant == NULL) return(NULL);
2003  cuddRef(constant);
2004 
2005  if (index == CUDD_CONST_INDEX) {
2006  /* Replace the top node. */
2007  if (cuddT(cube) == DD_ZERO(dd)) {
2008  res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube));
2009  } else {
2010  res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant);
2011  }
2012  } else {
2013  /* Add a new top node. */
2014 #ifdef DD_DEBUG
2015  assert(cuddI(dd,index) < cuddI(dd,cube->index));
2016 #endif
2017  if (phase) {
2018  res = cuddUniqueInter(dd,index,cube,constant);
2019  } else {
2020  res = cuddUniqueInter(dd,index,constant,cube);
2021  }
2022  }
2023  if (res == NULL) {
2024  Cudd_RecursiveDeref(dd, constant);
2025  return(NULL);
2026  }
2027  cuddDeref(constant); /* safe because constant is part of res */
2028 
2029  return(res);
2030 
2031 } /* end of createResult */
2032 
2033 
2035 
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdNode * Cudd_Disequality(DdManager *dd, int N, int c, DdNode **x, DdNode **y)
Definition: cuddPriority.c:932
DdHalfWord ref
Definition: cudd.h:280
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
DdNode * Cudd_bddClosestCube(DdManager *dd, DdNode *f, DdNode *g, int *distance)
#define cuddRef(n)
Definition: cuddInt.h:584
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
DdNode * Cudd_addHamming(DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars)
int Cudd_MinHammingDist(DdManager *dd, DdNode *f, int *minterm, int upperBound)
Definition: cudd.h:278
#define z1
Definition: extraBdd.h:78
#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
DdNode * Cudd_Inequality(DdManager *dd, int N, int c, DdNode **x, DdNode **y)
Definition: cuddPriority.c:744
DdNode * Cudd_PrioritySelect(DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DD_PRFP Pifunc)
Definition: cuddPriority.c:175
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:740
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
DdManager * manager
Definition: cuddInt.h:313
int size
Definition: cuddInt.h:361
DdNode * Cudd_Xeqy(DdManager *dd, int N, DdNode **x, DdNode **y)
Definition: cuddPriority.c:345
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
int cuddCheckCube(DdManager *dd, DdNode *g)
Definition: cuddCof.c:193
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
void map()
DdNode * Cudd_Xgty(DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y)
Definition: cuddPriority.c:280
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * Cudd_addApply(DdManager *dd, DdNode *(*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)
DdNode * Cudd_bddSwapVariables(DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)
Definition: cuddCompose.c:464
DdNode * Cudd_bddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:143
static int cuddMinHammingDistRecur(DdNode *f, int *minterm, DdHashTable *table, int upperBound)
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
Definition: cuddLCache.c:819
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCProjectionRecur(DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp)
static DdNode * separateCube(DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance)
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
int reordered
Definition: cuddInt.h:409
unsigned int dead
Definition: cuddInt.h:371
#define Cudd_IsComplement(node)
Definition: cudd.h:425
void Cudd_SetEpsilon(DdManager *dd, CUDD_VALUE_TYPE ep)
Definition: cuddAPI.c:2451
static char rcsid[] DD_UNUSED
Definition: cuddPriority.c:105
unsigned int dead
Definition: cuddInt.h:332
static DdNode * one
Definition: cuddDecomp.c:112
ABC_PTRINT_T ptrint
Definition: cuddInt.h:260
DdNode * cuddAddBddDoPattern(DdManager *dd, DdNode *f)
Definition: cuddBridge.c:493
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_BddToAdd(DdManager *dd, DdNode *B)
Definition: cuddBridge.c:349
#define CUDD_CONST_INDEX
Definition: cudd.h:117
DdNode * Cudd_bddAndAbstract(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddAndAbs.c:124
#define ddMin(x, y)
Definition: cuddInt.h:818
void cuddHashTableQuit(DdHashTable *hash)
Definition: cuddLCache.c:595
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_Dxygtdxz(DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)
Definition: cuddPriority.c:494
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define cuddI(dd, index)
Definition: cuddInt.h:686
static pcube phase
Definition: cvrm.c:405
DdNode * Cudd_Dxygtdyz(DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)
Definition: cuddPriority.c:621
DdNode * Cudd_addIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:129
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
DdNode * Cudd_addXeqy(DdManager *dd, int N, DdNode **x, DdNode **y)
Definition: cuddPriority.c:408
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
Definition: cuddLCache.c:767
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
DdNode * Cudd_CProjection(DdManager *dd, DdNode *R, DdNode *Y)
DdNode * one
Definition: cuddInt.h:345
#define CUDD_MAXINDEX
Definition: cudd.h:112
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define cuddSatDec(x)
Definition: cuddInt.h:896
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
Definition: cuddLCache.c:538
DdNode * cuddBddClosestCube(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound)
#define assert(ex)
Definition: util_old.h:213
DdSubtable constants
Definition: cuddInt.h:367
static int result
Definition: cuddGenetic.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:911
static DdNode * createResult(DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance)
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
CUDD_VALUE_TYPE Cudd_ReadEpsilon(DdManager *dd)
Definition: cuddAPI.c:2430
static DdNode * zero
Definition: cuddApa.c:100
DdNode * Cudd_bddInterval(DdManager *dd, int N, DdNode **x, unsigned int lowerB, unsigned int upperB)
DdNode * background
Definition: cuddInt.h:349
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
DdNode *(* DD_PRFP)(DdManager *, int, DdNode **, DdNode **, DdNode **)
Definition: cudd.h:314