• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Alan-Jowett / cudd / 19144810377

06 Nov 2025 05:48PM UTC coverage: 32.985% (-0.007%) from 32.992%
19144810377

push

github

Alan Jowett
Merge branch '4.0.0' of https://github.com/Alan-Jowett/cudd into 4.0.0

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

9789 of 29677 relevant lines covered (32.99%)

318758.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.99
/src/cuddZddIsop.c
1
/**
2
  @file
3

4
  @ingroup cudd
5

6
  @brief Functions to find irredundant SOP covers as ZDDs from BDDs.
7

8
  @author In-Ho Moon
9

10
  @copyright@parblock
11
  Copyright (c) 1995-2015, Regents of the University of Colorado
12

13
  All rights reserved.
14

15
  Redistribution and use in source and binary forms, with or without
16
  modification, are permitted provided that the following conditions
17
  are met:
18

19
  Redistributions of source code must retain the above copyright
20
  notice, this list of conditions and the following disclaimer.
21

22
  Redistributions in binary form must reproduce the above copyright
23
  notice, this list of conditions and the following disclaimer in the
24
  documentation and/or other materials provided with the distribution.
25

26
  Neither the name of the University of Colorado nor the names of its
27
  contributors may be used to endorse or promote products derived from
28
  this software without specific prior written permission.
29

30
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34
  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35
  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36
  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40
  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
  POSSIBILITY OF SUCH DAMAGE.
42
  @endparblock
43

44
*/
45

46
#include "util.h"
47
#include "cuddInt.h"
48

49
/*---------------------------------------------------------------------------*/
50
/* Constant declarations                                                     */
51
/*---------------------------------------------------------------------------*/
52

53

54
/*---------------------------------------------------------------------------*/
55
/* Stucture declarations                                                     */
56
/*---------------------------------------------------------------------------*/
57

58

59
/*---------------------------------------------------------------------------*/
60
/* Type declarations                                                         */
61
/*---------------------------------------------------------------------------*/
62

63

64
/*---------------------------------------------------------------------------*/
65
/* Variable declarations                                                     */
66
/*---------------------------------------------------------------------------*/
67

68

69
/*---------------------------------------------------------------------------*/
70
/* Macro declarations                                                        */
71
/*---------------------------------------------------------------------------*/
72

73
/** \cond */
74

75
/*---------------------------------------------------------------------------*/
76
/* Static function prototypes                                                */
77
/*---------------------------------------------------------------------------*/
78

79
/** \endcond */
80

81

82
/*---------------------------------------------------------------------------*/
83
/* Definition of exported functions                                          */
84
/*---------------------------------------------------------------------------*/
85

86
/**
87
  @brief Computes an ISOP in %ZDD form from BDDs.
88

89
  @details Computes an irredundant sum of products (ISOP) in %ZDD
90
  form from BDDs. The two BDDs L and U represent the lower bound and
91
  the upper bound, respectively, of the function. The ISOP uses two
92
  %ZDD variables for each %BDD variable: One for the positive literal,
93
  and one for the negative literal. These two variables should be
94
  adjacent in the %ZDD order. The two %ZDD variables corresponding to
95
  %BDD variable <code>i</code> should have indices <code>2i</code> and
96
  <code>2i+1</code>.  The result of this procedure depends on the
97
  variable order. If successful, Cudd_zddIsop returns the %BDD for
98
  the function chosen from the interval. The %ZDD representing the
99
  irredundant cover is returned as a side effect in zdd_I. In case of
100
  failure, NULL is returned.
101

102
  @return the %BDD for the chosen function if successful; NULL otherwise.
103

104
  @sideeffect zdd_I holds the pointer to the %ZDD for the ISOP on
105
  successful return.
106

107
  @see Cudd_bddIsop Cudd_zddVarsFromBddVars
108

109
*/
110
DdNode        *
111
Cudd_zddIsop(
44✔
112
  DdManager * dd,
113
  DdNode * L,
114
  DdNode * U,
115
  DdNode ** zdd_I)
116
{
117
    DdNode        *res;
118
    int                autoDynZ;
119

120
    autoDynZ = dd->autoDynZ;
44✔
121
    dd->autoDynZ = 0;
44✔
122

123
    do {
124
        dd->reordered = 0;
44✔
125
        res = cuddZddIsop(dd, L, U, zdd_I);
44✔
126
    } while (dd->reordered == 1);
44✔
127
    dd->autoDynZ = autoDynZ;
44✔
128
    if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
44✔
129
        dd->timeoutHandler(dd, dd->tohArg);
×
130
    }
