/*insert a loop for the product state (p, q) */ GNUC_INLINE void make_loop (bdd_manager *bddm, unsigned p, unsigned q) { int res; res = (int) lookup_in_hash_tab(htbl, p, q); invariant(res); /* res = 0 or id+1 */ (--res); /* make the next entry in bdd_roots(bddm) a leaf with value res; thus a loop is created */ invariant(bdd_roots_length(bddm) == res); #ifdef _AUTOMATON_HASHED_IN_PRODUCT_ bdd_find_leaf_hashed_add_root(bddm, res); #else BDD_ADD_ROOT(bddm, bdd_find_leaf_sequential(bddm, res)); #endif }
/* set default state and make BDD for current state pair */ void gtaStoreDefault(unsigned p) { bdd_ptr united; int n; bdd_manager *tmpBddm; invariant(numExceptions == nextException); defState = p; tmpBddm = bdd_new_manager(100, 10); /* large enough to avoid rehashing??? */ /* COULD AN ASSERTION CHECK THAT REHASHING DOES NOT OCCUR???????? */ /* insert default state as leaf */ def = bdd_find_leaf_hashed_add_root(tmpBddm, defState); /* insert paths for exceptions */ for (exp = 0; exp < numExceptions; exp++) { for (n = 0; n < numOffs; n++) sortedPath[n] = exception[exp].path[sortedIndex[n]]; bddPath[exp] = makePath(tmpBddm, exception[exp].value); } /* unite path roots */ if (numExceptions == 0) united = def; else if (numExceptions == 1) united = bddPath[0]; else united = unitePaths(tmpBddm); /* insert into result BDD manager */ bdd_prepare_apply1(tmpBddm); bdd_apply1(tmpBddm, united, gta->ss[s].bddm, &fn_identity); bdd_kill_manager(tmpBddm); /* set behaviour entry */ BEH(gta->ss[s], left, right) = BDD_LAST_HANDLE(gta->ss[s].bddm); }
/* make path ..... */ bdd_ptr makePath(bdd_manager *bddm, unsigned leafValue) { int n; bdd_ptr p; /* insert leaf node */ p = bdd_find_leaf_hashed_add_root(bddm, leafValue); /* build path bottom-up */ for (n = numOffs - 1; n >= 0; n--) switch (sortedPath[n]) { case '0': p = bdd_find_node_hashed_add_root(bddm, p, def, offs[sortedIndex[n]]); break; case '1': p = bdd_find_node_hashed_add_root(bddm, def, p, offs[sortedIndex[n]]); break; case 'X': /* do nothing */ break; } return p; }
int main() { bdd_manager *bddm, *bddm1; bdd_ptr zero, one; bdd_handle var2, var7; bdd_ptr and_2_7, nand_2_7; /*bdd_handle handle;*/ bdd_init(); /* needed since we're using statistics */ bddm = bdd_new_manager(100,50); /* get a BDD pointer to a node that is the leaf with value 0 */ zero = bdd_find_leaf_hashed_add_root(bddm, 0); /* and a leaf with value 1 */ one = bdd_find_leaf_hashed_add_root(bddm, 1); /* note already at this point "zero" could have been invalidated if the table doubled, but we know that there is room for a 100 nodes---anyway, this is really very bad style, so we go on in a more appropriate manner */ /* "then" part is one, "else" part is zero */ var2 = bdd_handle_find_node_hashed_add_root(bddm, zero, one, 2); var7 = bdd_handle_find_node_hashed_add_root(bddm, zero, one, 7); /* check node pointers and handles */ assert(zero == BDD_ROOT(bddm, 0)); /* since table was not doubled */ assert(one == BDD_ROOT(bddm, 1)); assert(var2 == 2); assert(var7 == 3); bddm1 = bdd_new_manager(100,50); /* make room for at least 100 nodes, overflow increment is 50 */ bdd_make_cache(bddm1, 100, 50); /* apply2 needs a result cache, here the size is a hundred with increment 50 */ /* apply operation on var2 and var7 in bddm; the result is a completely fresh bdd in bddm1 and a BDD pointer, named "and_2_7" */ and_2_7 = bdd_apply2_hashed(bddm, BDD_ROOT(bddm, var2), /* BDD #1 */ bddm, BDD_ROOT(bddm, var7), /* BDD #2 */ bddm1, /* result BDD */ &and); /* leaf operation */ bdd_update_statistics(bddm, 0); /* update statics group "0" with data from bddm before killing the manager */ printf("Size of bddm: %d\n\n", bdd_size(bddm)); /* let's see the number of nodes created */ bdd_kill_manager(bddm); printf("Size of bddm1: %d\n\n", bdd_size(bddm1)); /*handle = BDD_LAST_HANDLE(bddm1);*/ /* assert(handle == 0); assert(BDD_ROOT(bddm1, handle) == and_2_7); */ /* reset all mark fields in bddm1 before an apply1 operation */ bdd_prepare_apply1(bddm1); /* a new bdd (which as an unlabelled graph is isomorphic to old one) in bddm1 is the result of the following apply operation */ /* it's safe here to use and_2_7 since no operations were performed after it was calculated that could have entailed doubling of table */ nand_2_7 = bdd_apply1(bddm1, and_2_7, bddm1, ¬); bdd_update_statistics(bddm1, 1); printf("Size of bddm1: %d\n\n", bdd_size(bddm1)); print_bdd(bddm1, and_2_7); printf("\n\n"); print_bdd(bddm1, nand_2_7); printf("\n\n"); bdd_kill_manager(bddm1); bdd_print_statistics(0, "bddm"); /* print group 0 statistics with heading "bddm" */ bdd_print_statistics(1, "bddm1"); /* print group 1 statistics with heading "bddm1" */ return 0; }