abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddCof.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddCof.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Cofactoring functions.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_Cofactor()
12  </ul>
13  Internal procedures included in this module:
14  <ul>
15  <li> cuddGetBranches()
16  <li> cuddCheckCube()
17  <li> cuddCofactorRecur()
18  </ul>
19  ]
20 
21  SeeAlso []
22 
23  Author [Fabio Somenzi]
24 
25  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
26 
27  All rights reserved.
28 
29  Redistribution and use in source and binary forms, with or without
30  modification, are permitted provided that the following conditions
31  are met:
32 
33  Redistributions of source code must retain the above copyright
34  notice, this list of conditions and the following disclaimer.
35 
36  Redistributions in binary form must reproduce the above copyright
37  notice, this list of conditions and the following disclaimer in the
38  documentation and/or other materials provided with the distribution.
39 
40  Neither the name of the University of Colorado nor the names of its
41  contributors may be used to endorse or promote products derived from
42  this software without specific prior written permission.
43 
44  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
47  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
48  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
49  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
50  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
54  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55  POSSIBILITY OF SUCH DAMAGE.]
56 
57 ******************************************************************************/
58 
59 #include "misc/util/util_hack.h"
60 #include "cuddInt.h"
61 
63 
64 
65 
66 /*---------------------------------------------------------------------------*/
67 /* Constant declarations */
68 /*---------------------------------------------------------------------------*/
69 
70 
71 /*---------------------------------------------------------------------------*/
72 /* Stucture declarations */
73 /*---------------------------------------------------------------------------*/
74 
75 
76 /*---------------------------------------------------------------------------*/
77 /* Type declarations */
78 /*---------------------------------------------------------------------------*/
79 
80 
81 /*---------------------------------------------------------------------------*/
82 /* Variable declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 #ifndef lint
86 static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.9 2004/08/13 18:04:47 fabio Exp $";
87 #endif
88 
89 /*---------------------------------------------------------------------------*/
90 /* Macro declarations */
91 /*---------------------------------------------------------------------------*/
92 
93 
94 /**AutomaticStart*************************************************************/
95 
96 /*---------------------------------------------------------------------------*/
97 /* Static function prototypes */
98 /*---------------------------------------------------------------------------*/
99 
100 
101 /**AutomaticEnd***************************************************************/
102 
103 
104 /*---------------------------------------------------------------------------*/
105 /* Definition of exported functions */
106 /*---------------------------------------------------------------------------*/
107 
108 
109 /**Function********************************************************************
110 
111  Synopsis [Computes the cofactor of f with respect to g.]
112 
113  Description [Computes the cofactor of f with respect to g; g must be
114  the BDD or the ADD of a cube. Returns a pointer to the cofactor if
115  successful; NULL otherwise.]
116 
117  SideEffects [None]
118 
119  SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]
120 
121 ******************************************************************************/
122 DdNode *
124  DdManager * dd,
125  DdNode * f,
126  DdNode * g)
127 {
128  DdNode *res,*zero;
129 
130  zero = Cudd_Not(DD_ONE(dd));
131  if (g == zero || g == DD_ZERO(dd)) {
132  (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n");
134  return(NULL);
135  }
136  do {
137  dd->reordered = 0;
138  res = cuddCofactorRecur(dd,f,g);
139  } while (dd->reordered == 1);
140  return(res);
141 
142 } /* end of Cudd_Cofactor */
143 
144 
145 /*---------------------------------------------------------------------------*/
146 /* Definition of internal functions */
147 /*---------------------------------------------------------------------------*/
148 
149 
150 /**Function********************************************************************
151 
152  Synopsis [Computes the children of g.]
153 
154  Description []
155 
156  SideEffects [None]
157 
158  SeeAlso []
159 
160 ******************************************************************************/
161 void
163  DdNode * g,
164  DdNode ** g1,
165  DdNode ** g0)
166 {
167  DdNode *G = Cudd_Regular(g);
168 
169  *g1 = cuddT(G);
170  *g0 = cuddE(G);
171  if (Cudd_IsComplement(g)) {
172  *g1 = Cudd_Not(*g1);
173  *g0 = Cudd_Not(*g0);
174  }
175 
176 } /* end of cuddGetBranches */
177 
178 
179 /**Function********************************************************************
180 
181  Synopsis [Checks whether g is the BDD of a cube.]
182 
183  Description [Checks whether g is the BDD of a cube. Returns 1 in case
184  of success; 0 otherwise. The constant 1 is a valid cube, but all other
185  constant functions cause cuddCheckCube to return 0.]
186 
187  SideEffects [None]
188 
189  SeeAlso []
190 
191 ******************************************************************************/
192 int
194  DdManager * dd,
195  DdNode * g)
196 {
197  DdNode *g1,*g0,*one,*zero;
198 
199  one = DD_ONE(dd);
200  if (g == one) return(1);
201  if (Cudd_IsConstant(g)) return(0);
202 
203  zero = Cudd_Not(one);
204  cuddGetBranches(g,&g1,&g0);
205 
206  if (g0 == zero) {
207  return(cuddCheckCube(dd, g1));
208  }
209  if (g1 == zero) {
210  return(cuddCheckCube(dd, g0));
211  }
212  return(0);
213 
214 } /* end of cuddCheckCube */
215 
216 
217 /**Function********************************************************************
218 
219  Synopsis [Performs the recursive step of Cudd_Cofactor.]
220 
221  Description [Performs the recursive step of Cudd_Cofactor. Returns a
222  pointer to the cofactor if successful; NULL otherwise.]
223 
224  SideEffects [None]
225 
226  SeeAlso [Cudd_Cofactor]
227 
228 ******************************************************************************/
229 DdNode *
231  DdManager * dd,
232  DdNode * f,
233  DdNode * g)
234 {
235  DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
236  unsigned int topf,topg;
237  int comple;
238 
239  statLine(dd);
240  F = Cudd_Regular(f);
241  if (cuddIsConstant(F)) return(f);
242 
243  one = DD_ONE(dd);
244 
245  /* The invariant g != 0 is true on entry to this procedure and is
246  ** recursively maintained by it. Therefore it suffices to test g
247  ** against one to make sure it is not constant.
248  */
249  if (g == one) return(f);
250  /* From now on, f and g are known not to be constants. */
251 
252  comple = f != F;
253  r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
254  if (r != NULL) {
255  return(Cudd_NotCond(r,comple));
256  }
257 
258  topf = dd->perm[F->index];
259  G = Cudd_Regular(g);
260  topg = dd->perm[G->index];
261 
262  /* We take the cofactors of F because we are going to rely on
263  ** the fact that the cofactors of the complement are the complements
264  ** of the cofactors to better utilize the cache. Variable comple
265  ** remembers whether we have to complement the result or not.
266  */
267  if (topf <= topg) {
268  f1 = cuddT(F); f0 = cuddE(F);
269  } else {
270  f1 = f0 = F;
271  }
272  if (topg <= topf) {
273  g1 = cuddT(G); g0 = cuddE(G);
274  if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
275  } else {
276  g1 = g0 = g;
277  }
278 
279  zero = Cudd_Not(one);
280  if (topf >= topg) {
281  if (g0 == zero || g0 == DD_ZERO(dd)) {
282  r = cuddCofactorRecur(dd, f1, g1);
283  } else if (g1 == zero || g1 == DD_ZERO(dd)) {
284  r = cuddCofactorRecur(dd, f0, g0);
285  } else {
286  (void) fprintf(dd->out,
287  "Cudd_Cofactor: Invalid restriction 2\n");
289  return(NULL);
290  }
291  if (r == NULL) return(NULL);
292  } else /* if (topf < topg) */ {
293  t = cuddCofactorRecur(dd, f1, g);
294  if (t == NULL) return(NULL);
295  cuddRef(t);
296  e = cuddCofactorRecur(dd, f0, g);
297  if (e == NULL) {
298  Cudd_RecursiveDeref(dd, t);
299  return(NULL);
300  }
301  cuddRef(e);
302 
303  if (t == e) {
304  r = t;
305  } else if (Cudd_IsComplement(t)) {
306  r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e));
307  if (r != NULL)
308  r = Cudd_Not(r);
309  } else {
310  r = cuddUniqueInter(dd,(int)F->index,t,e);
311  }
312  if (r == NULL) {
313  Cudd_RecursiveDeref(dd ,e);
314  Cudd_RecursiveDeref(dd ,t);
315  return(NULL);
316  }
317  cuddDeref(t);
318  cuddDeref(e);
319  }
320 
322 
323  return(Cudd_NotCond(r,comple));
324 
325 } /* end of cuddCofactorRecur */
326 
327 
328 /*---------------------------------------------------------------------------*/
329 /* Definition of static functions */
330 /*---------------------------------------------------------------------------*/
331 
332 
334 
335 
#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
#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
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:162
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddCof.c:86
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:123
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
int reordered
Definition: cuddInt.h:409
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
FILE * out
Definition: cuddInt.h:441
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddCofactorRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:230
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927