131
    return(res);
44✔
132

133
} /* end of Cudd_zddIsop */
134

135

136
/**
137
  @brief Computes a %BDD in the interval between L and U with a
138
  simple sum-of-product cover.
139

140
  @details This procedure is similar to Cudd_zddIsop, but it does not
141
  return the %ZDD for the cover.
142

143
  @return a pointer to the %BDD if successful; NULL otherwise.
144

145
  @sideeffect None
146

147
  @see Cudd_zddIsop
148

149
*/
150
DdNode        *
151
Cudd_bddIsop(
×
152
  DdManager * dd,
153
  DdNode * L,
154
  DdNode * U)
155
{
156
    DdNode        *res;
157

158
    do {
159
        dd->reordered = 0;
×
160
        res = cuddBddIsop(dd, L, U);
×
161
    } while (dd->reordered == 1);
×
162
    if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
×
163
        dd->timeoutHandler(dd, dd->tohArg);
×
164
    }
165
    return(res);
×
166

167
} /* end of Cudd_bddIsop */
168

169

170
/**
171
  @brief Converts a %ZDD cover to a %BDD.
172

173
  @details Converts a %ZDD cover to a %BDD for the function represented
174
  by the cover.
175

176
  @return a %BDD node if successful; otherwise it returns NULL.
177

178
  @see Cudd_zddIsop
179

180
*/
181
DdNode        *
182
Cudd_MakeBddFromZddCover(
×
183
  DdManager * dd,
184
  DdNode * node)
185
{
186
    DdNode        *res;
187

188
    do {
189
        dd->reordered = 0;
×
190
        res = cuddMakeBddFromZddCover(dd, node);
×
191
    } while (dd->reordered == 1);
×
192
    if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
×
193
        dd->timeoutHandler(dd, dd->tohArg);
×
194
    }
195
    return(res);
×
196

197
} /* end of Cudd_MakeBddFromZddCover */
198

199

200
/*---------------------------------------------------------------------------*/
201
/* Definition of internal functions                                          */
202
/*---------------------------------------------------------------------------*/
203

204

205
/**
206
  @brief Performs the recursive step of Cudd_zddIsop.
207

208
  @sideeffect None
209

210
  @see Cudd_zddIsop
211

212
*/
213
DdNode        *
214
cuddZddIsop(
4,115✔
215
  DdManager * dd,
216
  DdNode * L,
217
  DdNode * U,
218
  DdNode ** zdd_I)
219
{
220
    DdNode        *one = DD_ONE(dd);
4,115✔
221
    DdNode        *zero = Cudd_Not(one);
4,115✔
222
    DdNode        *zdd_one = DD_ONE(dd);
4,115✔
223
    DdNode        *zdd_zero = DD_ZERO(dd);
4,115✔
224
    int                v, top_l, top_u;
225
    DdNode        *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
226
    DdNode        *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
227
    DdNode        *Isub0, *Isub1, *Id;
228
    DdNode        *zdd_Isub0, *zdd_Isub1, *zdd_Id;
229
    DdNode        *x;
230
    DdNode        *term0, *term1, *sum;
231
    DdNode        *Lv, *Uv, *Lnv, *Unv;
232
    DdNode        *r, *y, *z;
233
    unsigned        index;
234
    DD_CTFP        cacheOp;
235

236
    statLine(dd);
237
    if (L == zero) {
4,115✔
238
        *zdd_I = zdd_zero;
2,283✔
239
        return(zero);
2,283✔
240
    }
241
    if (U == one) {
1,832✔
242
        *zdd_I = zdd_one;
144✔
243
        return(one);
144✔
244
    }
245

246
    if (U == zero || L == one) {
1,688✔
247
        printf("*** ERROR : illegal condition for ISOP (U < L).\n");
×
248
        exit(1);
×
249
    }
250

251
    /* Check the cache. We store two results for each recursive call.
252
    ** One is the BDD, and the other is the ZDD. Both are needed.
253
    ** Hence we need a double hit in the cache to terminate the
254
    ** recursion. Clearly, collisions may evict only one of the two
255
    ** results. */
256
    cacheOp = (DD_CTFP) cuddZddIsop;
1,688✔
257
    r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
1,688✔
258
    if (r) {
1,688✔
259
        *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U);
331✔
260
        if (*zdd_I)
331✔
261
            return(r);
331✔
262
        else {
263
            /* The BDD result may have been dead. In that case
264
            ** cuddCacheLookup2 would have called cuddReclaim,
265
            ** whose effects we now have to undo. */
266
            cuddRef(r);
×
267
            Cudd_RecursiveDeref(dd, r);
×
268
        }
269
    }
