91 #ifndef DD_UNSORTED_FREE_LIST 92 #ifdef DD_RED_BLACK_FREE_LIST 94 #define DD_STACK_SIZE 128 97 #define DD_PAGE_SIZE 8192 98 #define DD_PAGE_MASK ~(DD_PAGE_SIZE - 1) 121 static char rcsid[]
DD_UNUSED =
"$Id: cuddTable.c,v 1.126 2012/02/05 01:07:19 fabio Exp $";
129 #ifndef DD_UNSORTED_FREE_LIST 130 #ifdef DD_RED_BLACK_FREE_LIST 132 #define DD_INSERT_COMPARE(x,y) \ 133 (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) 134 #define DD_COLOR(p) ((p)->index) 135 #define DD_IS_BLACK(p) ((p)->index == DD_BLACK) 136 #define DD_IS_RED(p) ((p)->index == DD_RED) 137 #define DD_LEFT(p) cuddT(p) 138 #define DD_RIGHT(p) cuddE(p) 139 #define DD_NEXT(p) ((p)->next) 154 #ifdef DD_RED_BLACK_FREE_LIST 157 static void cuddRotateLeft (
DdNodePtr *nodeP);
158 static void cuddRotateRight (
DdNodePtr *nodeP);
159 static void cuddDoRebalance (
DdNodePtr **stack,
int stackN);
163 static int cuddCheckCollisionOrdering (
DdManager *unique,
int i,
int j);
196 while ((
unsigned) (i * i) <= p) {
234 int currentSize = manager->
size;
237 if (currentSize + amount < currentSize)
239 if (amount <= manager->maxSize - manager->
size)
299 MMoutOfMemory = saveHandler;
308 if (unique->
stash != NULL) {
310 unique->
stash = NULL;
324 (void) fprintf(unique->
err,
325 "cuddAllocNode: out of memory");
326 (void) fprintf(unique->
err,
"Memory in use = %lu\n",
349 list[i - 1].
next = &list[i];
381 unsigned int numVars ,
382 unsigned int numVarsZ ,
383 unsigned int numSlots ,
384 unsigned int looseUpTo )
393 if (unique == NULL) {
399 cuddT(sentinel) = NULL;
400 cuddE(sentinel) = NULL;
401 sentinel->
next = NULL;
403 unique->
size = numVars;
404 unique->
sizeZ = numVarsZ;
410 while (slots < numSlots) {
416 unique->
slots = (numVars + numVarsZ + 1) * slots;
440 if (unique->
perm == NULL) {
455 if (unique->
permZ == NULL) {
475 if (unique->
stack == NULL) {
485 unique->
stack[0] = NULL;
487 #ifndef DD_NO_DEATH_ROW 508 for (i = 0; (unsigned) i < numVars; i++) {
521 if (nodelist == NULL) {
522 for (j = 0; j < i; j++) {
535 for (j = 0; (unsigned) j < slots; j++) {
536 nodelist[j] = sentinel;
541 for (i = 0; (unsigned) i < numVarsZ; i++) {
548 if (nodelist == NULL) {
549 for (j = 0; (unsigned) j < numVars; j++) {
553 for (j = 0; j < i; j++) {
565 for (j = 0; (unsigned) j < slots; j++) {
568 unique->
permZ[i] = i;
577 if (nodelist == NULL) {
578 for (j = 0; (unsigned) j < numVars; j++) {
582 for (j = 0; (unsigned) j < numVarsZ; j++) {
594 for (j = 0; (unsigned) j < slots; j++) {
602 * (
sizeof(
DdSubtable) + 2 *
sizeof(
int)) + (numVars + 1) *
605 #ifndef DD_NO_DEATH_ROW 627 unique->
treeZ = NULL;
647 unique->
out = stdout;
648 unique->
err = stderr;
659 unique->nodesDropped = 0;
660 unique->nodesFreed = 0;
663 #ifdef DD_UNIQUE_PROFILE 664 unique->uniqueLookUps = 0;
665 unique->uniqueLinks = 0;
668 unique->recursiveCalls = 0;
669 unique->swapSteps = 0;
671 unique->nextSample = 250000;
700 while (memlist != NULL) {
708 for (i = 0; i < unique->
size; i++) {
711 for (i = 0; i < unique->
sizeZ; i++) {
725 #ifndef DD_NO_DEATH_ROW 770 int i, j, deleted, totalDeleted, totalDeletedZ;
775 unsigned long localTime;
776 #ifndef DD_UNSORTED_FREE_LIST 777 #ifdef DD_RED_BLACK_FREE_LIST 781 DdNode *downTrav, *sentry;
786 #ifndef DD_NO_DEATH_ROW 791 while (hook != NULL) {
792 int res = (hook->
f)(unique,
"DD",NULL);
793 if (res == 0)
return(0);
799 while (hook != NULL) {
800 int res = (hook->
f)(unique,
"DD",NULL);
801 if (res == 0)
return(0);
815 (void) fprintf(unique->
err,
"minDead = %d\n", unique->
minDead);
825 (void) fprintf(unique->
err,
826 "garbage collecting (%d dead BDD nodes out of %d, min %d)...",
828 (void) fprintf(unique->
err,
829 " (%d dead ZDD nodes out of %d)...",
836 for (i = 0; i < slots; i++) {
838 if (c->
data != NULL) {
854 #ifndef DD_UNSORTED_FREE_LIST 855 #ifdef DD_RED_BLACK_FREE_LIST 860 for (i = 0; i < unique->
size; i++) {
866 for (j = 0; j < slots; j++) {
867 lastP = &(nodelist[j]);
869 while (node != sentinel) {
871 if (node->
ref == 0) {
873 #ifndef DD_UNSORTED_FREE_LIST 874 #ifdef DD_RED_BLACK_FREE_LIST 875 cuddOrderedInsert(&tree,node);
882 lastP = &(node->
next);
891 totalDeleted += deleted;
899 for (j = 0; j < slots; j++) {
900 lastP = &(nodelist[j]);
902 while (node != NULL) {
904 if (node->
ref == 0) {
906 #ifndef DD_UNSORTED_FREE_LIST 907 #ifdef DD_RED_BLACK_FREE_LIST 908 cuddOrderedInsert(&tree,node);
915 lastP = &(node->
next);
924 totalDeleted += deleted;
928 if ((
unsigned) totalDeleted != unique->
dead) {
931 unique->
keys -= totalDeleted;
934 unique->nodesFreed += (double) totalDeleted;
939 for (i = 0; i < unique->
sizeZ; i++) {
945 for (j = 0; j < slots; j++) {
946 lastP = &(nodelist[j]);
948 while (node != NULL) {
950 if (node->
ref == 0) {
952 #ifndef DD_UNSORTED_FREE_LIST 953 #ifdef DD_RED_BLACK_FREE_LIST 954 cuddOrderedInsert(&tree,node);
961 lastP = &(node->
next);
970 totalDeletedZ += deleted;
978 if ((
unsigned) totalDeletedZ != unique->
deadZ) {
981 unique->
keysZ -= totalDeletedZ;
984 unique->nodesFreed += (double) totalDeletedZ;
988 #ifndef DD_UNSORTED_FREE_LIST 989 #ifdef DD_RED_BLACK_FREE_LIST 994 while (memListTrav != NULL) {
999 downTrav = (
DdNode *)memListTrav;
1002 if (downTrav[k].ref == 0) {
1003 if (sentry == NULL) {
1004 unique->
nextFree = sentry = &downTrav[k];
1008 sentry = (sentry->
next = &downTrav[k]);
1012 memListTrav = nxtNode;
1014 sentry->
next = NULL;
1021 while (hook != NULL) {
1022 int res = (hook->
f)(unique,
"DD",NULL);
1023 if (res == 0)
return(0);
1028 (void) fprintf(unique->
err,
" done\n");
1031 return(totalDeleted+totalDeletedZ);
1152 #ifdef DD_UNIQUE_PROFILE 1153 unique->uniqueLookUps++;
1156 if ((0x1ffffUL & (
unsigned long) unique->
cacheMisses) == 0) {
1162 if (index >= unique->
size) {
1167 level = unique->
perm[index];
1177 previousP = &(nodelist[pos]);
1178 looking = *previousP;
1180 while (T <
cuddT(looking)) {
1181 previousP = &(looking->
next);
1182 looking = *previousP;
1183 #ifdef DD_UNIQUE_PROFILE 1184 unique->uniqueLinks++;
1187 while (T ==
cuddT(looking) && E <
cuddE(looking)) {
1188 previousP = &(looking->
next);
1189 looking = *previousP;
1190 #ifdef DD_UNIQUE_PROFILE 1191 unique->uniqueLinks++;
1194 if (T ==
cuddT(looking) && E ==
cuddE(looking)) {
1195 if (looking->
ref == 0) {
1205 unsigned long cpuTime;
1208 if (retval != 0)
return(NULL);
1210 if (retval != 0)
return(NULL);
1236 (subtable->
dead > subtable->
keys * 0.95)))) {
1250 previousP = &(nodelist[pos]);
1251 looking = *previousP;
1253 while (T <
cuddT(looking)) {
1254 previousP = &(looking->
next);
1255 looking = *previousP;
1256 #ifdef DD_UNIQUE_PROFILE 1257 unique->uniqueLinks++;
1260 while (T ==
cuddT(looking) && E <
cuddE(looking)) {
1261 previousP = &(looking->
next);
1262 looking = *previousP;
1263 #ifdef DD_UNIQUE_PROFILE 1264 unique->uniqueLinks++;
1271 if (looking == NULL) {
1281 previousP = &(nodelist[pos]);
1282 looking2 = *previousP;
1284 while (T <
cuddT(looking2)) {
1285 previousP = &(looking2->
next);
1286 looking2 = *previousP;
1287 #ifdef DD_UNIQUE_PROFILE 1288 unique->uniqueLinks++;
1291 while (T ==
cuddT(looking2) && E <
cuddE(looking2)) {
1292 previousP = &(looking2->
next);
1293 looking2 = *previousP;
1294 #ifdef DD_UNIQUE_PROFILE 1295 unique->uniqueLinks++;
1299 looking->
index = index;
1302 looking->
next = *previousP;
1303 *previousP = looking;
1308 cuddCheckCollisionOrdering(unique,level,pos);
1385 #ifdef DD_UNIQUE_PROFILE 1386 unique->uniqueLookUps++;
1389 if (index >= unique->
sizeZ) {
1393 level = unique->
permZ[index];
1403 (10 * subtable->
dead > 9 * subtable->
keys))) {
1412 looking = nodelist[pos];
1414 while (looking != NULL) {
1415 if (
cuddT(looking) == T &&
cuddE(looking) == E) {
1416 if (looking->
ref == 0) {
1421 looking = looking->
next;
1422 #ifdef DD_UNIQUE_PROFILE 1423 unique->uniqueLinks++;
1432 if (retval != 0)
return(NULL);
1434 if (retval != 0)
return(NULL);
1451 if (looking == NULL)
return(NULL);
1452 looking->
index = index;
1455 looking->
next = nodelist[pos];
1456 nodelist[pos] = looking;
1488 #ifdef DD_UNIQUE_PROFILE 1489 unique->uniqueLookUps++;
1510 looking = nodelist[pos];
1517 while (looking != NULL) {
1520 if (looking->
ref == 0) {
1525 looking = looking->
next;
1526 #ifdef DD_UNIQUE_PROFILE 1527 unique->uniqueLinks++;
1535 if (looking == NULL)
return(NULL);
1538 looking->
next = nodelist[pos];
1539 nodelist[pos] = looking;
1563 unsigned int slots, oldslots;
1564 int shift, oldshift;
1578 (void) fprintf(unique->
err,
"minDead = %d\n", unique->
minDead);
1587 (void) fprintf(unique->
err,
"minDead = %d\n", unique->
minDead);
1599 slots = oldslots << 1;
1600 shift = oldshift - 1;
1605 MMoutOfMemory = saveHandler;
1606 if (nodelist == NULL) {
1607 (void) fprintf(unique->
err,
1608 "Unable to resize subtable %d for lack of memory\n",
1612 if (unique->
stash != NULL) {
1614 unique->
stash = NULL;
1630 for (j = 0; (unsigned) j < oldslots; j++) {
1632 node = oldnodelist[j];
1633 evenP = &(nodelist[j<<1]);
1634 oddP = &(nodelist[(j<<1)+1]);
1635 while (node != sentinel) {
1640 oddP = &(node->
next);
1643 evenP = &(node->
next);
1647 *evenP = *oddP = sentinel;
1652 (void) fprintf(unique->
err,
1653 "rehashing layer %d: keys %d dead %d new size %d\n",
1667 slots = oldslots << 1;
1668 shift = oldshift - 1;
1672 MMoutOfMemory = saveHandler;
1673 if (nodelist == NULL) {
1674 (void) fprintf(unique->
err,
1675 "Unable to resize constant subtable for lack of memory\n");
1677 for (j = 0; j < unique->
size; j++) {
1687 for (j = 0; (unsigned) j < slots; j++) {
1690 for (j = 0; (unsigned) j < oldslots; j++) {
1691 node = oldnodelist[j];
1692 while (node != NULL) {
1696 node->
next = nodelist[pos];
1697 nodelist[pos] = node;
1704 (void) fprintf(unique->
err,
1705 "rehashing constants: keys %d dead %d new size %d\n",
1713 unique->
slots += (slots - oldslots);
1740 unsigned int slots, oldslots;
1746 slots = oldslots >> 1;
1750 MMoutOfMemory = saveHandler;
1751 if (nodelist == NULL) {
1759 (void) fprintf(unique->
err,
1760 "shrunk layer %d (%d keys) from %d to %d slots\n",
1764 for (j = 0; (unsigned) j < slots; j++) {
1765 nodelist[j] = sentinel;
1768 for (j = 0; (unsigned) j < oldslots; j++) {
1769 node = oldnodelist[j];
1770 while (node != sentinel) {
1775 previousP = &(nodelist[posn]);
1776 looking = *previousP;
1779 while (T <
cuddT(looking)) {
1780 previousP = &(looking->
next);
1781 looking = *previousP;
1782 #ifdef DD_UNIQUE_PROFILE 1783 unique->uniqueLinks++;
1786 while (T ==
cuddT(looking) && E <
cuddE(looking)) {
1787 previousP = &(looking->
next);
1788 looking = *previousP;
1789 #ifdef DD_UNIQUE_PROFILE 1790 unique->uniqueLinks++;
1793 node->
next = *previousP;
1800 unique->
memused += ((long) slots - (
long) oldslots) *
sizeof(
DdNode *);
1801 unique->
slots += slots - oldslots;
1833 int oldsize,newsize;
1834 int i,j,index,reorderSave;
1835 unsigned int numSlots = unique->
initSlots;
1836 int *newperm, *newinvperm, *newmap;
1840 assert(n > 0 && level < unique->size);
1843 oldsize = unique->
size;
1845 if (oldsize + n <= unique->maxSize) {
1847 for (i = oldsize - 1; i >= level; i--) {
1863 unique->
perm[index] += n;
1866 for (i = 0; i < n; i++) {
1879 unique->
perm[oldsize+i] = level + i;
1880 unique->
invperm[level+i] = oldsize + i;
1883 if (newnodelist == NULL) {
1887 for (j = 0; (unsigned) j < numSlots; j++) {
1888 newnodelist[j] = sentinel;
1891 if (unique->
map != NULL) {
1892 for (i = 0; i < n; i++) {
1893 unique->
map[oldsize+i] = oldsize + i;
1903 (void) fprintf(unique->
err,
1904 "Increasing the table size from %d to %d\n",
1909 if (newsubtables == NULL) {
1914 if (newvars == NULL) {
1919 newperm =
ALLOC(
int,newsize);
1920 if (newperm == NULL) {
1926 newinvperm =
ALLOC(
int,newsize);
1927 if (newinvperm == NULL) {
1934 if (unique->
map != NULL) {
1935 newmap =
ALLOC(
int,newsize);
1936 if (newmap == NULL) {
1949 for (i = 0; i < level; i++) {
1962 newvars[i] = unique->
vars[i];
1963 newperm[i] = unique->
perm[i];
1964 newinvperm[i] = unique->
invperm[i];
1967 for (i = level; i < oldsize; i++) {
1968 newperm[i] = unique->
perm[i];
1971 for (i = level; i < level + n; i++) {
1972 newsubtables[i].
slots = numSlots;
1973 newsubtables[i].
shift =
sizeof(int) * 8 -
1975 newsubtables[i].
keys = 0;
1977 newsubtables[i].
dead = 0;
1984 newperm[oldsize + i - level] = i;
1985 newinvperm[i] = oldsize + i - level;
1987 if (newnodelist == NULL) {
1992 for (j = 0; (unsigned) j < numSlots; j++) {
1993 newnodelist[j] = sentinel;
1997 for (i = level; i < oldsize; i++) {
2011 newvars[i] = unique->
vars[i];
2013 newinvperm[i+n] = index;
2014 newperm[index] += n;
2017 if (unique->
map != NULL) {
2018 for (i = 0; i < oldsize; i++) {
2019 newmap[i] = unique->
map[i];
2021 for (i = oldsize; i < oldsize + n; i++) {
2025 unique->
map = newmap;
2032 unique->
vars = newvars;
2034 unique->
perm = newperm;
2041 if (unique->
stack == NULL) {
2045 unique->
stack[0] = NULL;
2052 unique->
slots += n * numSlots;
2063 reorderSave = unique->
autoDyn;
2065 for (i = oldsize; i < oldsize + n; i++) {
2067 if (unique->
vars[i] == NULL) {
2068 unique->
autoDyn = reorderSave;
2070 for (j = oldsize; j < i; j++) {
2073 unique->
vars[j] = NULL;
2075 for (j = level; j < oldsize; j++) {
2099 unique->
perm[index] -= n;
2101 unique->
size = oldsize;
2102 unique->
slots -= n * numSlots;
2109 if (unique->
tree != NULL) {
2114 unique->
autoDyn = reorderSave;
2144 int firstIndex, lastIndex;
2145 int index, level, newlevel;
2151 if (n <= 0)
return(0);
2152 if (n > unique->
size) n = unique->
size;
2155 vars = unique->
vars;
2156 firstIndex = unique->
size - n;
2157 lastIndex = unique->
size;
2165 lowestLevel = unique->
size;
2166 for (index = firstIndex; index < lastIndex; index++) {
2167 level = unique->
perm[index];
2168 if (level < lowestLevel) lowestLevel = level;
2169 nodelist = subtables[level].
nodelist;
2170 if (subtables[level].keys - subtables[level].dead != 1)
return(0);
2177 if (vars[index]->ref != 1) {
2178 if (vars[index]->ref !=
DD_MAXREF)
return(0);
2183 vars[index]->
ref = 1;
2195 for (index = firstIndex; index < lastIndex; index++) {
2196 level = unique->
perm[index];
2197 nodelist = subtables[level].
nodelist;
2199 assert(subtables[level].keys == 0);
2204 unique->
dead -= subtables[level].
dead;
2215 for (level = lowestLevel + 1; level < unique->
size; level++) {
2216 if (subtables[level].keys == 0) {
2220 newlevel = level - shift;
2221 subtables[newlevel].
slots = subtables[level].
slots;
2222 subtables[newlevel].
shift = subtables[level].
shift;
2223 subtables[newlevel].
keys = subtables[level].
keys;
2225 subtables[newlevel].
dead = subtables[level].
dead;
2227 index = unique->
invperm[level];
2228 unique->
perm[index] = newlevel;
2229 unique->
invperm[newlevel] = index;
2239 if (unique->
map != NULL) {
2276 int oldsize,newsize;
2277 int i,j,reorderSave;
2278 unsigned int numSlots = unique->
initSlots;
2279 int *newperm, *newinvperm;
2281 oldsize = unique->
sizeZ;
2283 if (index < unique->maxSizeZ) {
2284 for (i = oldsize; i <= index; i++) {
2291 unique->
permZ[i] = i;
2295 if (newnodelist == NULL) {
2299 for (j = 0; (unsigned) j < numSlots; j++) {
2300 newnodelist[j] = NULL;
2310 (void) fprintf(unique->
err,
2311 "Increasing the ZDD table size from %d to %d\n",
2315 if (newsubtables == NULL) {
2319 newperm =
ALLOC(
int,newsize);
2320 if (newperm == NULL) {
2324 newinvperm =
ALLOC(
int,newsize);
2325 if (newinvperm == NULL) {
2331 if (newsize > unique->
maxSize) {
2334 if (unique->
stack == NULL) {
2338 unique->
stack[0] = NULL;
2343 for (i = 0; i < oldsize; i++) {
2350 newperm[i] = unique->
permZ[i];
2351 newinvperm[i] = unique->
invpermZ[i];
2353 for (i = oldsize; i <= index; i++) {
2354 newsubtables[i].
slots = numSlots;
2355 newsubtables[i].
shift =
sizeof(int) * 8 -
2357 newsubtables[i].
keys = 0;
2359 newsubtables[i].
dead = 0;
2363 if (newnodelist == NULL) {
2367 for (j = 0; (unsigned) j < numSlots; j++) {
2368 newnodelist[j] = NULL;
2375 unique->
permZ = newperm;
2379 unique->
slots += (index + 1 - unique->
sizeZ) * numSlots;
2381 unique->
sizeZ = index + 1;
2421 for (i = 0; i < unique->
size; i++) {
2427 (void) fprintf(unique->
err,
"Slowing down table growth: ");
2428 (void) fprintf(unique->
err,
"GC fraction = %.2f\t", unique->
gcFrac);
2429 (void) fprintf(unique->
err,
"minDead = %u\n", unique->
minDead);
2455 unsigned int slots, oldslots;
2456 int shift, oldshift;
2467 (void) fprintf(unique->
err,
"GC fraction = %.2f\t",
2469 (void) fprintf(unique->
err,
"minDead = %d\n", unique->
minDead);
2488 }
while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys);
2493 MMoutOfMemory = saveHandler;
2494 if (nodelist == NULL) {
2495 (void) fprintf(unique->
err,
2496 "Unable to resize ZDD subtable %d for lack of memory.\n",
2499 for (j = 0; j < unique->
sizeZ; j++) {
2508 for (j = 0; (unsigned) j < slots; j++) {
2511 for (j = 0; (unsigned) j < oldslots; j++) {
2512 node = oldnodelist[j];
2513 while (node != NULL) {
2516 node->
next = nodelist[pos];
2517 nodelist[pos] = node;
2524 (void) fprintf(unique->
err,
2525 "rehashing layer %d: keys %d dead %d new size %d\n",
2532 unique->
slots += (slots - oldslots);
2564 int oldsize,newsize;
2565 int i,j,reorderSave;
2567 int *newperm, *newinvperm, *newmap;
2570 oldsize = unique->
size;
2572 if (index >= 0 && index < unique->maxSize) {
2573 for (i = oldsize; i <= index; i++) {
2586 unique->
perm[i] = i;
2590 if (newnodelist == NULL) {
2591 for (j = oldsize; j < i; j++) {
2597 for (j = 0; j < numSlots; j++) {
2598 newnodelist[j] = sentinel;
2601 if (unique->
map != NULL) {
2602 for (i = oldsize; i <= index; i++) {
2611 newsize = (index < 0) ? amount : index + amount;
2613 (void) fprintf(unique->
err,
2614 "Increasing the table size from %d to %d\n",
2618 if (newsubtables == NULL) {
2623 if (newvars == NULL) {
2628 newperm =
ALLOC(
int,newsize);
2629 if (newperm == NULL) {
2635 newinvperm =
ALLOC(
int,newsize);
2636 if (newinvperm == NULL) {
2643 if (unique->
map != NULL) {
2644 newmap =
ALLOC(
int,newsize);
2645 if (newmap == NULL) {
2660 if (unique->
stack == NULL) {
2665 if (unique->
map != NULL) {
2671 unique->
stack[0] = NULL;
2676 for (i = 0; i < oldsize; i++) {
2689 newvars[i] = unique->
vars[i];
2690 newperm[i] = unique->
perm[i];
2691 newinvperm[i] = unique->
invperm[i];
2693 for (i = oldsize; i <= index; i++) {
2694 newsubtables[i].
slots = numSlots;
2695 newsubtables[i].
shift =
sizeof(int) * 8 -
2697 newsubtables[i].
keys = 0;
2699 newsubtables[i].
dead = 0;
2709 if (newnodelist == NULL) {
2713 for (j = 0; j < numSlots; j++) {
2714 newnodelist[j] = sentinel;
2717 if (unique->
map != NULL) {
2718 for (i = 0; i < oldsize; i++) {
2719 newmap[i] = unique->
map[i];
2721 for (i = oldsize; i <= index; i++) {
2725 unique->
map = newmap;
2731 unique->
vars = newvars;
2733 unique->
perm = newperm;
2746 unique->
size = index + 1;
2747 if (unique->
tree != NULL) {
2750 unique->
slots += (index + 1 - oldsize) * numSlots;
2753 reorderSave = unique->
autoDyn;
2755 for (i = oldsize; i <= index; i++) {
2757 if (unique->
vars[i] == NULL) {
2758 unique->
autoDyn = reorderSave;
2759 for (j = oldsize; j < i; j++) {
2762 unique->
vars[j] = NULL;
2764 for (j = oldsize; j <= index; j++) {
2768 unique->
size = oldsize;
2769 unique->
slots -= (index + 1 - oldsize) * numSlots;
2775 unique->
autoDyn = reorderSave;
2805 for (i =
cuddI(table,node->
index) - 1; i >= 0; i--) {
2809 for (j = 0; j < slots; j++) {
2811 while (
cuddT(f) > node) {
2857 #ifndef DD_UNSORTED_FREE_LIST 2858 #ifdef DD_RED_BLACK_FREE_LIST 2882 while ((scan = *scanP) != NULL) {
2883 stack[stackN++] = scanP;
2884 if (DD_INSERT_COMPARE(node, scan) == 0) {
2885 DD_NEXT(node) = DD_NEXT(scan);
2886 DD_NEXT(scan) = node;
2889 scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan);
2891 DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL;
2892 DD_COLOR(node) = DD_RED;
2894 stack[stackN] = &node;
2895 cuddDoRebalance(stack,stackN);
2925 DdNode *current, *next, *prev, *end;
2934 while (current != NULL) {
2935 if (DD_RIGHT(current) != NULL) {
2943 next = DD_RIGHT(current);
2944 DD_RIGHT(current) = NULL;
2956 for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end));
2957 DD_NEXT(end) = list;
2962 if (DD_LEFT(current) != NULL) {
2963 next = DD_LEFT(current);
2994 DdNode *oldRoot = *nodeP;
2996 *nodeP = newRoot = DD_RIGHT(oldRoot);
2997 DD_RIGHT(oldRoot) = DD_LEFT(newRoot);
2998 DD_LEFT(newRoot) = oldRoot;
3020 DdNode *oldRoot = *nodeP;
3022 *nodeP = newRoot = DD_LEFT(oldRoot);
3023 DD_LEFT(oldRoot) = DD_RIGHT(newRoot);
3024 DD_RIGHT(newRoot) = oldRoot;
3046 DdNode *x, *y, *parent, *grandpa;
3051 while (--stackN >= 0) {
3052 parentP = stack[stackN];
3054 if (DD_IS_BLACK(parent))
break;
3056 grandpaP = stack[stackN-1];
3057 grandpa = *grandpaP;
3058 if (parent == DD_LEFT(grandpa)) {
3059 y = DD_RIGHT(grandpa);
3060 if (y != NULL && DD_IS_RED(y)) {
3061 DD_COLOR(parent) = DD_BLACK;
3062 DD_COLOR(y) = DD_BLACK;
3063 DD_COLOR(grandpa) = DD_RED;
3067 if (x == DD_RIGHT(parent)) {
3068 cuddRotateLeft(parentP);
3069 DD_COLOR(x) = DD_BLACK;
3071 DD_COLOR(parent) = DD_BLACK;
3073 DD_COLOR(grandpa) = DD_RED;
3074 cuddRotateRight(grandpaP);
3078 y = DD_LEFT(grandpa);
3079 if (y != NULL && DD_IS_RED(y)) {
3080 DD_COLOR(parent) = DD_BLACK;
3081 DD_COLOR(y) = DD_BLACK;
3082 DD_COLOR(grandpa) = DD_RED;
3086 if (x == DD_LEFT(parent)) {
3087 cuddRotateRight(parentP);
3088 DD_COLOR(x) = DD_BLACK;
3090 DD_COLOR(parent) = DD_BLACK;
3092 DD_COLOR(grandpa) = DD_RED;
3093 cuddRotateLeft(grandpaP);
3097 DD_COLOR(*(stack[0])) = DD_BLACK;
3124 while (auxnode != NULL) {
3126 if (auxnode->
child != NULL) {
3150 cuddCheckCollisionOrdering(
3163 if (node == sentinel)
return(1);
3165 while (next != sentinel) {
3168 (void) fprintf(unique->
err,
3169 "Unordered list: index %u, position %d\n", i, j);
3198 const char *caller )
3201 (void) fprintf(unique->
err,
3202 "%s: problem in constants\n", caller);
3203 }
else if (i != -1) {
3204 (void) fprintf(unique->
err,
3205 "%s: problem in table %d\n", caller, i);
3207 (void) fprintf(unique->
err,
" dead count != deleted\n");
3208 (void) fprintf(unique->
err,
" This problem is often due to a missing \ 3209 call to Cudd_Ref\n or to an extra call to Cudd_RecursiveDeref.\n \ 3210 See the CUDD Programmer's Guide for additional details.");
static void ddReportRefMess(DdManager *unique, int i, const char *caller)
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
unsigned int Cudd_Prime(unsigned int p)
Cudd_AggregationType groupcheck
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
void cuddZddFreeUniv(DdManager *zdd)
static int ddResizeTable(DdManager *unique, int index, int amount)
void Cudd_OutOfMem(long size)
Cudd_ReorderingType autoMethod
#define cuddIZ(dd, index)
unsigned int peakLiveNodes
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
static void ddPatchTree(DdManager *dd, MtrNode *treenode)
DdHook * preReorderingHook
struct DdManager DdManager
unsigned int maxCacheHard
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
#define Cudd_Regular(node)
void cuddReclaim(DdManager *table, DdNode *n)
void cuddShrinkSubtable(DdManager *unique, int i)
void Mtr_FreeTree(MtrNode *node)
Cudd_ReorderingType autoMethodZ
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
#define DD_DEFAULT_RECOMB
static char rcsid [] DD_UNUSED
void cuddCacheResize(DdManager *table)
unsigned int randomizeOrder
Cudd_VariableType varType
void cuddFreeTable(DdManager *unique)
DdNode * cuddUniqueInterIVO(DdManager *unique, int index, DdNode *T, DdNode *E)
DdNode * cuddZddProduct(DdManager *dd, DdNode *f, DdNode *g)
int cuddDestroySubtables(DdManager *unique, int n)
int cuddResizeTableZdd(DdManager *unique, int index)
DdHook * postReorderingHook
int cuddGarbageCollect(DdManager *unique, int clearCache)
#define DD_SIFT_MAX_SWAPS
Cudd_LazyGroupType varToBeGrouped
static int cuddFindParent(DdManager *table, DdNode *node)
void cuddRehash(DdManager *unique, int i)
int cuddInsertSubtables(DdManager *unique, int n, int level)
int Cudd_DebugCheck(DdManager *table)
DdLocalCache * localCaches
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
#define DD_MAX_CACHE_TO_SLOTS_RATIO
static void ddRehashZdd(DdManager *unique, int i)
void(* MMoutOfMemory)(long)
void cuddLocalCacheClearDead(DdManager *manager)
#define cuddDeallocNode(unique, node)
void cuddReclaimZdd(DdManager *table, DdNode *n)
int Cudd_Reserve(DdManager *manager, int amount)
int Cudd_RemoveHook(DdManager *dd, DD_HFP f, Cudd_HookType where)
#define ddEqualVal(x, y, e)
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
int cuddZddInitUniv(DdManager *zdd)
void cuddSlowTableGrowth(DdManager *unique)
unsigned int maxReorderings
int Cudd_zddReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
void cuddCacheFlush(DdManager *table)
#define DD_DEFAULT_RESIZE
void cuddClearDeathRow(DdManager *table)
int Cudd_CheckKeys(DdManager *table)
#define DD_MAX_REORDER_GROWTH
static DD_INLINE void ddFixLimits(DdManager *unique)
DdNode * cuddZddGetNodeIVO(DdManager *dd, int index, DdNode *g, DdNode *h)
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
DdManager * cuddInitTable(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo)
int cuddComputeFloorLog2(unsigned int value)
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
void cuddShrinkDeathRow(DdManager *table)
DdNode * cuddAllocNode(DdManager *unique)