1 /**CFile***********************************************************************
7 Synopsis [Cofactoring functions.]
9 Description [External procedures included in this module:
13 Internal procedures included in this module:
15 <li> cuddGetBranches()
17 <li> cuddCofactorRecur()
23 Author [Fabio Somenzi]
25 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
29 Redistribution and use in source and binary forms, with or without
30 modification, are permitted provided that the following conditions
33 Redistributions of source code must retain the above copyright
34 notice, this list of conditions and the following disclaimer.
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.
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.
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.]
57 ******************************************************************************/
62 /*---------------------------------------------------------------------------*/
63 /* Constant declarations */
64 /*---------------------------------------------------------------------------*/
67 /*---------------------------------------------------------------------------*/
68 /* Stucture declarations */
69 /*---------------------------------------------------------------------------*/
72 /*---------------------------------------------------------------------------*/
73 /* Type declarations */
74 /*---------------------------------------------------------------------------*/
77 /*---------------------------------------------------------------------------*/
78 /* Variable declarations */
79 /*---------------------------------------------------------------------------*/
82 static char rcsid
[] DD_UNUSED
= "$Id: cuddCof.c,v 1.9 2004/08/13 18:04:47 fabio Exp $";
85 /*---------------------------------------------------------------------------*/
86 /* Macro declarations */
87 /*---------------------------------------------------------------------------*/
90 /**AutomaticStart*************************************************************/
92 /*---------------------------------------------------------------------------*/
93 /* Static function prototypes */
94 /*---------------------------------------------------------------------------*/
97 /**AutomaticEnd***************************************************************/
100 /*---------------------------------------------------------------------------*/
101 /* Definition of exported functions */
102 /*---------------------------------------------------------------------------*/
105 /**Function********************************************************************
107 Synopsis [Computes the cofactor of f with respect to g.]
109 Description [Computes the cofactor of f with respect to g; g must be
110 the BDD or the ADD of a cube. Returns a pointer to the cofactor if
111 successful; NULL otherwise.]
115 SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]
117 ******************************************************************************/
126 zero
= Cudd_Not(DD_ONE(dd
));
127 if (g
== zero
|| g
== DD_ZERO(dd
)) {
128 (void) fprintf(dd
->err
,"Cudd_Cofactor: Invalid restriction 1\n");
129 dd
->errorCode
= CUDD_INVALID_ARG
;
134 res
= cuddCofactorRecur(dd
,f
,g
);
135 } while (dd
->reordered
== 1);
138 } /* end of Cudd_Cofactor */
141 /*---------------------------------------------------------------------------*/
142 /* Definition of internal functions */
143 /*---------------------------------------------------------------------------*/
146 /**Function********************************************************************
148 Synopsis [Computes the children of g.]
156 ******************************************************************************/
163 DdNode
*G
= Cudd_Regular(g
);
167 if (Cudd_IsComplement(g
)) {
172 } /* end of cuddGetBranches */
175 /**Function********************************************************************
177 Synopsis [Checks whether g is the BDD of a cube.]
179 Description [Checks whether g is the BDD of a cube. Returns 1 in case
180 of success; 0 otherwise. The constant 1 is a valid cube, but all other
181 constant functions cause cuddCheckCube to return 0.]
187 ******************************************************************************/
193 DdNode
*g1
,*g0
,*one
,*zero
;
196 if (g
== one
) return(1);
197 if (Cudd_IsConstant(g
)) return(0);
199 zero
= Cudd_Not(one
);
200 cuddGetBranches(g
,&g1
,&g0
);
203 return(cuddCheckCube(dd
, g1
));
206 return(cuddCheckCube(dd
, g0
));
210 } /* end of cuddCheckCube */
213 /**Function********************************************************************
215 Synopsis [Performs the recursive step of Cudd_Cofactor.]
217 Description [Performs the recursive step of Cudd_Cofactor. Returns a
218 pointer to the cofactor if successful; NULL otherwise.]
222 SeeAlso [Cudd_Cofactor]
224 ******************************************************************************/
231 DdNode
*one
,*zero
,*F
,*G
,*g1
,*g0
,*f1
,*f0
,*t
,*e
,*r
;
232 unsigned int topf
,topg
;
237 if (cuddIsConstant(F
)) return(f
);
241 /* The invariant g != 0 is true on entry to this procedure and is
242 ** recursively maintained by it. Therefore it suffices to test g
243 ** against one to make sure it is not constant.
245 if (g
== one
) return(f
);
246 /* From now on, f and g are known not to be constants. */
249 r
= cuddCacheLookup2(dd
,Cudd_Cofactor
,F
,g
);
251 return(Cudd_NotCond(r
,comple
));
254 topf
= dd
->perm
[F
->index
];
256 topg
= dd
->perm
[G
->index
];
258 /* We take the cofactors of F because we are going to rely on
259 ** the fact that the cofactors of the complement are the complements
260 ** of the cofactors to better utilize the cache. Variable comple
261 ** remembers whether we have to complement the result or not.
264 f1
= cuddT(F
); f0
= cuddE(F
);
269 g1
= cuddT(G
); g0
= cuddE(G
);
270 if (g
!= G
) { g1
= Cudd_Not(g1
); g0
= Cudd_Not(g0
); }
275 zero
= Cudd_Not(one
);
277 if (g0
== zero
|| g0
== DD_ZERO(dd
)) {
278 r
= cuddCofactorRecur(dd
, f1
, g1
);
279 } else if (g1
== zero
|| g1
== DD_ZERO(dd
)) {
280 r
= cuddCofactorRecur(dd
, f0
, g0
);
282 (void) fprintf(dd
->out
,
283 "Cudd_Cofactor: Invalid restriction 2\n");
284 dd
->errorCode
= CUDD_INVALID_ARG
;
287 if (r
== NULL
) return(NULL
);
288 } else /* if (topf < topg) */ {
289 t
= cuddCofactorRecur(dd
, f1
, g
);
290 if (t
== NULL
) return(NULL
);
292 e
= cuddCofactorRecur(dd
, f0
, g
);
294 Cudd_RecursiveDeref(dd
, t
);
301 } else if (Cudd_IsComplement(t
)) {
302 r
= cuddUniqueInter(dd
,(int)F
->index
,Cudd_Not(t
),Cudd_Not(e
));
306 r
= cuddUniqueInter(dd
,(int)F
->index
,t
,e
);
309 Cudd_RecursiveDeref(dd
,e
);
310 Cudd_RecursiveDeref(dd
,t
);
317 cuddCacheInsert2(dd
,Cudd_Cofactor
,F
,g
,r
);
319 return(Cudd_NotCond(r
,comple
));
321 } /* end of cuddCofactorRecur */
324 /*---------------------------------------------------------------------------*/
325 /* Definition of static functions */
326 /*---------------------------------------------------------------------------*/