270

271
    top_l = dd->perm[Cudd_Regular(L)->index];
1,357✔
272
    top_u = dd->perm[Cudd_Regular(U)->index];
1,357✔
273
    v = ddMin(top_l, top_u);
1,357✔
274

275
    /* Compute cofactors. */
276
    if (top_l == v) {
1,357✔
277
        index = Cudd_Regular(L)->index;
1,344✔
278
        Lv = Cudd_T(L);
1,344✔
279
        Lnv = Cudd_E(L);
1,344✔
280
        if (Cudd_IsComplement(L)) {
1,344✔
281
            Lv = Cudd_Not(Lv);
1,089✔
282
            Lnv = Cudd_Not(Lnv);
1,089✔
283
        }
284
    }
285
    else {
286
        index = Cudd_Regular(U)->index;
13✔
287
        Lv = Lnv = L;
13✔
288
    }
289

290
    if (top_u == v) {
1,357✔
291
        Uv = Cudd_T(U);
1,020✔
292
        Unv = Cudd_E(U);
1,020✔
293
        if (Cudd_IsComplement(U)) {
1,020✔
294
            Uv = Cudd_Not(Uv);
541✔
295
            Unv = Cudd_Not(Unv);
541✔
296
        }
297
    }
298
    else {
299
        Uv = Unv = U;
337✔
300
    }
301

302
    Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
1,357✔
303
    if (Lsub0 == NULL)
1,357✔
304
        return(NULL);
×
305
    Cudd_Ref(Lsub0);
1,357✔
306
    Usub0 = Unv;
1,357✔
307
    Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
1,357✔
308
    if (Lsub1 == NULL) {
1,357✔
309
        Cudd_RecursiveDeref(dd, Lsub0);
×
310
        return(NULL);
×
311
    }
312
    Cudd_Ref(Lsub1);
1,357✔
313
    Usub1 = Uv;
1,357✔
314

315
    Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0);
1,357✔
316
    if (Isub0 == NULL) {
1,357✔
317
        Cudd_RecursiveDeref(dd, Lsub0);
×
318
        Cudd_RecursiveDeref(dd, Lsub1);
×
319
        return(NULL);
×
320
    }
321
    /*
322
    if ((!cuddIsConstant(Cudd_Regular(Isub0))) &&
323
        (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 ||
324
        dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) {
325
        printf("*** ERROR : illegal permutation in ZDD. ***\n");
326
    }
327
    */
328
    Cudd_Ref(Isub0);
1,357✔
329
    Cudd_Ref(zdd_Isub0);
1,357✔
330
    Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1);
1,357✔
331
    if (Isub1 == NULL) {
1,357✔
332
        Cudd_RecursiveDeref(dd, Lsub0);
×
333
        Cudd_RecursiveDeref(dd, Lsub1);
×
334
        Cudd_RecursiveDeref(dd, Isub0);
×
335
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
336
        return(NULL);
×
337
    }
338
    /*
339
    if ((!cuddIsConstant(Cudd_Regular(Isub1))) &&
340
        (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 ||
341
        dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) {
342
        printf("*** ERROR : illegal permutation in ZDD. ***\n");
343
    }
344
    */
345
    Cudd_Ref(Isub1);
1,357✔
346
    Cudd_Ref(zdd_Isub1);
1,357✔
347
    Cudd_RecursiveDeref(dd, Lsub0);
1,357✔
348
    Cudd_RecursiveDeref(dd, Lsub1);
1,357✔
349

350
    Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
1,357✔
351
    if (Lsuper0 == NULL) {
1,357✔
352
        Cudd_RecursiveDeref(dd, Isub0);
×
353
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
354
        Cudd_RecursiveDeref(dd, Isub1);
×
355
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
356
        return(NULL);
×
357
    }
358
    Cudd_Ref(Lsuper0);
1,357✔
359
    Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
1,357✔
360
    if (Lsuper1 == NULL) {
1,357✔
361
        Cudd_RecursiveDeref(dd, Isub0);
×
362
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
363
        Cudd_RecursiveDeref(dd, Isub1);
×
364
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
365
        Cudd_RecursiveDeref(dd, Lsuper0);
×
366
        return(NULL);
×
367
    }
