bdd_ptr bddpaths[10];

/* function that updates BDD pointers floating around in user's code;
the remaining ones are kept in the sub_results list below */

void update_bddpaths(unsigned (*new_place) (unsigned node)) {
  int j;
  
  /* update the pointers in bddpaths */

  for (j = 0; j < exp_count; j++) 
    bddpaths[j] = new_place(bddpaths[j]);
}

/* we can only update pointers that are not stored as local
   variables, so values of local variables are thrown onto a stack */

DECLARE_SEQUENTIAL_LIST(sub_results, unsigned);

bdd_ptr makepath(bdd_manager *bddm, ..., 
                  void (*update_bddpaths) 
                     (unsigned (*new_place) (unsigned node))) {

...
  bdd_ptr res, sub_res, default_state_ptr;
 
  sub_res = makepath(bddm, n+1, leaf_value, update_bddpaths);

  /* push BDD pointer sub_res on list sub_results */

  PUSH_SEQUENTIAL_LIST(sub_results, unsigned, sub_res);
  
  /* insert a new hashed node; thus potentially changing the pointer
  to the node known as sub_res above, and also potentially changing
  the pointers in bddpaths[10].  But bdd_find_leaf_hashed automatically
  updates all pointers in the sub_results list, since it was provided
  as an argument.  Also, the function update_bddpaths is called when a
  doubling of the table takes place and an appropriate renaming function
  new_place is supplied by bdd_find_leaf_hashed */

  default_state_ptr = 
    bdd_find_leaf_hashed(bddm, 
                         default_state, 
                         SEQUENTIAL_LIST(sub_results), 
                         update_bddpaths);

  /* restore the value of sub_res */

  POP_SEQUENTIAL_LIST(sub_results, unsigned, sub_res);
  ...
}
