Esempio n. 1
0
void dfaStoreState(int ds)
{
  default_state = ds;

  bdd_kill_cache(aut->bddm);
  bdd_make_cache(aut->bddm, 8, 4);

  makebdd(aut->bddm);
}
Esempio n. 2
0
/* unite bddPaths */
bdd_ptr unitePaths(bdd_manager *bddm)
{
  int n;
  bdd_ptr p = bddPath[0];

  bdd_make_cache(bddm, 8, 4);
  for (n = 1; n < numExceptions; n++)
    p = bdd_apply2_hashed(bddm, p, bddm, bddPath[n],
			  bddm, &fn_unite);
  bdd_kill_cache(bddm);

  return p;
}
Esempio n. 3
0
void makebdd(bdd_manager *bddm)
{
  bdd_manager *tmp_bddm;
  bdd_ptr united_bdds, default_ptr;
  int i;

  tmp_bddm = bdd_new_manager(8, 4);

  /*
  ** insert a leaf with value 'default_state' in tmp_bddm,
  ** if not already present
  */
  default_ptr = bdd_find_leaf_hashed(tmp_bddm, default_state, SEQUENTIAL_LIST(sub_results), &update_bddpaths); 

  for (exp_count = 0; exp_count < no_exceptions; exp_count++) {
    for (i = 0; i < offsets_size; i++)
      sorted_path[i] = exceptions[exp_count].path[sorted_indices[i]];

    /* clear the cache */
    bdd_kill_cache(tmp_bddm);
    bdd_make_cache(tmp_bddm, 8, 4);
    tmp_bddm->cache_erase_on_doubling = TRUE;

    bddpaths[exp_count] = makepath(tmp_bddm, 0, exceptions[exp_count].value, &update_bddpaths);
    PUSH_SEQUENTIAL_LIST(tmp_bddm->roots, unsigned, bddpaths[exp_count]);
  }    

  if (no_exceptions == 0)
    united_bdds = default_ptr;
  else if (no_exceptions == 1) 
    united_bdds = TOP_SEQUENTIAL_LIST(tmp_bddm->roots);
  else
    united_bdds = unite_roots(tmp_bddm);

  bdd_prepare_apply1(tmp_bddm);
  bdd_apply1(tmp_bddm, united_bdds, bddm, &fn_identity);       /* store the result in bddm->roots */

  bdd_kill_manager(tmp_bddm);
}
Esempio n. 4
0
void double_table_and_cache_hashed(bdd_manager *bddm,
				   unsigned* some_roots,
				   void (*update_fn)(unsigned (*new_place)(unsigned node)),
				   unsigned *p_of_find, unsigned *q_of_find,
				   boolean rehash_p_and_q) {
  unsigned *p;  

  old_bddm = mem_alloc((size_t) sizeof (bdd_manager));
  *old_bddm = *bddm;

  /*make new bigger table, but only if a bigger one is possible */
  if (bddm->table_total_size > BDD_MAX_TOTAL_TABLE_SIZE) {
    printf("\nBDD too large (>%d nodes)\n", BDD_MAX_TOTAL_TABLE_SIZE);
    abort();
  }
  bddm->table_log_size++;
  bddm->table_size *= 2;
  bddm->table_overflow_increment *= 2;
  {
    unsigned desired_size = bddm->table_size + BDD_NUMBER_OF_BINS + 
      bddm->table_overflow_increment;
    bddm->table_total_size = (desired_size <= BDD_MAX_TOTAL_TABLE_SIZE)?
      desired_size: BDD_MAX_TOTAL_TABLE_SIZE;
  }
  bddm->node_table = (bdd_record*) 
    mem_alloc( (size_t)
	       bddm->table_total_size
	       * (sizeof (bdd_record)));
  bddm->table_mask =   bddm->table_size - BDD_NUMBER_OF_BINS; 
  
  bddm->table_double_trigger *= 2;
  bddm->table_overflow =  bddm->table_size + BDD_NUMBER_OF_BINS; 
#ifdef _BDD_STAT_
  bddm->number_double++;
#endif

  /* initialize to unused */
  bddm->table_elements = 0;
  mem_zero(&bddm->node_table[BDD_NUMBER_OF_BINS], (size_t)
	   bddm->table_size * (sizeof (bdd_record)));

  /* initialize bddm roots to the empty list, this new list will
     contain the rehashed addresses of old_bddm->roots*/
  MAKE_SEQUENTIAL_LIST(bddm->roots, unsigned, 1024);
  
  /*now rehash all nodes reachable from the old roots; we must be sure
    that the apply1 operation does not entail doubling of bddm node
    table: this is achieved by our having just doubled the size of the
    table*/

  

  bdd_prepare_apply1(old_bddm);

  for (p = SEQUENTIAL_LIST(old_bddm->roots); *p ;  p++) {
    bdd_apply1(old_bddm, *p, bddm, &double_leaf_fn);    
  }
 
  /*also make sure to rehash portion that is accessible from some_roots*/ 
  for (p = some_roots; *p;  p++) {
    if (*p != BDD_UNDEF)
	*p = bdd_apply1_dont_add_roots(old_bddm, *p, bddm, &double_leaf_fn);    
  }

  /*and fix values p_of_find and q_of_find if indicated*/
  if (rehash_p_and_q) {
    *p_of_find = 
	bdd_apply1_dont_add_roots(old_bddm, *p_of_find, bddm, &double_leaf_fn); 
    *q_of_find = 
	bdd_apply1_dont_add_roots(old_bddm, *q_of_find, bddm, &double_leaf_fn);
  }
  


  /*perform user supplied updates*/
  if (update_fn)
      (*update_fn)(&get_new_r);

  /*old_table now contains nodes whose mark field designates the
    new position of the node*/
  if (bddm->cache) {
    if (bddm->cache_erase_on_doubling) {
        bdd_kill_cache(bddm);
	bdd_make_cache(bddm, 2 * bddm->cache_size * CACHE_NUMBER_OF_BINS, 
		      2 * bddm->cache_overflow_increment * CACHE_NUMBER_OF_BINS);
      }
    else /*this is only a good idea when bddm is different from the  managers
	   the current apply operation is performed over*/
	double_cache(bddm, &get_new_r);
 }

  old_bddm->cache = (cache_record*) 0; /* old cache has been deallocated by now*/

  /*deallocated old table and old roots*/
  bdd_kill_manager(old_bddm);
}
Esempio n. 5
0
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);
  
}