368
    Cudd_Ref(Lsuper1);
1,357✔
369
    Usuper0 = Unv;
1,357✔
370
    Usuper1 = Uv;
1,357✔
371

372
    /* Ld = Lsuper0 + Lsuper1 */
373
    Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
1,357✔
374
    if (Ld == NULL) {
1,357✔
375
        Cudd_RecursiveDeref(dd, Isub0);
×
376
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
377
        Cudd_RecursiveDeref(dd, Isub1);
×
378
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
379
        Cudd_RecursiveDeref(dd, Lsuper0);
×
380
        Cudd_RecursiveDeref(dd, Lsuper1);
×
381
        return(NULL);
×
382
    }
383
    Ld = Cudd_Not(Ld);
1,357✔
384
    Cudd_Ref(Ld);
1,357✔
385
    /* Ud = Usuper0 * Usuper1 */
386
    Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
1,357✔
387
    if (Ud == NULL) {
1,357✔
388
        Cudd_RecursiveDeref(dd, Isub0);
×
389
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
390
        Cudd_RecursiveDeref(dd, Isub1);
×
391
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
392
        Cudd_RecursiveDeref(dd, Lsuper0);
×
393
        Cudd_RecursiveDeref(dd, Lsuper1);
×
394
        Cudd_RecursiveDeref(dd, Ld);
×
395
        return(NULL);
×
396
    }
397
    Cudd_Ref(Ud);
1,357✔
398
    Cudd_RecursiveDeref(dd, Lsuper0);
1,357✔
399
    Cudd_RecursiveDeref(dd, Lsuper1);
1,357✔
400

401
    Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id);
1,357✔
402
    if (Id == NULL) {
1,357✔
403
        Cudd_RecursiveDeref(dd, Isub0);
×
404
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
405
        Cudd_RecursiveDeref(dd, Isub1);
×
406
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
407
        Cudd_RecursiveDeref(dd, Ld);
×
408
        Cudd_RecursiveDeref(dd, Ud);
×
409
        return(NULL);
×
410
    }
411
    /*
412
    if ((!cuddIsConstant(Cudd_Regular(Id))) &&
413
        (Cudd_Regular(Id)->index != zdd_Id->index / 2 ||
414
        dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) {
415
        printf("*** ERROR : illegal permutation in ZDD. ***\n");
416
    }
417
    */
418
    Cudd_Ref(Id);
1,357✔
419
    Cudd_Ref(zdd_Id);
1,357✔
420
    Cudd_RecursiveDeref(dd, Ld);
1,357✔
421
    Cudd_RecursiveDeref(dd, Ud);
1,357✔
422

423
    x = cuddUniqueInter(dd, index, one, zero);
1,357✔
424
    if (x == NULL) {
1,357✔
425
        Cudd_RecursiveDeref(dd, Isub0);
×
426
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
427
        Cudd_RecursiveDeref(dd, Isub1);
×
428
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
429
        Cudd_RecursiveDeref(dd, Id);
×
430
        Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
431
        return(NULL);
×
432
    }
433
    Cudd_Ref(x);
1,357✔
434
    /* term0 = x * Isub0 */
435
    term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
1,357✔
436
    if (term0 == NULL) {
1,357✔
437
        Cudd_RecursiveDeref(dd, Isub0);
×
438
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
439
        Cudd_RecursiveDeref(dd, Isub1);
×
440
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
441
        Cudd_RecursiveDeref(dd, Id);
×
442
        Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
443
        Cudd_RecursiveDeref(dd, x);
×
444
        return(NULL);
×
445
    }
446
    Cudd_Ref(term0);
1,357✔
447
    Cudd_RecursiveDeref(dd, Isub0);
1,357✔
448
    /* term1 = x * Isub1 */
449
    term1 = cuddBddAndRecur(dd, x, Isub1);
1,357✔
450
    if (term1 == NULL) {
1,357✔
451
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
452
        Cudd_RecursiveDeref(dd, Isub1);
×
453
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
454
        Cudd_RecursiveDeref(dd, Id);
×
455
        Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
456
        Cudd_RecursiveDeref(dd, x);
×
457
        Cudd_RecursiveDeref(dd, term0);
×
458
        return(NULL);
×
459
    }
460
    Cudd_Ref(term1);
1,357✔
461
    Cudd_RecursiveDeref(dd, x);
