int bdd_makenode(unsigned int level, int low, int high) { register unsigned int hash; register int res; #ifdef CACHESTATS bddcachestats.uniqueAccess++; #endif /* check whether childs are equal */ if (low == high) return low; /* Try to find an existing node of this kind */ hash = NODEHASH(level, low, high); res = HASH(hash); #if defined(SMALL_NODES) if (res != 0) { int m1 = (level << LEV_LPOS) | low; int m2 = ((level << (LEV_HPOS-LEV_LBITS)) & LEV_HMASK) | high; do { if (bddnodes[res].low_llev == m1 && bddnodes[res].high_hlev == m2) { #ifdef CACHESTATS bddcachestats.uniqueHit++; #endif return res; } res = NEXT(res); #ifdef CACHESTATS bddcachestats.uniqueChain++; #endif } while (res != 0); } #else // SMALL_NODES while(res != 0) { if (LEVEL(res) == level && LOW(res) == low && HIGH(res) == high) { #ifdef CACHESTATS bddcachestats.uniqueHit++; #endif return res; } res = NEXT(res); #ifdef CACHESTATS bddcachestats.uniqueChain++; #endif } #endif // SMALL_NODES /* No existing node -> build one */ #ifdef CACHESTATS bddcachestats.uniqueMiss++; #endif /* Any free nodes to use ? */ if (bddfreepos == 0) { if (bdderrorcond) return 0; /* Try to allocate more nodes */ bdd_gbc(); if ((bddnodesize-bddfreenum) >= usednodes_nextreorder && bdd_reorder_ready()) { longjmp(bddexception,1); } if ((bddfreenum*100) / bddnodesize <= minfreenodes) { bdd_noderesize(1); hash = NODEHASH(level, low, high); } /* Panic if that is not possible */ if (bddfreepos == 0) { bdd_error(BDD_NODENUM); bdderrorcond = abs(BDD_NODENUM); return 0; } } /* Build new node */ res = bddfreepos; bddfreepos = NEXT(bddfreepos); bddfreenum--; bddproduced++; { int next = HASH(hash); CREATE_NODE(res, level, low, high, next); /* Insert node */ SETHASH(hash, res); } return res; }
int bdd_makenode(unsigned int level, int low, int high) { register BddNode *node; register unsigned int hash; register int res; #ifdef CACHESTATS bddcachestats.uniqueAccess++; #endif /* check whether childs are equal */ if (low == high) return low; /* Try to find an existing node of this kind */ hash = NODEHASH(level, low, high); res = bddnodes[hash].hash; while(res != 0) { if (LEVEL(res) == level && LOW(res) == low && HIGH(res) == high) { #ifdef CACHESTATS bddcachestats.uniqueHit++; #endif return res; } res = bddnodes[res].next; #ifdef CACHESTATS bddcachestats.uniqueChain++; #endif } /* No existing node -> build one */ #ifdef CACHESTATS bddcachestats.uniqueMiss++; #endif /* Any free nodes to use ? */ if (bddfreepos == 0) { if (bdderrorcond) return 0; /* Try to allocate more nodes */ bdd_gbc(); if ((bddnodesize-bddfreenum) >= usednodes_nextreorder && bdd_reorder_ready()) { longjmp(bddexception,1); } if ((bddfreenum*100) / bddnodesize <= minfreenodes) { bdd_noderesize(1); hash = NODEHASH(level, low, high); } /* Panic if that is not possible */ if (bddfreepos == 0) { bdd_error(BDD_NODENUM); bdderrorcond = abs(BDD_NODENUM); return 0; } } /* Build new node */ res = bddfreepos; bddfreepos = bddnodes[bddfreepos].next; bddfreenum--; bddproduced++; node = &bddnodes[res]; LEVELp(node) = level; LOWp(node) = low; HIGHp(node) = high; /* Insert node */ node->next = bddnodes[hash].hash; bddnodes[hash].hash = res; return res; }
int main (int argc, char** argv) { int argi = init_sysCx (&argc, &argv); const int xdomsz = 4; int xdoms[3]; int xfddidcs[3]; bdd ybdds[3]; bdd satbdd; int off; bdd a, b, c, d, e; if (argi < argc) return 1; xdoms[0] = xdoms[1] = xdoms[2] = xdomsz; bdd_init (1000,100); push_losefn_sysCx (bdd_done); off = bdd_extvarnum (1); satbdd = bdd_ithvar (off); xfddidcs[0] = fdd_extdomain (xdoms, 3); xfddidcs[1] = xfddidcs[0] + 1; xfddidcs[2] = xfddidcs[1] + 1; off = bdd_extvarnum (3); printf ("y0:%d y1:%d y2:%d\n", off + 0, off + 1, off + 2); ybdds[0] = bdd_ithvar (off + 0); ybdds[1] = bdd_ithvar (off + 1); ybdds[2] = bdd_ithvar (off + 2); { int cnt = bdd_getnodenum (); printf ("Start with %d nodes!\n", cnt); } d = satbdd; {:for (i ; 3) a = fdd_equals (xfddidcs[i], xfddidcs[(i+1)%3]); a = bdd_addref (a); b = bdd_biimp (ybdds[i], ybdds[(i+1)%3]); b = bdd_addref (b); e = bdd_imp (a, b); e = bdd_addref (e); bdd_delref (a); bdd_delref (b); c = d; d = bdd_and (c, e); d = bdd_addref (d); bdd_delref (c); bdd_delref (e); } #if 0 a = bdd_satone (d); a = bdd_addref (a); fdd_printset (a); fputc ('\n', stdout); bdd_printset (a); fputc ('\n', stdout); bdd_delref (a); #endif bdd_printtable (d); bdd_delref (d); /* fdd_clearall (); */ { int cnt; bdd_gbc (); cnt = bdd_getnodenum (); printf ("Still have %d nodes!\n", cnt); } lose_sysCx (); return 0; }