00001
00074 #include "util.h"
00075 #include "cuddInt.h"
00076
00077
00078
00079
00080
00081
00082 #if SIZEOF_LONG == 8
00083 #define BPL 64
00084 #define LOGBPL 6
00085 #else
00086 #define BPL 32
00087 #define LOGBPL 5
00088 #endif
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 struct DdTlcInfo {
00119 DdHalfWord *vars;
00120 long *phases;
00121 DdHalfWord cnt;
00122 };
00123
00124
00125
00126
00127
00128 struct TlClause {
00129 DdHalfWord v1, v2;
00130 short p1, p2;
00131 struct TlClause *next;
00132 };
00133
00134
00135
00136
00137
00138 typedef long BitVector;
00139 typedef struct TlClause TlClause;
00140
00141
00142
00143
00144
00145 #ifndef lint
00146 static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.24 2009/02/21 18:24:10 fabio Exp $";
00147 #endif
00148
00149 static BitVector *Tolv;
00150 static BitVector *Tolp;
00151 static BitVector *Eolv;
00152 static BitVector *Eolp;
00153
00154
00155
00156
00157
00160
00161
00162
00163
00164 static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f);
00165 static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table);
00166 static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size);
00167 static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase);
00168 static DdTlcInfo * emptyClauseSet (void);
00169 static int sentinelp (DdHalfWord var1, DdHalfWord var2);
00170 static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b);
00171 static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b);
00172 static int oneliteralp (DdHalfWord var);
00173 static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp);
00174 static BitVector * bitVectorAlloc (int size);
00175 DD_INLINE static void bitVectorClear (BitVector *vector, int size);
00176 static void bitVectorFree (BitVector *vector);
00177 DD_INLINE static short bitVectorRead (BitVector *vector, int i);
00178 DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val);
00179 static DdTlcInfo * tlcInfoAlloc (void);
00180
00184
00185
00186
00187
00188
00204 DdNode *
00205 Cudd_FindEssential(
00206 DdManager * dd,
00207 DdNode * f)
00208 {
00209 DdNode *res;
00210
00211 do {
00212 dd->reordered = 0;
00213 res = ddFindEssentialRecur(dd,f);
00214 } while (dd->reordered == 1);
00215 return(res);
00216
00217 }
00218
00219
00234 int
00235 Cudd_bddIsVarEssential(
00236 DdManager * manager,
00237 DdNode * f,
00238 int id,
00239 int phase)
00240 {
00241 DdNode *var;
00242 int res;
00243
00244 var = Cudd_bddIthVar(manager, id);
00245
00246 var = Cudd_NotCond(var,phase == 0);
00247
00248 res = Cudd_bddLeq(manager, f, var);
00249
00250 return(res);
00251
00252 }
00253
00254
00272 DdTlcInfo *
00273 Cudd_FindTwoLiteralClauses(
00274 DdManager * dd,
00275 DdNode * f)
00276 {
00277 DdTlcInfo *res;
00278 st_table *table;
00279 st_generator *gen;
00280 DdTlcInfo *tlc;
00281 DdNode *node;
00282 int size = dd->size;
00283
00284 if (Cudd_IsConstant(f)) {
00285 res = emptyClauseSet();
00286 return(res);
00287 }
00288 table = st_init_table(st_ptrcmp,st_ptrhash);
00289 if (table == NULL) return(NULL);
00290 Tolv = bitVectorAlloc(size);
00291 if (Tolv == NULL) {
00292 st_free_table(table);
00293 return(NULL);
00294 }
00295 Tolp = bitVectorAlloc(size);
00296 if (Tolp == NULL) {
00297 st_free_table(table);
00298 bitVectorFree(Tolv);
00299 return(NULL);
00300 }
00301 Eolv = bitVectorAlloc(size);
00302 if (Eolv == NULL) {
00303 st_free_table(table);
00304 bitVectorFree(Tolv);
00305 bitVectorFree(Tolp);
00306 return(NULL);
00307 }
00308 Eolp = bitVectorAlloc(size);
00309 if (Eolp == NULL) {
00310 st_free_table(table);
00311 bitVectorFree(Tolv);
00312 bitVectorFree(Tolp);
00313 bitVectorFree(Eolv);
00314 return(NULL);
00315 }
00316
00317 res = ddFindTwoLiteralClausesRecur(dd,f,table);
00318
00319 st_foreach_item(table, gen, &node, &tlc) {
00320 if (node != f) {
00321 Cudd_tlcInfoFree(tlc);
00322 }
00323 }
00324 st_free_table(table);
00325 bitVectorFree(Tolv);
00326 bitVectorFree(Tolp);
00327 bitVectorFree(Eolv);
00328 bitVectorFree(Eolp);
00329
00330 if (res != NULL) {
00331 int i;
00332 for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2);
00333 res->cnt = i >> 1;
00334 }
00335
00336 return(res);
00337
00338 }
00339
00340
00354 int
00355 Cudd_ReadIthClause(
00356 DdTlcInfo * tlc,
00357 int i,
00358 DdHalfWord *var1,
00359 DdHalfWord *var2,
00360 int *phase1,
00361 int *phase2)
00362 {
00363 if (tlc == NULL) return(0);
00364 if (tlc->vars == NULL || tlc->phases == NULL) return(0);
00365 if (i < 0 || (unsigned) i >= tlc->cnt) return(0);
00366 *var1 = tlc->vars[2*i];
00367 *var2 = tlc->vars[2*i+1];
00368 *phase1 = (int) bitVectorRead(tlc->phases, 2*i);
00369 *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1);
00370 return(1);
00371
00372 }
00373
00374
00388 int
00389 Cudd_PrintTwoLiteralClauses(
00390 DdManager * dd,
00391 DdNode * f,
00392 char **names,
00393 FILE *fp)
00394 {
00395 DdHalfWord *vars;
00396 BitVector *phases;
00397 int i;
00398 DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f);
00399 FILE *ifp = fp == NULL ? dd->out : fp;
00400
00401 if (res == NULL) return(0);
00402 vars = res->vars;
00403 phases = res->phases;
00404 for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) {
00405 if (names != NULL) {
00406 if (vars[i+1] == CUDD_MAXINDEX) {
00407 (void) fprintf(ifp, "%s%s\n",
00408 bitVectorRead(phases, i) ? "~" : " ",
00409 names[vars[i]]);
00410 } else {
00411 (void) fprintf(ifp, "%s%s | %s%s\n",
00412 bitVectorRead(phases, i) ? "~" : " ",
00413 names[vars[i]],
00414 bitVectorRead(phases, i+1) ? "~" : " ",
00415 names[vars[i+1]]);
00416 }
00417 } else {
00418 if (vars[i+1] == CUDD_MAXINDEX) {
00419 (void) fprintf(ifp, "%s%d\n",
00420 bitVectorRead(phases, i) ? "~" : " ",
00421 (int) vars[i]);
00422 } else {
00423 (void) fprintf(ifp, "%s%d | %s%d\n",
00424 bitVectorRead(phases, i) ? "~" : " ",
00425 (int) vars[i],
00426 bitVectorRead(phases, i+1) ? "~" : " ",
00427 (int) vars[i+1]);
00428 }
00429 }
00430 }
00431 Cudd_tlcInfoFree(res);
00432
00433 return(1);
00434
00435 }
00436
00437
00450 void
00451 Cudd_tlcInfoFree(
00452 DdTlcInfo * t)
00453 {
00454 if (t->vars != NULL) FREE(t->vars);
00455 if (t->phases != NULL) FREE(t->phases);
00456 FREE(t);
00457
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00481 static DdNode *
00482 ddFindEssentialRecur(
00483 DdManager * dd,
00484 DdNode * f)
00485 {
00486 DdNode *T, *E, *F;
00487 DdNode *essT, *essE, *res;
00488 int index;
00489 DdNode *one, *lzero, *azero;
00490
00491 one = DD_ONE(dd);
00492 F = Cudd_Regular(f);
00493
00494 if (cuddIsConstant(F)) return(one);
00495
00496 res = cuddCacheLookup1(dd,Cudd_FindEssential,f);
00497 if (res != NULL) {
00498 return(res);
00499 }
00500
00501 lzero = Cudd_Not(one);
00502 azero = DD_ZERO(dd);
00503
00504 T = cuddT(F);
00505 E = cuddE(F);
00506 if (Cudd_IsComplement(f)) {
00507 T = Cudd_Not(T); E = Cudd_Not(E);
00508 }
00509
00510 index = F->index;
00511 if (Cudd_IsConstant(T) && T != lzero && T != azero) {
00512
00513
00514
00515
00516
00517 if (E == lzero || E == azero) {
00518 res = dd->vars[index];
00519 } else {
00520 res = one;
00521 }
00522 } else if (T == lzero || T == azero) {
00523 if (Cudd_IsConstant(E)) {
00524 res = Cudd_Not(dd->vars[index]);
00525 } else {
00526
00527 essE = ddFindEssentialRecur(dd,E);
00528 if (essE == NULL) {
00529 return(NULL);
00530 }
00531 cuddRef(essE);
00532
00533
00534 res = cuddUniqueInter(dd,index,one,Cudd_Not(essE));
00535 if (res == NULL) {
00536 Cudd_RecursiveDeref(dd,essE);
00537 return(NULL);
00538 }
00539 res = Cudd_Not(res);
00540 cuddDeref(essE);
00541 }
00542 } else {
00543 if (E == lzero || E == azero) {
00544
00545 essT = ddFindEssentialRecur(dd,T);
00546 if (essT == NULL) {
00547 return(NULL);
00548 }
00549 cuddRef(essT);
00550
00551
00552
00553 res = cuddBddAndRecur(dd,dd->vars[index],essT);
00554 if (res == NULL) {
00555 Cudd_RecursiveDeref(dd,essT);
00556 return(NULL);
00557 }
00558 cuddDeref(essT);
00559 } else if (!Cudd_IsConstant(E)) {
00560
00561
00562
00563 essT = ddFindEssentialRecur(dd,T);
00564 if (essT == NULL) {
00565 return(NULL);
00566 }
00567 if (essT == one) {
00568 res = one;
00569 } else {
00570 cuddRef(essT);
00571 essE = ddFindEssentialRecur(dd,E);
00572 if (essE == NULL) {
00573 Cudd_RecursiveDeref(dd,essT);
00574 return(NULL);
00575 }
00576 cuddRef(essE);
00577
00578
00579 res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE);
00580 if (res == NULL) {
00581 Cudd_RecursiveDeref(dd,essT);
00582 Cudd_RecursiveDeref(dd,essE);
00583 return(NULL);
00584 }
00585 cuddRef(res);
00586 Cudd_RecursiveDeref(dd,essT);
00587 Cudd_RecursiveDeref(dd,essE);
00588 cuddDeref(res);
00589 }
00590 } else {
00591 res = one;
00592 }
00593 }
00594
00595 cuddCacheInsert1(dd,Cudd_FindEssential, f, res);
00596 return(res);
00597
00598 }
00599
00600
00615 static DdTlcInfo *
00616 ddFindTwoLiteralClausesRecur(
00617 DdManager * dd,
00618 DdNode * f,
00619 st_table *table)
00620 {
00621 DdNode *T, *E, *F;
00622 DdNode *one, *lzero, *azero;
00623 DdTlcInfo *res, *Tres, *Eres;
00624 DdHalfWord index;
00625
00626 F = Cudd_Regular(f);
00627
00628 assert(!cuddIsConstant(F));
00629
00630
00631
00632 if (st_lookup(table, f, &res)) {
00633 return(res);
00634 }
00635
00636
00637 one = DD_ONE(dd);
00638 lzero = Cudd_Not(one);
00639 azero = DD_ZERO(dd);
00640
00641
00642 T = cuddT(F); E = cuddE(F);
00643 if (Cudd_IsComplement(f)) {
00644 T = Cudd_Not(T); E = Cudd_Not(E);
00645 }
00646 index = F->index;
00647
00648 if (Cudd_IsConstant(T) && T != lzero && T != azero) {
00649
00650
00651
00652
00653
00654 if (E == lzero || E == azero) {
00655
00656 res = tlcInfoAlloc();
00657 if (res == NULL) return(NULL);
00658 res->vars = ALLOC(DdHalfWord,4);
00659 if (res->vars == NULL) {
00660 FREE(res);
00661 return(NULL);
00662 }
00663 res->phases = bitVectorAlloc(2);
00664 if (res->phases == NULL) {
00665 FREE(res->vars);
00666 FREE(res);
00667 return(NULL);
00668 }
00669 res->vars[0] = index;
00670 res->vars[1] = CUDD_MAXINDEX;
00671 res->vars[2] = 0;
00672 res->vars[3] = 0;
00673 bitVectorSet(res->phases, 0, 0);
00674 bitVectorSet(res->phases, 1, 1);
00675 } else if (Cudd_IsConstant(E)) {
00676
00677 res = emptyClauseSet();
00678 } else {
00679
00680 Tres = emptyClauseSet();
00681 if (Tres == NULL) return(NULL);
00682 Eres = ddFindTwoLiteralClausesRecur(dd, E, table);
00683 if (Eres == NULL) {
00684 Cudd_tlcInfoFree(Tres);
00685 return(NULL);
00686 }
00687 res = computeClauses(Tres, Eres, index, dd->size);
00688 Cudd_tlcInfoFree(Tres);
00689 }
00690 } else if (T == lzero || T == azero) {
00691
00692
00693
00694
00695 if (Cudd_IsConstant(E)) {
00696
00697 res = tlcInfoAlloc();
00698 if (res == NULL) return(NULL);
00699 res->vars = ALLOC(DdHalfWord,4);
00700 if (res->vars == NULL) {
00701 FREE(res);
00702 return(NULL);
00703 }
00704 res->phases = bitVectorAlloc(2);
00705 if (res->phases == NULL) {
00706 FREE(res->vars);
00707 FREE(res);
00708 return(NULL);
00709 }
00710 res->vars[0] = index;
00711 res->vars[1] = CUDD_MAXINDEX;
00712 res->vars[2] = 0;
00713 res->vars[3] = 0;
00714 bitVectorSet(res->phases, 0, 1);
00715 bitVectorSet(res->phases, 1, 1);
00716 } else {
00717 Eres = ddFindTwoLiteralClausesRecur(dd, E, table);
00718 if (Eres == NULL) return(NULL);
00719 res = computeClausesWithUniverse(Eres, index, 1);
00720 }
00721 } else {
00722 Tres = ddFindTwoLiteralClausesRecur(dd, T, table);
00723 if (Tres == NULL) return(NULL);
00724 if (Cudd_IsConstant(E)) {
00725 if (E == lzero || E == azero) {
00726 res = computeClausesWithUniverse(Tres, index, 0);
00727 } else {
00728 Eres = emptyClauseSet();
00729 if (Eres == NULL) return(NULL);
00730 res = computeClauses(Tres, Eres, index, dd->size);
00731 Cudd_tlcInfoFree(Eres);
00732 }
00733 } else {
00734 Eres = ddFindTwoLiteralClausesRecur(dd, E, table);
00735 if (Eres == NULL) return(NULL);
00736 res = computeClauses(Tres, Eres, index, dd->size);
00737 }
00738 }
00739
00740
00741 if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) {
00742 FREE(res);
00743 return(NULL);
00744 }
00745 return(res);
00746
00747 }
00748
00749
00763 static DdTlcInfo *
00764 computeClauses(
00765 DdTlcInfo *Tres ,
00766 DdTlcInfo *Eres ,
00767 DdHalfWord label ,
00768 int size )
00769 {
00770 DdHalfWord *Tcv = Tres->vars;
00771 BitVector *Tcp = Tres->phases;
00772 DdHalfWord *Ecv = Eres->vars;
00773 BitVector *Ecp = Eres->phases;
00774 DdHalfWord *Vcv = NULL;
00775 BitVector *Vcp = NULL;
00776 DdTlcInfo *res = NULL;
00777 int pt = 0;
00778 int pe = 0;
00779 int cv = 0;
00780 TlClause *iclauses = NULL;
00781 TlClause *tclauses = NULL;
00782 TlClause *eclauses = NULL;
00783 TlClause *nclauses = NULL;
00784 TlClause *lnclause = NULL;
00785 TlClause *newclause;
00786
00787
00788
00789
00790
00791
00792 bitVectorClear(Tolv, size);
00793 bitVectorClear(Tolp, size);
00794 bitVectorClear(Eolv, size);
00795 bitVectorClear(Eolp, size);
00796
00797
00798 res = tlcInfoAlloc();
00799 if (res == NULL) goto cleanup;
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) {
00811 if (equalp(Tcv[pt], bitVectorRead(Tcp, pt),
00812 Tcv[pt+1], bitVectorRead(Tcp, pt+1),
00813 Ecv[pe], bitVectorRead(Ecp, pe),
00814 Ecv[pe+1], bitVectorRead(Ecp, pe+1))) {
00815
00816 newclause = ALLOC(TlClause,1);
00817 if (newclause == NULL) goto cleanup;
00818 newclause->v1 = Tcv[pt];
00819 newclause->v2 = Tcv[pt+1];
00820 newclause->p1 = bitVectorRead(Tcp, pt);
00821 newclause->p2 = bitVectorRead(Tcp, pt+1);
00822 newclause->next = iclauses;
00823 iclauses = newclause;
00824 pt += 2; pe += 2; cv++;
00825 } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt),
00826 Tcv[pt+1], bitVectorRead(Tcp, pt+1),
00827 Ecv[pe], bitVectorRead(Ecp, pe),
00828 Ecv[pe+1], bitVectorRead(Ecp, pe+1))) {
00829 if (oneliteralp(Tcv[pt+1])) {
00830
00831 newclause = ALLOC(TlClause,1);
00832 if (newclause == NULL) goto cleanup;
00833 newclause->v1 = Tcv[pt];
00834 newclause->v2 = CUDD_MAXINDEX;
00835 newclause->p1 = bitVectorRead(Tcp, pt);
00836 newclause->p2 = 1;
00837 newclause->next = tclauses;
00838 tclauses = newclause;
00839 bitVectorSet(Tolv, Tcv[pt], 1);
00840 bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt));
00841 } else {
00842 if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt),
00843 Tcv[pt+1], bitVectorRead(Tcp, pt+1),
00844 Eolv, Eolp)) {
00845
00846 newclause = ALLOC(TlClause,1);
00847 if (newclause == NULL) goto cleanup;
00848 newclause->v1 = Tcv[pt];
00849 newclause->v2 = Tcv[pt+1];
00850 newclause->p1 = bitVectorRead(Tcp, pt);
00851 newclause->p2 = bitVectorRead(Tcp, pt+1);
00852 newclause->next = iclauses;
00853 iclauses = newclause;
00854 cv++;
00855 }
00856 }
00857 pt += 2;
00858 } else {
00859 if (oneliteralp(Ecv[pe+1])) {
00860
00861 newclause = ALLOC(TlClause,1);
00862 if (newclause == NULL) goto cleanup;
00863 newclause->v1 = Ecv[pe];
00864 newclause->v2 = CUDD_MAXINDEX;
00865 newclause->p1 = bitVectorRead(Ecp, pe);
00866 newclause->p2 = 1;
00867 newclause->next = eclauses;
00868 eclauses = newclause;
00869 bitVectorSet(Eolv, Ecv[pe], 1);
00870 bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe));
00871 } else {
00872 if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe),
00873 Ecv[pe+1], bitVectorRead(Ecp, pe+1),
00874 Tolv, Tolp)) {
00875
00876 newclause = ALLOC(TlClause,1);
00877 if (newclause == NULL) goto cleanup;
00878 newclause->v1 = Ecv[pe];
00879 newclause->v2 = Ecv[pe+1];
00880 newclause->p1 = bitVectorRead(Ecp, pe);
00881 newclause->p2 = bitVectorRead(Ecp, pe+1);
00882 newclause->next = iclauses;
00883 iclauses = newclause;
00884 cv++;
00885 }
00886 }
00887 pe += 2;
00888 }
00889 }
00890
00891
00892
00893 newclause = ALLOC(TlClause,1);
00894 if (newclause == NULL) goto cleanup;
00895 newclause->v1 = label;
00896 newclause->v2 = CUDD_MAXINDEX;
00897 newclause->p1 = 0;
00898 newclause->p2 = 1;
00899 newclause->next = tclauses;
00900 tclauses = newclause;
00901 newclause = ALLOC(TlClause,1);
00902 if (newclause == NULL) goto cleanup;
00903 newclause->v1 = label;
00904 newclause->v2 = CUDD_MAXINDEX;
00905 newclause->p1 = 1;
00906 newclause->p2 = 1;
00907 newclause->next = eclauses;
00908 eclauses = newclause;
00909
00910
00911
00912
00913 while (tclauses != NULL && eclauses != NULL) {
00914 if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2,
00915 tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) {
00916 TlClause *nextclause = tclauses->next;
00917 TlClause *otherclauses = eclauses;
00918 while (otherclauses != NULL) {
00919 if (tclauses->v1 != otherclauses->v1) {
00920 newclause = ALLOC(TlClause,1);
00921 if (newclause == NULL) goto cleanup;
00922 newclause->v1 = tclauses->v1;
00923 newclause->v2 = otherclauses->v1;
00924 newclause->p1 = tclauses->p1;
00925 newclause->p2 = otherclauses->p1;
00926 newclause->next = NULL;
00927 if (nclauses == NULL) {
00928 nclauses = newclause;
00929 lnclause = newclause;
00930 } else {
00931 lnclause->next = newclause;
00932 lnclause = newclause;
00933 }
00934 cv++;
00935 }
00936 otherclauses = otherclauses->next;
00937 }
00938 FREE(tclauses);
00939 tclauses = nextclause;
00940 } else {
00941 TlClause *nextclause = eclauses->next;
00942 TlClause *otherclauses = tclauses;
00943 while (otherclauses != NULL) {
00944 if (eclauses->v1 != otherclauses->v1) {
00945 newclause = ALLOC(TlClause,1);
00946 if (newclause == NULL) goto cleanup;
00947 newclause->v1 = eclauses->v1;
00948 newclause->v2 = otherclauses->v1;
00949 newclause->p1 = eclauses->p1;
00950 newclause->p2 = otherclauses->p1;
00951 newclause->next = NULL;
00952 if (nclauses == NULL) {
00953 nclauses = newclause;
00954 lnclause = newclause;
00955 } else {
00956 lnclause->next = newclause;
00957 lnclause = newclause;
00958 }
00959 cv++;
00960 }
00961 otherclauses = otherclauses->next;
00962 }
00963 FREE(eclauses);
00964 eclauses = nextclause;
00965 }
00966 }
00967 while (tclauses != NULL) {
00968 TlClause *nextclause = tclauses->next;
00969 FREE(tclauses);
00970 tclauses = nextclause;
00971 }
00972 while (eclauses != NULL) {
00973 TlClause *nextclause = eclauses->next;
00974 FREE(eclauses);
00975 eclauses = nextclause;
00976 }
00977
00978
00979
00980
00981 Vcv = ALLOC(DdHalfWord, 2*(cv+1));
00982 if (Vcv == NULL) goto cleanup;
00983 if (cv > 0) {
00984 Vcp = bitVectorAlloc(2*cv);
00985 if (Vcp == NULL) goto cleanup;
00986 } else {
00987 Vcp = NULL;
00988 }
00989 res->vars = Vcv;
00990 res->phases = Vcp;
00991
00992 Vcv[2*cv] = 0;
00993 Vcv[2*cv+1] = 0;
00994 while (iclauses != NULL || nclauses != NULL) {
00995 TlClause *nextclause;
00996 cv--;
00997 if (nclauses == NULL || (iclauses != NULL &&
00998 beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2,
00999 iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) {
01000 Vcv[2*cv] = iclauses->v1;
01001 Vcv[2*cv+1] = iclauses->v2;
01002 bitVectorSet(Vcp, 2*cv, iclauses->p1);
01003 bitVectorSet(Vcp, 2*cv+1, iclauses->p2);
01004 nextclause = iclauses->next;
01005 FREE(iclauses);
01006 iclauses = nextclause;
01007 } else {
01008 Vcv[2*cv] = nclauses->v1;
01009 Vcv[2*cv+1] = nclauses->v2;
01010 bitVectorSet(Vcp, 2*cv, nclauses->p1);
01011 bitVectorSet(Vcp, 2*cv+1, nclauses->p2);
01012 nextclause = nclauses->next;
01013 FREE(nclauses);
01014 nclauses = nextclause;
01015 }
01016 }
01017 assert(cv == 0);
01018
01019 return(res);
01020
01021 cleanup:
01022 if (res != NULL) Cudd_tlcInfoFree(res);
01023 while (iclauses != NULL) {
01024 TlClause *nextclause = iclauses->next;
01025 FREE(iclauses);
01026 iclauses = nextclause;
01027 }
01028 while (nclauses != NULL) {
01029 TlClause *nextclause = nclauses->next;
01030 FREE(nclauses);
01031 nclauses = nextclause;
01032 }
01033 while (tclauses != NULL) {
01034 TlClause *nextclause = tclauses->next;
01035 FREE(tclauses);
01036 tclauses = nextclause;
01037 }
01038 while (eclauses != NULL) {
01039 TlClause *nextclause = eclauses->next;
01040 FREE(eclauses);
01041 eclauses = nextclause;
01042 }
01043
01044 return(NULL);
01045
01046 }
01047
01048
01063 static DdTlcInfo *
01064 computeClausesWithUniverse(
01065 DdTlcInfo *Cres ,
01066 DdHalfWord label ,
01067 short phase )
01068 {
01069 DdHalfWord *Ccv = Cres->vars;
01070 BitVector *Ccp = Cres->phases;
01071 DdHalfWord *Vcv = NULL;
01072 BitVector *Vcp = NULL;
01073 DdTlcInfo *res = NULL;
01074 int i;
01075
01076
01077 res = tlcInfoAlloc();
01078 if (res == NULL) goto cleanup;
01079
01080 for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2);
01081
01082
01083
01084 Vcv = ALLOC(DdHalfWord,i+4);
01085 if (Vcv == NULL) goto cleanup;
01086 Vcp = bitVectorAlloc(i+4);
01087 if (Vcp == NULL) goto cleanup;
01088 res->vars = Vcv;
01089 res->phases = Vcp;
01090
01091 for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) {
01092 Vcv[i] = Ccv[i];
01093 Vcv[i+1] = Ccv[i+1];
01094 bitVectorSet(Vcp, i, bitVectorRead(Ccp, i));
01095 bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1));
01096 }
01097
01098 Vcv[i] = label;
01099 bitVectorSet(Vcp, i, phase);
01100 i++;
01101 Vcv[i] = CUDD_MAXINDEX;
01102 bitVectorSet(Vcp, i, 1);
01103 i++;
01104
01105 Vcv[i] = 0;
01106 Vcv[i+1] = 0;
01107 bitVectorSet(Vcp, i, 0);
01108 bitVectorSet(Vcp, i+1, 0);
01109
01110 return(res);
01111
01112 cleanup:
01113
01114 if (Vcv != NULL) FREE(Vcv);
01115 if (res != NULL) Cudd_tlcInfoFree(res);
01116
01117 return(NULL);
01118
01119 }
01120
01121
01135 static DdTlcInfo *
01136 emptyClauseSet(void)
01137 {
01138 DdTlcInfo *eset;
01139
01140 eset = ALLOC(DdTlcInfo,1);
01141 if (eset == NULL) return(NULL);
01142 eset->vars = ALLOC(DdHalfWord,2);
01143 if (eset->vars == NULL) {
01144 FREE(eset);
01145 return(NULL);
01146 }
01147
01148 eset->vars[0] = 0;
01149 eset->vars[1] = 0;
01150 eset->phases = NULL;
01151 eset->cnt = 0;
01152 return(eset);
01153
01154 }
01155
01156
01169 static int
01170 sentinelp(
01171 DdHalfWord var1,
01172 DdHalfWord var2)
01173 {
01174 return(var1 == 0 && var2 == 0);
01175
01176 }
01177
01178
01192 static int
01193 equalp(
01194 DdHalfWord var1a,
01195 short phase1a,
01196 DdHalfWord var1b,
01197 short phase1b,
01198 DdHalfWord var2a,
01199 short phase2a,
01200 DdHalfWord var2b,
01201 short phase2b)
01202 {
01203 return(var1a == var2a && phase1a == phase2a &&
01204 var1b == var2b && phase1b == phase2b);
01205
01206 }
01207
01208
01228 static int
01229 beforep(
01230 DdHalfWord var1a,
01231 short phase1a,
01232 DdHalfWord var1b,
01233 short phase1b,
01234 DdHalfWord var2a,
01235 short phase2a,
01236 DdHalfWord var2b,
01237 short phase2b)
01238 {
01239 return(var1a > var2a || (var1a == var2a &&
01240 (phase1a < phase2a || (phase1a == phase2a &&
01241 (var1b > var2b || (var1b == var2b && phase1b < phase2b))))));
01242
01243 }
01244
01245
01260 static int
01261 oneliteralp(
01262 DdHalfWord var)
01263 {
01264 return(var == CUDD_MAXINDEX);
01265
01266 }
01267
01268
01283 static int
01284 impliedp(
01285 DdHalfWord var1,
01286 short phase1,
01287 DdHalfWord var2,
01288 short phase2,
01289 BitVector *olv,
01290 BitVector *olp)
01291 {
01292 return((bitVectorRead(olv, var1) &&
01293 bitVectorRead(olp, var1) == phase1) ||
01294 (bitVectorRead(olv, var2) &&
01295 bitVectorRead(olp, var2) == phase2));
01296
01297 }
01298
01299
01314 static BitVector *
01315 bitVectorAlloc(
01316 int size)
01317 {
01318 int allocSize;
01319 BitVector *vector;
01320
01321
01322
01323
01324
01325 allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1;
01326 vector = ALLOC(BitVector, allocSize);
01327 if (vector == NULL) return(NULL);
01328
01329 (void) memset(vector, 0, allocSize * sizeof(BitVector));
01330 return(vector);
01331
01332 }
01333
01334
01347 DD_INLINE
01348 static void
01349 bitVectorClear(
01350 BitVector *vector,
01351 int size)
01352 {
01353 int allocSize;
01354
01355
01356
01357
01358
01359 allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1;
01360
01361 (void) memset(vector, 0, allocSize * sizeof(BitVector));
01362 return;
01363
01364 }
01365
01366
01378 static void
01379 bitVectorFree(
01380 BitVector *vector)
01381 {
01382 FREE(vector);
01383
01384 }
01385
01386
01398 DD_INLINE
01399 static short
01400 bitVectorRead(
01401 BitVector *vector,
01402 int i)
01403 {
01404 int word, bit;
01405 short result;
01406
01407 if (vector == NULL) return((short) 0);
01408
01409 word = i >> LOGBPL;
01410 bit = i & (BPL - 1);
01411 result = (short) ((vector[word] >> bit) & 1L);
01412 return(result);
01413
01414 }
01415
01416
01428 DD_INLINE
01429 static void
01430 bitVectorSet(
01431 BitVector * vector,
01432 int i,
01433 short val)
01434 {
01435 int word, bit;
01436
01437 word = i >> LOGBPL;
01438 bit = i & (BPL - 1);
01439 vector[word] &= ~(1L << bit);
01440 vector[word] |= (((long) val) << bit);
01441
01442 }
01443
01444
01457 static DdTlcInfo *
01458 tlcInfoAlloc(void)
01459 {
01460 DdTlcInfo *res = ALLOC(DdTlcInfo,1);
01461 if (res == NULL) return(NULL);
01462 res->vars = NULL;
01463 res->phases = NULL;
01464 res->cnt = 0;
01465 return(res);
01466
01467 }