1,357✔
462
    Cudd_RecursiveDeref(dd, Isub1);
1,357✔
463
    /* sum = term0 + term1 */
464
    sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
1,357✔
465
    if (sum == NULL) {
1,357✔
466
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
467
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
468
        Cudd_RecursiveDeref(dd, Id);
×
469
        Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
470
        Cudd_RecursiveDeref(dd, term0);
×
471
        Cudd_RecursiveDeref(dd, term1);
×
472
        return(NULL);
×
473
    }
474
    sum = Cudd_Not(sum);
1,357✔
475
    Cudd_Ref(sum);
1,357✔
476
    Cudd_RecursiveDeref(dd, term0);
1,357✔
477
    Cudd_RecursiveDeref(dd, term1);
1,357✔
478
    /* r = sum + Id */
479
    r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
1,357✔
480
    r = Cudd_NotCond(r, r != NULL);
1,357✔
481
    if (r == NULL) {
1,357✔
482
        Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
483
        Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
484
        Cudd_RecursiveDeref(dd, Id);
×
485
        Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
486
        Cudd_RecursiveDeref(dd, sum);
×
487
        return(NULL);
×
488
    }
489
    Cudd_Ref(r);
1,357✔
490
    Cudd_RecursiveDeref(dd, sum);
1,357✔
491
    Cudd_RecursiveDeref(dd, Id);
1,357✔
492

493
    if (zdd_Isub0 != zdd_zero) {
1,357✔
494
        z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id);
520✔
495
        if (z == NULL) {
520✔
496
            Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
497
            Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
498
            Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
499
            Cudd_RecursiveDeref(dd, r);
×
500
            return(NULL);
×
501
        }
502
    }
503
    else {
504
        z = zdd_Id;
837✔
505
    }
506
    Cudd_Ref(z);
1,357✔
507
    if (zdd_Isub1 != zdd_zero) {
1,357✔
508
        y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z);
451✔
509
        if (y == NULL) {
451✔
510
            Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
×
511
            Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
×
512
            Cudd_RecursiveDerefZdd(dd, zdd_Id);
×
513
            Cudd_RecursiveDeref(dd, r);
×
514
            Cudd_RecursiveDerefZdd(dd, z);
×
515
            return(NULL);
×
516
        }
517
    }
518
    else
519
        y = z;
906✔
520
    Cudd_Ref(y);
1,357✔
521

522
    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
1,357✔
523
    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
1,357✔
524
    Cudd_RecursiveDerefZdd(dd, zdd_Id);
1,357✔
525
    Cudd_RecursiveDerefZdd(dd, z);
1,357✔
526

527
    cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
1,357✔
528
    cuddCacheInsert2(dd, cacheOp, L, U, y);
1,357✔
529

530
    Cudd_Deref(r);
1,357✔
531
    Cudd_Deref(y);
1,357✔
532
    *zdd_I = y;
1,357✔
533
    /*
534
    if (Cudd_Regular(r)->index != y->index / 2) {
535
        printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
536
    }
537
    */
538
    return(r);
1,357✔
539

540
} /* end of cuddZddIsop */
541

542

543
/**
544
  @brief Performs the recursive step of Cudd_bddIsop.
545

546
  @sideeffect None
547

548
  @see Cudd_bddIsop
549

550
*/
551
DdNode        *
552
cuddBddIsop(
×
553
  DdManager * dd,
554
  DdNode * L,
555
  DdNode * U)
