static int findVariant(Tree *tree, int num, int idx, Tree **node, unsigned index) { /* find the (unique) leaf node with a 1 */ int v = -1; if (tree && !tree->empty) { if (num > 1) { /* search the variant-tree */ v = findVariant(tree->left, (num+1)/2, idx, node, index); if (v == -1) v = findVariant(tree->right, num/2, idx+(num+1)/2, node, index); } else { trace_descr t, p = find_one_path(tree->bddm, bdd_roots(tree->bddm)[tree->behavior_handle], tree->state); t = p; while (t && (t->index != index)) t = t->next; if (t && t->value) /* read a 1? */ v = idx; /* found the variant */ kill_trace(p); *node = tree; /* remember the node */ } } return v; }
DFA *dfaBuild(char *finals) { int i; unsigned *root_ptr; for (i=0, root_ptr = bdd_roots(aut->bddm); i < no_states; root_ptr++, i++) { aut->q[i] = *root_ptr; aut->f[i] = (finals[i] == '-') ? -1 : (finals[i] == '+' ? 1 : 0); } FREE_SEQUENTIAL_LIST(sub_results); return aut; }
static Tree *printTreeRoot(Tree *tree, unsigned index, int type, char *path) { Tree *res = 0; if (tree && !tree->empty) { trace_descr t, p = find_one_path(tree->bddm, bdd_roots(tree->bddm)[tree->behavior_handle], tree->state); t = p; while (t && (t->index != index)) t = t->next; if (t && t->value) { /* read a 1? */ printf(path); res = tree; } kill_trace(p); if (!res) res = printTreeRootVariants(tree, treetypes[type].numVariants, 0, index, path, type); } return res; }
static void printTypePositions(Tree *tree, unsigned index, int *first, int begin, int all, char path[], int type) { if (tree && !tree->empty) { trace_descr t, p = find_one_path(tree->bddm, bdd_roots(tree->bddm)[tree->behavior_handle], tree->state); t = p; while (t && (t->index != index)) t = t->next; if (t && t->value) { /* read a 1? */ if (!*first) printf(","); printf(path); *first = 0; } kill_trace(p); if (all || *first) printTypePosVariants(tree, treetypes[type].numVariants, 0, index, first, begin, all, path, type); } }
DFA *dfaProduct(DFA* a1, DFA* a2, dfaProductType ff) { DFA *b; int i; unsigned *root_ptr; char binfun[4]; int make_a_loop; unsigned size_estimate = 4 + 4 * (bdd_size(a1->bddm) > bdd_size(a2->bddm) ? bdd_size(a1->bddm) : bdd_size(a2->bddm)); bdd_manager *bddm; /* #define _AUTOMATON_HASHED_IN_PRODUCT_ */ #ifdef _AUTOMATON_HASHED_IN_PRODUCT_ /*prepare hashed access */ bddm = bdd_new_manager(size_estimate, size_estimate/8 + 2); bdd_make_cache(bddm, size_estimate, size_estimate/8 + 2); bddm->cache_erase_on_doubling = TRUE ; #else /*prepare sequential access*/ bddm = bdd_new_manager(size_estimate, 0); bdd_make_cache(bddm, size_estimate, size_estimate/8 + 2); #endif binfun[0] = ff&1; binfun[1] = (ff&2)>>1; /* The binary function */ binfun[2] = (ff&4)>>2; binfun[3] = (ff&8)>>3; qst = qh = qt = new_list(a1->s, a2->s, (list) 0); htbl = new_hash_tab(&hash2, &eq2); insert_in_hash_tab(htbl, a1->s, a2->s, (void *) 1); last_state = 1; /* Careful here! Bdd's start at 0, hashtbl at 1 */ while(qh) { /* Our main loop, nice and tight */ make_a_loop = make_a_loop_status(is_loop(a1->bddm, qh->li1, a1->q[qh->li1]), a1->f[qh->li1], is_loop(a2->bddm, qh->li2, a2->q[qh->li2]), a2->f[qh->li2], binfun); if (make_a_loop != 2) make_loop(bddm, qh->li1, qh->li2); else { #ifdef _AUTOMATON_HASHED_IN_PRODUCT_ (void) bdd_apply2_hashed (a1->bddm, a1->q[qh->li1], a2->bddm, a2->q[qh->li2], bddm, &prod_term_fn); #else (void) bdd_apply2_sequential (a1->bddm, a1->q[qh->li1], a2->bddm, a2->q[qh->li2], bddm, &prod_term_fn); #endif } qh = qh->next; } b = dfaMakeNoBddm(last_state); /* Return the result */ b->s = 0; /* Always first on list */ b->bddm = bddm; for (i=0, root_ptr = bdd_roots(bddm); i < last_state; root_ptr++, i++) { list qnxt; b->q[i] = *root_ptr; b->f[i] = ((a1->f[qst->li1] != 0) && (a2->f[qst->li2] != 0)) ? /* both states are non-bottom, use "binfun" */ BOOL_TO_STATUS(binfun[STATUS_TO_BOOL(a1->f[qst->li1])*2 + STATUS_TO_BOOL(a2->f[qst->li2])]) : /* at least one is bottom */ 0; qnxt = qst->next; mem_free(qst); /* Free the list */ qst = qnxt; } free_hash_tab(htbl); bdd_update_statistics(bddm, (unsigned) PRODUCT); bdd_kill_cache(b->bddm); return(b); }