static bddp hit_z2b_rec(zddp f, my_hash *h)
{
  if(f == zdd_top()) return bdd_bot();
  if(f == zdd_bot()) return bdd_top();

  bddp r;
  if(ht_search((uintptr_t)f, (uintptr_t*)&r, h)) return r;

  INC_RECDEPTH(recdepth);  
  bddp r0 = hit_z2b_rec(zdd_lo(f), h);
  bddp r1 = hit_z2b_rec(zdd_hi(f), h);
  DEC_RECDEPTH(recdepth);

  bddp t = bdd_node(zdd_itemval(f), r1, bdd_top());
  ENSURE_TRUE_MSG(t != BDD_NULL, "BDD operation failed");
  r = bdd_and(r0, t);
  ENSURE_TRUE_MSG(r != BDD_NULL, "BDD operation failed");

  ht_insert((uintptr_t)f, (uintptr_t)r, h);

#ifdef SIZE_LOG
  const uintmax_t insize  = zdd_size(f);
  const uintmax_t outsize = bdd_size(r);
  fprintf(sizelog, "%ju\t%ju\n", insize, outsize);
  if(maxsize < outsize) maxsize = outsize;
#endif /*SIZE_LOG*/

  return r;
}
Exemplo n.º 2
0
void 
print_stat(GTA *g)
{
  unsigned s;
  int dfasize = 0, bddsize = 0;
  for (s = 0; s < guide.numSs; s++) {
    dfasize += g->ss[s].size;
    bddsize += bdd_size(g->ss[s].bddm);
  }
  cout << "(" << dfasize << "," << bddsize << ")";
}
Exemplo n.º 3
0
void
update_largest(GTA *g)
{
  unsigned s;
  int states = 0, nodes = 0;
  for (s = 0; s < guide.numSs; s++) {
    states += g->ss[s].size;
    nodes += bdd_size(g->ss[s].bddm);
  }
  if (states > largest_states)
    largest_states = states;
  if (nodes > largest_bdd)
    largest_bdd = nodes;
}
Exemplo n.º 4
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);
  
}
Exemplo n.º 5
0
int main () {
  GTA* G;
  char **free_vars;
  int *orders; 
  unsigned numvars;
  SSSet *statespaces;

  /*read the automaton from a file, the TRUE argument means that the
    guide is being defined by the automaton description in the file */
  G = gtaImport("html.gta", &free_vars, &orders, &statespaces, TRUE);
  if(!G) {
    printf("error: file 'html.gta' not found (run 'mona -n html.mona')\n");
    exit(1);
  }
  printf("Guide: number of state spaces is %d\n", guide.numSs);
  
  /* illustrate use of state space names */
  {
    SsId d;    
    for (d = 0; d < guide.numSs; d++) 
      printf("State space %s is numbered %d\n", guide.ssName[d], d);
  } 
  
  /* illustrate use of inherited acceptance information */
  {
    SsId d;
    State p;
    int s;
    boolean ***inheritedAcceptance = gtaCalcInheritedAcceptance(G); 
    for (d = 0; d < guide.numSs; d++) {
      printf("State space %d\n", d);
      for (p = 0; p < G->ss[d].size; p++)
        for (s = 1; s >= -1; s--)
          printf(" State %d can%s lead to %s\n", 
                 p, inheritedAcceptance[d][p][s]? "":  " not",
                 (s==1)? "accept":(s==0)? "don't care": "reject");
    }
    gtaFreeInheritedAcceptance(inheritedAcceptance);
  }
  
  /* illustrate how to find indices of free variables and how to find
     out about their order (Boolean, first-order, or second-order) */
  {
    unsigned i;
    numvars = 0;
    while (free_vars[numvars] != 0)
      numvars++;
    printf("Number of free variables: %d\n", numvars);
    if (numvars != 6) {                                      
      printf("Oops\n");
      exit(1);
    } 
    /* get table index of variable G1 */
    for (i = 0; i < numvars; i++)
      if (strcmp(free_vars[i], "G1")==0)
        break;
    if (i == numvars) 
      printf("G1 not found\n");
    else {
      printf("G1 has index %d and is %d. order\n", i, orders[i]);
    }
  }
  
  /* illustrate how to analyze the BDD associated with an entry in the
     transition table */
  
  { /* lookup, say, transition corresponding to state space 1,
       state pair (left, right) = (4,3) */
    unsigned i;
    bdd_ptr my_bdd_ptr = BDD_ROOT(G->ss[1].bddm, BEH(G->ss[1], 4, 3));
    char var_is_used[MAXVARS]; /* var_is_used[i] is true iff variable i
                                  is the index of some BDD node in
                                  the DAG rooted in my_bdd_ptr */
    printf("State space 0 goes to (%d, %d)\n", 
           guide.muLeft[0], guide.muRight[0]);
    printf("State space 1 goes to (%d, %d)\n", 
           guide.muLeft[1], guide.muRight[1]);
    
    printf("Number of BDD nodes in state space 1: %d\n", bdd_size(G->ss[1].bddm));
    for (i = 0; i < numvars; i++)
      var_is_used[i] = 0;
    bdd_prepare_apply1(G->ss[1].bddm);
    my_global_variable = var_is_used;
    global_bddm = (G->ss[1].bddm);
    bdd_operate_on_nodes(G->ss[1].bddm, my_bdd_ptr, &check_off_index);
    
    for (i = 0; i < numvars; i++)
      if (var_is_used[i])
        printf("Variable %s in use for transitions from (4,3) in state space 1\n",
               free_vars[i]); 
  }
  
  /* illustrate how to perform a lookup in the transition table */
  {
    char bit_vector[6] = {0, 1, 1, 0, 1, 0};
    bdd_manager *bddm = G->ss[1].bddm;
    bdd_ptr my_bdd_ptr = BDD_ROOT(bddm, BEH(G->ss[1], 0, 2));
    while (!bdd_is_leaf(bddm, my_bdd_ptr)) {
      my_bdd_ptr =  (bit_vector[bdd_ifindex(bddm, my_bdd_ptr)])?
        bdd_then(bddm, my_bdd_ptr):
        bdd_else(bddm, my_bdd_ptr);
    }
    printf("State reached from (0,2) on {0, 1, 1, 0, 1, 0} is %d\n", 
           bdd_leaf_value(bddm, my_bdd_ptr));
  }

  return 0;
}
Exemplo n.º 6
0
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, &not);
 
  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;
}