556
{
557
    DdNode        *one = DD_ONE(dd);
×
558
    DdNode        *zero = Cudd_Not(one);
×
559
    int                v, top_l, top_u;
560
    DdNode        *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
561
    DdNode        *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
562
    DdNode        *Isub0, *Isub1, *Id;
563
    DdNode        *x;
564
    DdNode        *term0, *term1, *sum;
565
    DdNode        *Lv, *Uv, *Lnv, *Unv;
566
    DdNode        *r;
567
    unsigned        index;
568

569
    statLine(dd);
570
    if (L == zero)
×
571
        return(zero);
×
572
    if (U == one)
×
573
        return(one);
×
574

575
    /* Check cache */
576
    r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
×
577
    if (r)
×
578
        return(r);
×
579

580
    top_l = dd->perm[Cudd_Regular(L)->index];
×
581
    top_u = dd->perm[Cudd_Regular(U)->index];
×
582
    v = ddMin(top_l, top_u);
×
583

584
    /* Compute cofactors */
585
    if (top_l == v) {
×
586
        index = Cudd_Regular(L)->index;
×
587
        Lv = Cudd_T(L);
×
588
        Lnv = Cudd_E(L);
×
589
        if (Cudd_IsComplement(L)) {
×
590
            Lv = Cudd_Not(Lv);
×
591
            Lnv = Cudd_Not(Lnv);
×
592
        }
593
    }
594
    else {
595
        index = Cudd_Regular(U)->index;
×
596
        Lv = Lnv = L;
×
597
    }
598

599
    if (top_u == v) {
×
600
        Uv = Cudd_T(U);
×
601
        Unv = Cudd_E(U);
×
602
        if (Cudd_IsComplement(U)) {
×
603
            Uv = Cudd_Not(Uv);
×
604
            Unv = Cudd_Not(Unv);
×
605
        }
606
    }
607
    else {
608
        Uv = Unv = U;
×
609
    }
610

611
    Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
×
612
    if (Lsub0 == NULL)
×
613
        return(NULL);
×
614
    Cudd_Ref(Lsub0);
×
615
    Usub0 = Unv;
×
616
    Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
×
617
    if (Lsub1 == NULL) {
×
618
        Cudd_RecursiveDeref(dd, Lsub0);
×
619
        return(NULL);
×
620
    }
621
    Cudd_Ref(Lsub1);
×
622
    Usub1 = Uv;
×
623

624
    Isub0 = cuddBddIsop(dd, Lsub0, Usub0);
×
625
    if (Isub0 == NULL) {
×
626
        Cudd_RecursiveDeref(dd, Lsub0);
×
627
        Cudd_RecursiveDeref(dd, Lsub1);
×
628
        return(NULL);
×
629
    }
630
    Cudd_Ref(Isub0);
×
631
    Isub1 = cuddBddIsop(dd, Lsub1, Usub1);
×
632
    if (Isub1 == NULL) {
×
633
        Cudd_RecursiveDeref(dd, Lsub0);
×
634
        Cudd_RecursiveDeref(dd, Lsub1);
×
635
        Cudd_RecursiveDeref(dd, Isub0);
×
636
        return(NULL);
×
637
    }
638
    Cudd_Ref(Isub1);
×
639
    Cudd_RecursiveDeref(dd, Lsub0);
×
640
    Cudd_RecursiveDeref(dd, Lsub1);
×
641

642
    Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
×
643
    if (Lsuper0 == NULL) {
×
644
        Cudd_RecursiveDeref(dd, Isub0);
×
645
        Cudd_RecursiveDeref(dd, Isub1);
×
646
        return(NULL);
×
647
    }
648
    Cudd_Ref(Lsuper0);
×
649
    Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
×
650
    if (Lsuper1 == NULL) {
×
651
        Cudd_RecursiveDeref(dd, Isub0);
×
652
        Cudd_RecursiveDeref(dd, Isub1);
×
653
        Cudd_RecursiveDeref(dd, Lsuper0);
×
654
        return(NULL);
×
655
    }
656
    Cudd_Ref(Lsuper1);
×
657
    Usuper0 = Unv;
×
658
    Usuper1 = Uv;
×
659

660
    /* Ld = Lsuper0 + Lsuper1 */
661
    Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
×
662
    Ld = Cudd_NotCond(Ld, Ld != NULL);
×
663
    if (Ld == NULL) {
×
664
        Cudd_RecursiveDeref(dd, Isub0);
×
665
        Cudd_RecursiveDeref(dd, Isub1);
×
666
        Cudd_RecursiveDeref(dd, Lsuper0);
×
667
        Cudd_RecursiveDeref(dd, Lsuper1);
×
668
        return(NULL);
×
669
    }
670
    Cudd_Ref(Ld);
×
671
    Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
×
672
    if (Ud == NULL) {
×
673
        Cudd_RecursiveDeref(dd, Isub0);
×
674
        Cudd_RecursiveDeref(dd, Isub1);
×
675
        Cudd_RecursiveDeref(dd, Lsuper0);
×
676
        Cudd_RecursiveDeref(dd, Lsuper1);
×
677
        Cudd_RecursiveDeref(dd, Ld);
×
678
        return(NULL);
×
679
    }
680
    Cudd_Ref(Ud);
×
681
    Cudd_RecursiveDeref(dd, Lsuper0);
×
682
    Cudd_RecursiveDeref(dd, Lsuper1);
×
683

684
    Id = cuddBddIsop(dd, Ld, Ud);
×
685
    if (Id == NULL) {
×
686
        Cudd_RecursiveDeref(dd, Isub0);
×
687
        Cudd_RecursiveDeref(dd, Isub1);
×
688
        Cudd_RecursiveDeref(dd, Ld);
×
689
        Cudd_RecursiveDeref(dd, Ud);
×
690
        return(NULL);
×
691
    }
692
    Cudd_Ref(Id);
×
693
    Cudd_RecursiveDeref(dd, Ld);
×
694
    Cudd_RecursiveDeref(dd, Ud);
×
695

696
    x = cuddUniqueInter(dd, index, one, zero);
×
697
    if (x == NULL) {
×
698
        Cudd_RecursiveDeref(dd, Isub0);
×
699
        Cudd_RecursiveDeref(dd, Isub1);
×
700
        Cudd_RecursiveDeref(dd, Id);
×
701
        return(NULL);
×
702
    }
703
    Cudd_Ref(x);
×
704
    term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
×
705
    if (term0 == NULL) {
×
706
        Cudd_RecursiveDeref(dd, Isub0);
×
707
        Cudd_RecursiveDeref(dd, Isub1);
×
708
        Cudd_RecursiveDeref(dd, Id);
×
709
        Cudd_RecursiveDeref(dd, x);
×
710
        return(NULL);
×
711
    }
712
    Cudd_Ref(term0);
×
713
    Cudd_RecursiveDeref(dd, Isub0);
×
714
    term1 = cuddBddAndRecur(dd, x, Isub1);
×
715
    if (term1 == NULL) {
×
716
        Cudd_RecursiveDeref(dd, Isub1);
×
717
        Cudd_RecursiveDeref(dd, Id);
×
718
        Cudd_RecursiveDeref(dd, x);
×
719
        Cudd_RecursiveDeref(dd, term0);
×
720
        return(NULL);
×
721
    }
722
    Cudd_Ref(term1);
×
723
    Cudd_RecursiveDeref(dd, x);
×
724
    Cudd_RecursiveDeref(dd, Isub1);
×
725
    /* sum = term0 + term1 */
726
    sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
×
727
    sum = Cudd_NotCond(sum, sum != NULL);
×
728
    if (sum == NULL) {
×
729
        Cudd_RecursiveDeref(dd, Id);
×
730
        Cudd_RecursiveDeref(dd, term0);
×
731
        Cudd_RecursiveDeref(dd, term1);
×
732
        return(NULL);
×
733
    }
734
    Cudd_Ref(sum);
×
735
    Cudd_RecursiveDeref(dd, term0);
×
736
    Cudd_RecursiveDeref(dd, term1);
×
737
    /* r = sum + Id */
738
    r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
×
739
    r = Cudd_NotCond(r, r != NULL);
×
740
    if (r == NULL) {
×
741
        Cudd_RecursiveDeref(dd, Id);
×
742
        Cudd_RecursiveDeref(dd, sum);
×
743
        return(NULL);
×
744
    }
745
    Cudd_Ref(r);
×
746
    Cudd_RecursiveDeref(dd, sum);
×
747
    Cudd_RecursiveDeref(dd, Id);
×
748

749
    cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
×
750

751
    Cudd_Deref(r);
×
752
    return(r);
×
753

754
} /* end of cuddBddIsop */
755

756

757
/**
758
  @brief Converts a %ZDD cover to a %BDD.
759

760
  @details It is a recursive algorithm that works as follows. First it
761
  computes 3 cofactors of a %ZDD cover: f1, f0 and fd. Second, it
762
  compute BDDs (b1, b0 and bd) of f1, f0 and fd.  Third, it computes
763
  T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where v is the
764
  variable which has the index of the top node of the %ZDD cover.  In
765
  this case, since the index of v can be larger than either the one of
766
  T or the one of E, cuddUniqueInterIVO is called, where IVO stands
767
  for independent from variable ordering.
768

769
  @return a %BDD node if successful; otherwise it returns NULL.
770

771
  @see Cudd_MakeBddFromZddCover
772

773
*/
774
DdNode        *
775
cuddMakeBddFromZddCover(
×
776
  DdManager * dd,
777
  DdNode * node)
778
{
779
    DdNode        *neW;
780
    unsigned        v;
781
    DdNode        *f1, *f0, *fd;
782
    DdNode        *b1, *b0, *bd;
783
    DdNode        *T, *E;
784

785
    statLine(dd);
786
    if (node == dd->one)
×
787
        return(dd->one);
×
788
    if (node == dd->zero)
×
789
        return(Cudd_Not(dd->one));
×
790

791
    /* Check cache */
792
    neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node);
×
793
    if (neW)
×
794
        return(neW);
×
795

796
    v = Cudd_Regular(node)->index;        /* either yi or zi */
×
797
    if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL);
×
798
    Cudd_Ref(f1);
×
799
    Cudd_Ref(f0);
×
800
    Cudd_Ref(fd);
×
801

802
    b1 = cuddMakeBddFromZddCover(dd, f1);
×
803
    if (!b1) {
×
804
        Cudd_RecursiveDerefZdd(dd, f1);
×
805
        Cudd_RecursiveDerefZdd(dd, f0);
×
806
        Cudd_RecursiveDerefZdd(dd, fd);
×
807
        return(NULL);
×
808
    }
809
    Cudd_Ref(b1);
×
810
    b0 = cuddMakeBddFromZddCover(dd, f0);
×
811
    if (!b0) {
×
812
        Cudd_RecursiveDerefZdd(dd, f1);
×
813
        Cudd_RecursiveDerefZdd(dd, f0);
×
814
        Cudd_RecursiveDerefZdd(dd, fd);
×
815
        Cudd_RecursiveDeref(dd, b1);
×
816
        return(NULL);
×
817
    }
818
    Cudd_Ref(b0);
×
819
    Cudd_RecursiveDerefZdd(dd, f1);
×
820
    Cudd_RecursiveDerefZdd(dd, f0);
×
821
    if (fd != dd->zero) {
×
822
        bd = cuddMakeBddFromZddCover(dd, fd);
×
823
        if (!bd) {
×
824
            Cudd_RecursiveDerefZdd(dd, fd);
×
825
            Cudd_RecursiveDeref(dd, b1);
×
826
            Cudd_RecursiveDeref(dd, b0);
×
827
            return(NULL);
×
828
        }
829
        Cudd_Ref(bd);
×
830
        Cudd_RecursiveDerefZdd(dd, fd);
×
831

832
        T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd));
×
833
        if (!T) {
×
834
            Cudd_RecursiveDeref(dd, b1);
×
835
            Cudd_RecursiveDeref(dd, b0);
×
836
            Cudd_RecursiveDeref(dd, bd);
×
837
            return(NULL);
×
838
        }
839
        T = Cudd_NotCond(T, T != NULL);
×
840
        Cudd_Ref(T);
×
841
        Cudd_RecursiveDeref(dd, b1);
×
842
        E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd));
×
843
        if (!E) {
×
844
            Cudd_RecursiveDeref(dd, b0);
×
845
            Cudd_RecursiveDeref(dd, bd);
×
846
            Cudd_RecursiveDeref(dd, T);
×
847
            return(NULL);
×
848
        }
849
        E = Cudd_NotCond(E, E != NULL);
×
850
        Cudd_Ref(E);
×
851
        Cudd_RecursiveDeref(dd, b0);
×
852
        Cudd_RecursiveDeref(dd, bd);
×
853
    }
854
    else {
855
        Cudd_RecursiveDerefZdd(dd, fd);
×
856
        T = b1;
×
857
        E = b0;
×
858
    }
859

860
    if (Cudd_IsComplement(T)) {
×
861
        neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E));
×
862
        if (!neW) {
×
863
            Cudd_RecursiveDeref(dd, T);
×
864
            Cudd_RecursiveDeref(dd, E);
×
865
            return(NULL);
×
866
        }
867
        neW = Cudd_Not(neW);
×
868
    }
869
    else {
870
        neW = cuddUniqueInterIVO(dd, v / 2, T, E);
×
871
        if (!neW) {
×
872
            Cudd_RecursiveDeref(dd, T);
×
873
            Cudd_RecursiveDeref(dd, E);
×
874
            return(NULL);
×
875
        }
876
    }
877
    Cudd_Ref(neW);
×
878
    Cudd_RecursiveDeref(dd, T);
×
879
    Cudd_RecursiveDeref(dd, E);
×
880

881
    cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW);
×
882
    Cudd_Deref(neW);
×
883
    return(neW);
×
884

885
} /* end of cuddMakeBddFromZddCover */
886

887

888
/*---------------------------------------------------------------------------*/
889
/* Definition of static functions                                            */
890
/*---------------------------------------------------------------------------*/
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc