struct fsm_read_handle *fsm_read_init(struct fsm *net) { struct fsm_read_handle *handle; struct fsm_state *fsm; int i, j, k, num_states, num_initials, num_finals, sno, *finals_head, *initials_head, *states_head; unsigned char *lookuptable; if (net == NULL) {return (NULL);} num_states = net->statecount; lookuptable = xxcalloc(num_states, sizeof(unsigned char)); num_initials = num_finals = 0; for (i=0, fsm=net->states; (fsm+i)->state_no != -1; i++) { sno = (fsm+i)->state_no; if ((fsm+i)->start_state) { if (!(*(lookuptable+sno) & 1)) { *(lookuptable+sno) |= 1; num_initials++; } } if ((fsm+i)->final_state) { if (!(*(lookuptable+sno) & 2)) { *(lookuptable+sno) |= 2; num_finals++; } } } finals_head = xxcalloc(num_finals+1,sizeof(int)); initials_head = xxcalloc(num_initials+1,sizeof(int)); states_head = xxcalloc(num_states+1,sizeof(int)); for (i=j=k=0; i < num_states; i++) { if (*(lookuptable+i) & 1) { *(initials_head+j) = i; j++; } if (*(lookuptable+i) & 2) { *(finals_head+k) = i; k++; } *(states_head+i) = i; } *(initials_head+j) = -1; *(finals_head+k) = -1; *(states_head+i) = -1; xxfree(lookuptable); handle = xxcalloc(1,sizeof(struct fsm_read_handle)); handle->finals_head = finals_head; handle->initials_head = initials_head; handle->states_head = states_head; handle->fsm_sigma_list = sigma_to_list(net->sigma); handle->sigma_list_size = sigma_max(net->sigma)+1; handle->arcs_head = fsm; return(handle); }
static void memoize_e_closure(struct fsm_state *fsm) { int i, state, laststate, *redcheck; struct e_closure_memo *ptr; e_closure_memo = xxcalloc(num_states,sizeof(struct e_closure_memo)); marktable = xxcalloc(num_states,sizeof(int)); /* Table for avoiding redundant epsilon arcs in closure */ redcheck = xxmalloc(num_states*sizeof(int)); for (i=0; i < num_states; i++) { ptr = e_closure_memo+i; ptr->state = i; ptr->target = NULL; *(redcheck+i) = -1; } laststate = -1; for (i=0; ;i++) { state = (fsm+i)->state_no; if (state != laststate) { if (!int_stack_isempty()) { deterministic = 0; ptr = e_closure_memo+laststate; ptr->target = e_closure_memo+int_stack_pop(); while (!int_stack_isempty()) { ptr->next = xxmalloc(sizeof(struct e_closure_memo)); ptr->next->state = laststate; ptr->next->target = e_closure_memo+int_stack_pop(); ptr->next->next = NULL; ptr = ptr->next; } } } if (state == -1) { break; } if ((fsm+i)->target == -1) { continue; } /* Check if we have a redundant epsilon arc */ if ((fsm+i)->in == EPSILON && (fsm+i)->out == EPSILON) { if (*(redcheck+((fsm+i)->target)) != (fsm+i)->state_no) { if ((fsm+i)->target != (fsm+i)->state_no) { int_stack_push((fsm+i)->target); *(redcheck+((fsm+i)->target)) = (fsm+i)->state_no; } } laststate = state; } } xxfree(redcheck); }
void apply_create_sigarray(struct apply_handle *h, struct fsm *net) { struct sigma *sig; struct fsm_state *fsm; int i, maxsigma; fsm = net->states; maxsigma = sigma_max(net->sigma); // Default size created at init, resized later if necessary h->sigmatch_array = xxcalloc(1024,sizeof(struct sigmatch_array)); h->sigmatch_array_size = 1024; h->sigs = xxmalloc(sizeof(char **)*(maxsigma+1)); h->has_flags = 0; h->flag_list = NULL; /* Malloc first array of trie and store trie ptrs to free later */ h->sigma_trie = xxcalloc(256,sizeof(struct sigma_trie)); h->sigma_trie_arrays = xxmalloc(sizeof(struct sigma_trie_arrays)); h->sigma_trie_arrays->arr = h->sigma_trie; h->sigma_trie_arrays->next = NULL; for (i=0;i<256;i++) (h->sigma_trie+i)->next = NULL; for (sig = h->gsigma; sig != NULL && sig->number != -1; sig = sig->next) { if (flag_check(sig->symbol)) { h->has_flags = 1; apply_add_flag(h, flag_get_name(sig->symbol)); } *(h->sigs+(sig->number)) = sig->symbol; /* Add sigma entry to trie */ if (sig->number > IDENTITY) { apply_add_sigma_trie(h, sig->number, sig->symbol); } } if (h->has_flags) { h->flag_lookup = xxmalloc(sizeof(struct flag_lookup)*(maxsigma+1)); for (i=0; i <= maxsigma; i++) { (h->flag_lookup+i)->type = 0; (h->flag_lookup+i)->name = NULL; (h->flag_lookup+i)->value = NULL; } for (sig = h->gsigma; sig != NULL ; sig = sig->next) { if (flag_check(sig->symbol)) { (h->flag_lookup+sig->number)->type = flag_get_type(sig->symbol); (h->flag_lookup+sig->number)->name = flag_get_name(sig->symbol); (h->flag_lookup+sig->number)->value = flag_get_value(sig->symbol); } } } }
struct fsm_trie_handle *fsm_trie_init() { struct fsm_trie_handle *th; th = xxcalloc(1,sizeof(struct fsm_trie_handle)); th->trie_hash = xxcalloc(THASH_TABLESIZE, sizeof(struct trie_hash)); th->trie_states = xxcalloc(TRIE_STATESIZE, sizeof(struct trie_states)); th->statesize = TRIE_STATESIZE; th->trie_cursor = 0; th->sh_hash = sh_init(); return(th); }
void apply_mark_flagstates(struct apply_handle *h) { int i; struct fsm_state *fsm; /* Create bitarray with those states that have a flag symbol on an arc */ /* This is needed to decide whether we can perform a binary search. */ if (!h->has_flags || h->flag_lookup == NULL) { return; } if (h->flagstates) { xxfree(h->flagstates); } h->flagstates = xxcalloc(BITNSLOTS(h->last_net->statecount), sizeof(uint8_t)); fsm = h->last_net->states; for (i=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->target == -1) { continue; } if ((h->flag_lookup+(fsm+i)->in)->type) { BITSET(h->flagstates,(fsm+i)->state_no); } if ((h->flag_lookup+(fsm+i)->out)->type) { BITSET(h->flagstates,(fsm+i)->state_no); } } }
void apply_add_sigma_trie(struct apply_handle *h, int number, char *symbol, int len) { /* Create a trie of sigma symbols (prefixes) so we can */ /* quickly (in O(n)) tokenize an arbitrary string into */ /* integer sequences representing symbols, using longest- */ /* leftmost factorization. */ int i; struct sigma_trie *st; struct sigma_trie_arrays *sta; st = h->sigma_trie; for (i = 0; i < len; i++) { st = st+(unsigned char)*(symbol+i); if (i == (len-1)) { st->signum = number; } else { if (st->next == NULL) { st->next = xxcalloc(256,sizeof(struct sigma_trie)); st = st->next; /* store these arrays to free them later */ sta = xxmalloc(sizeof(struct sigma_trie_arrays)); sta->arr = st; sta->next = h->sigma_trie_arrays; h->sigma_trie_arrays = sta; } else { st = st->next; } } } }
void apply_add_sigma_trie(struct apply_handle *h, int number, char *symbol) { int i, len; struct sigma_trie *st; struct sigma_trie_arrays *sta; len = strlen(symbol); st = h->sigma_trie; for (i = 0; i < len; i++) { st = st+(unsigned char)*(symbol+i); if (i == (len-1)) { st->signum = number; } else { if (st->next == NULL) { st->next = xxcalloc(256,sizeof(struct sigma_trie)); st = st->next; /* store these arrays to free them later */ sta = xxmalloc(sizeof(struct sigma_trie_arrays)); sta->arr = st; sta->next = h->sigma_trie_arrays; h->sigma_trie_arrays = sta; } else { st = st->next; } } } }
static int initial_e_closure(struct fsm *net) { struct fsm_state *fsm; int i,j; finals = xxcalloc(num_states, sizeof(_Bool)); num_start_states = 0; fsm = net->states; /* Create lookups for each state */ for (i=0,j=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->final_state) { finals[(fsm+i)->state_no] = 1; } /* Add the start states as the initial set */ if ((op == SUBSET_TEST_STAR_FREE) || ((fsm+i)->start_state)) { if (*(e_table+((fsm+i)->state_no)) != mainloop) { num_start_states++; numss = (fsm+i)->state_no; *(e_table+((fsm+i)->state_no)) = mainloop; *(temp_move+j) = (fsm+i)->state_no; j++; } } } mainloop++; /* Memoize e-closure(u) */ if (epsilon_symbol != -1) { memoize_e_closure(fsm); } return(e_closure(j)); }
static void generate_inverse(struct fsm *net) { struct fsm_state *fsm; struct trans_array *tptr; struct trans_list *listptr; int i, source, target, offsetcount, symbol, size; fsm = net->states; trans_array = xxcalloc(net->statecount, sizeof(struct trans_array)); trans_list = xxcalloc(net->arccount, sizeof(struct trans_list)); /* Figure out the number of transitions each one has */ for (i=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->target == -1) { continue; } target = (fsm+i)->target; (E+target)->inv_count++; (E+target)->group->inv_count++; (trans_array+target)->size++; } offsetcount = 0; for (i=0; i < net->statecount; i++) { (trans_array+i)->transitions = trans_list + offsetcount; offsetcount += (trans_array+i)->size; } for (i=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->target == -1) { continue; } symbol = symbol_pair_to_single_symbol((fsm+i)->in,(fsm+i)->out); source = (fsm+i)->state_no; target = (fsm+i)->target; tptr = trans_array + target; ((tptr->transitions)+(tptr->tail))->inout = symbol; ((tptr->transitions)+(tptr->tail))->source = source; tptr->tail++; } /* Sort arcs */ for (i=0; i < net->statecount; i++) { listptr = (trans_array+i)->transitions; size = (trans_array+i)->size; if (size > 1) qsort(listptr, size, sizeof(struct trans_list), trans_sort_cmp); } }
struct fsm_construct_handle *fsm_construct_init(char *name) { struct fsm_construct_handle *handle; handle = xxmalloc(sizeof(struct fsm_construct_handle)); handle->fsm_state_list = xxcalloc(1024,sizeof(struct fsm_state_list)); handle->fsm_state_list_size = 1024; handle->fsm_sigma_list = xxcalloc(1024,sizeof(struct fsm_sigma_list)); handle->fsm_sigma_list_size = 1024; handle->fsm_sigma_hash = xxcalloc(SIGMA_HASH_SIZE,sizeof(struct fsm_sigma_hash)); handle->maxstate = -1; handle->maxsigma = -1; handle->numfinals = 0; if (name == NULL) { handle->name = NULL; } else { handle->name = xxstrdup(name); } return(handle); }
struct fsm_sigma_list *sigma_to_list(struct sigma *sigma) { struct fsm_sigma_list *sl; struct sigma *s; sl = xxcalloc(sigma_max(sigma)+1,sizeof(struct fsm_sigma_list)); for (s = sigma; s != NULL && s->number != -1; s = s->next) { (sl+(s->number))->symbol = s->symbol; } return sl; }
static void init(struct fsm *net) { /* A temporary table for handling epsilon closure */ /* to avoid doubles */ e_table = xxcalloc(net->statecount,sizeof(int)); /* Counter for our access tables */ mainloop = 1; /* Temporary table for storing sets and */ /* passing to hash function */ /* Table for listing current results of move & e-closure */ temp_move = xxmalloc((net->statecount + 1) *sizeof(int)); /* We malloc this much memory to begin with for the new fsm */ /* Then grow it by the double as needed */ limit = next_power_of_two(net->linecount); fsm_linecount = 0; sigma_to_pairs(net); /* Optimistically malloc T_ptr array */ /* We allocate memory for a number of pointers to a set of states */ /* To handle fast lookup in array */ /* Optimistically, we choose the initial size to be the number of */ /* states in the non-deterministic fsm */ T_last_unmarked = 0; T_limit = next_power_of_two(num_states); T_ptr = xxcalloc(T_limit,sizeof(struct T_memo)); /* Stores all sets consecutively in one table */ /* T_ptr->set_offset and size */ /* are used to retrieve the set */ set_table_size = next_power_of_two(num_states); set_table = xxmalloc(set_table_size*sizeof(int)); set_table_offset = 0; init_trans_array(net); }
static void nhash_init (int initial_size) { int i; for (i=0; primes[i] < initial_size; i++) { } nhash_load = 0; nhash_tablesize = primes[i]; table = xxcalloc(nhash_tablesize , sizeof(struct nhash_list)); current_setnum = -1; }
/* Return the content based ID for a node. * This includes : * command * input files (content) * output files (name) : * important addition as changed expected outputs may not * be reflected in the command and not present in archive * LATER : environment variables (name:value) * returns a string the caller needs to free **/ char * batch_task_generate_id(struct batch_task *t) { if(t->hash) free(t->hash); unsigned char *hash = xxcalloc(1, sizeof(char *)*SHA1_DIGEST_LENGTH); struct batch_file *f; sha1_context_t context; sha1_init(&context); /* Add command to the archive id */ sha1_update(&context, "C", 1); sha1_update(&context, t->command, strlen(t->command)); sha1_update(&context, "\0", 1); /* Sort inputs for consistent hashing */ list_sort(t->input_files, batch_file_outer_compare); /* add checksum of the node's input files together */ struct list_cursor *cur = list_cursor_create(t->input_files); for(list_seek(cur, 0); list_get(cur, (void**)&f); list_next(cur)) { char * file_id; if(path_is_dir(f->inner_name) == 1){ f->hash = batch_file_generate_id_dir(f->outer_name); file_id = xxstrdup(f->hash); } else{ file_id = batch_file_generate_id(f); } sha1_update(&context, "I", 1); sha1_update(&context, f->outer_name, strlen(f->outer_name)); sha1_update(&context, "C", 1); sha1_update(&context, file_id, strlen(file_id)); sha1_update(&context, "\0", 1); free(file_id); } list_cursor_destroy(cur); /* Sort outputs for consistent hashing */ list_sort(t->output_files, batch_file_outer_compare); /* add checksum of the node's output file names together */ cur = list_cursor_create(t->output_files); for(list_seek(cur, 0); list_get(cur, (void**)&f); list_next(cur)) { sha1_update(&context, "O", 1); sha1_update(&context, f->outer_name, strlen(f->outer_name)); sha1_update(&context, "\0", 1); } list_cursor_destroy(cur); sha1_final(hash, &context); t->hash = xxstrdup(sha1_string(hash)); free(hash); return xxstrdup(t->hash); }
static void init_trans_array(struct fsm *net) { struct trans_list *arrptr; struct fsm_state *fsm; int i, j, laststate, lastsym, inout, size, state; arrptr = trans_list = xxmalloc(net->linecount * sizeof(struct trans_list)); trans_array = xxcalloc(net->statecount, sizeof(struct trans_array)); laststate = -1; fsm = net->states; for (i=0, size = 0; (fsm+i)->state_no != -1; i++) { state = (fsm+i)->state_no; if (state != laststate) { if (laststate != -1) { (trans_array+laststate)->size = size; } (trans_array+state)->transitions = arrptr; size = 0; } laststate = state; if ((fsm+i)->target == -1) continue; inout = symbol_pair_to_single_symbol((fsm+i)->in, (fsm+i)->out); if (inout == epsilon_symbol) continue; arrptr->inout = inout; arrptr->target = (fsm+i)->target; arrptr++; size++; } if (laststate != -1) { (trans_array+laststate)->size = size; } for (i=0; i < net->statecount; i++) { arrptr = (trans_array+i)->transitions; size = (trans_array+i)->size; if (size > 1) { qsort(arrptr, size, sizeof(struct trans_list), trans_sort_cmp); lastsym = -1; /* Figure out if we're already deterministic */ for (j=0; j < size; j++) { if ((arrptr+j)->inout == lastsym) deterministic = 0; lastsym = (arrptr+j)->inout; } } } }
int fsm_isstarfree(struct fsm *net) { #define DFS_WHITE 0 #define DFS_GRAY 1 #define DFS_BLACK 2 struct fsm *sfnet; struct state_array *state_array; struct fsm_state *curr_ptr; int v, vp, is_star_free; short int in; char *dfs_map; sfnet = fsm_subset(net, SUBSET_TEST_STAR_FREE); is_star_free = 1; state_array = map_firstlines(net); ptr_stack_clear(); ptr_stack_push(state_array->transitions); dfs_map = xxcalloc(sfnet->statecount, sizeof(char)); while(!ptr_stack_isempty()) { curr_ptr = ptr_stack_pop(); nopop: v = curr_ptr->state_no; /* source state number */ vp = curr_ptr->target; /* target state number */ if (v == -1 || vp == -1) { *(dfs_map+v) = DFS_BLACK; continue; } *(dfs_map+v) = DFS_GRAY; in = curr_ptr->in; if (*(dfs_map+vp) == DFS_GRAY && in == maxsigma) { /* Not star-free */ is_star_free = 0; break; } if (v == (curr_ptr+1)->state_no) { ptr_stack_push(curr_ptr+1); } if (*(dfs_map+vp) == DFS_WHITE) { curr_ptr = (state_array+vp)->transitions; goto nopop; } } ptr_stack_clear(); xxfree(dfs_map); xxfree(state_array); //stack_add(sfnet); return(is_star_free); }
int fsm_construct_add_symbol(struct fsm_construct_handle *handle, char *symbol) { int i, symnum, reserved; unsigned int hash; struct fsm_sigma_hash *fh, *newfh; char *symdup; /* Is symbol reserved? */ for (i=0, reserved = 0; foma_reserved_symbols[i].symbol != NULL; i++) { if (strcmp(symbol, foma_reserved_symbols[i].symbol) == 0) { symnum = foma_reserved_symbols[i].number; reserved = 1; if (handle->maxsigma < symnum) { handle->maxsigma = symnum; } break; } } if (reserved == 0) { symnum = handle->maxsigma + 1; if (symnum < MINSIGMA) symnum = MINSIGMA; handle->maxsigma = symnum; } if (symnum >= handle->fsm_sigma_list_size) { handle->fsm_sigma_list_size = next_power_of_two(handle->fsm_sigma_list_size); handle->fsm_sigma_list = xxrealloc(handle->fsm_sigma_list, (handle->fsm_sigma_list_size) * sizeof(struct fsm_sigma_list)); } /* Insert into list */ symdup = xxstrdup(symbol); ((handle->fsm_sigma_list)+symnum)->symbol = symdup; /* Insert into hashtable */ hash = fsm_construct_hash_sym(symbol); fh = (handle->fsm_sigma_hash)+hash; if (fh->symbol == NULL) { fh->symbol = symdup; fh->sym = symnum; } else { newfh = xxcalloc(1,sizeof(struct fsm_sigma_hash)); newfh->next = fh->next; fh->next = newfh; newfh->symbol = symdup; newfh->sym = symnum; } return symnum; }
struct fsm_state *fsm_state_init(int sigma_size) { current_fsm_head = xxmalloc(INITIAL_SIZE * sizeof(struct fsm_state)); current_fsm_size = INITIAL_SIZE; current_fsm_linecount = 0; ssize = sigma_size+1; slookup = xxcalloc(ssize*ssize,sizeof(struct sigma_lookup)); mainloop = 1; is_deterministic = 1; is_epsilon_free = 1; arccount = 0; num_finals = 0; num_initials = 0; statecount = 0; arity = 1; current_trans = 1; return(current_fsm_head); }
void fsm_trie_symbol(struct fsm_trie_handle *th, char *insym, char *outsym) { unsigned int h; struct trie_hash *thash, *newthash; h = trie_hashf(th->trie_cursor, insym, outsym); if ((th->trie_hash+h)->insym != NULL) { for (thash = th->trie_hash+h; thash != NULL; thash = thash->next) { if (strcmp(thash->insym, insym) == 0 && strcmp(thash->outsym, outsym) == 0 && thash->sourcestate == th->trie_cursor) { /* Exists, move cursor */ th->trie_cursor = thash->targetstate; return; } } } /* Doesn't exist */ /* Insert trans, move counter and cursor */ th->used_states++; thash = th->trie_hash+h; if (thash->insym == NULL) { thash->insym = sh_find_add_string(th->sh_hash, insym,1); thash->outsym = sh_find_add_string(th->sh_hash, outsym,1); thash->sourcestate = th->trie_cursor; thash->targetstate = th->used_states; } else { newthash = xxcalloc(1, sizeof(struct trie_hash)); newthash->next = thash->next; newthash->insym = sh_find_add_string(th->sh_hash, insym,1); newthash->outsym = sh_find_add_string(th->sh_hash, outsym,1); newthash->sourcestate = th->trie_cursor; newthash->targetstate = th->used_states; thash->next = newthash; } th->trie_cursor = th->used_states; /* Realloc */ if (th->used_states >= th->statesize) { th->statesize = next_power_of_two(th->statesize); th->trie_states = xxrealloc(th->trie_states, th->statesize * sizeof(struct trie_states)); } (th->trie_states+th->used_states)->is_final = 0; }
static void nhash_rebuild_table () { int i, oldsize; struct nhash_list *oldtable, *tableptr, *ntableptr, *newptr; unsigned int hashval; oldtable = table; oldsize = nhash_tablesize; nhash_load = 0; for (i=0; primes[i] < nhash_tablesize; i++) { } nhash_tablesize = primes[(i+1)]; table = xxcalloc(nhash_tablesize,sizeof(struct nhash_list)); for (i=0; i < oldsize;i++) { if ((oldtable+i)->size == 0) { continue; } tableptr = oldtable+i; for ( ; tableptr != NULL; (tableptr = tableptr->next)) { /* rehash */ hashval = hashf(set_table+tableptr->set_offset,tableptr->size); ntableptr = table+hashval; if (ntableptr->size == 0) { nhash_load++; ntableptr->size = tableptr->size; ntableptr->set_offset = tableptr->set_offset; ntableptr->setnum = tableptr->setnum; ntableptr->next = NULL; } else { newptr = xxmalloc(sizeof(struct nhash_list)); newptr->next = ntableptr->next; ntableptr->next = newptr; newptr->setnum = tableptr->setnum; newptr->size = tableptr->size; newptr->set_offset = tableptr->set_offset; } } } nhash_free(oldtable, oldsize); }
char *escape_string(char *string, char chr) { size_t i,j; char *newstring; for (i=0,j=0; i < strlen(string); i++) { if (string[i] == chr) { j++; } } if (j>0) { newstring = xxcalloc((strlen(string)+j),sizeof(char)); for (i=0,j=0; i<strlen(string); i++, j++) { if (string[i] == chr) { newstring[j++] = '\\'; newstring[j] = chr; } else { newstring[j] = string[i]; } } return(newstring); } else { return(string); } }
void fsm_construct_copy_sigma(struct fsm_construct_handle *handle, struct sigma *sigma) { unsigned int hash; int symnum; struct fsm_sigma_hash *fh, *newfh; char *symbol, *symdup; for (; sigma != NULL && sigma->number != -1; sigma = sigma->next) { symnum = sigma->number; if (symnum > handle->maxsigma) { handle->maxsigma = symnum; } symbol = sigma->symbol; if (symnum >= handle->fsm_sigma_list_size) { handle->fsm_sigma_list_size = next_power_of_two(handle->fsm_sigma_list_size); handle->fsm_sigma_list = xxrealloc(handle->fsm_sigma_list, (handle->fsm_sigma_list_size) * sizeof(struct fsm_sigma_list)); } /* Insert into list */ symdup = xxstrdup(symbol); ((handle->fsm_sigma_list)+symnum)->symbol = symdup; /* Insert into hashtable */ hash = fsm_construct_hash_sym(symbol); fh = (handle->fsm_sigma_hash)+hash; if (fh->symbol == NULL) { fh->symbol = symdup; fh->sym = symnum; } else { newfh = xxcalloc(1,sizeof(struct fsm_sigma_hash)); newfh->next = fh->next; fh->next = newfh; newfh->symbol = symdup; newfh->sym = symnum; } } }
static void sigma_to_pairs(struct fsm *net) { int i, j, x, y, z, next_x = 0; struct fsm_state *fsm; fsm = net->states; epsilon_symbol = -1; maxsigma = sigma_max(net->sigma); maxsigma++; single_sigma_array = xxmalloc(2*maxsigma*maxsigma*sizeof(int)); double_sigma_array = xxmalloc(maxsigma*maxsigma*sizeof(int)); for (i=0; i < maxsigma; i++) { for (j=0; j< maxsigma; j++) { *(double_sigma_array+maxsigma*i+j) = -1; } } /* f(x) -> y,z sigma pair */ /* f(y,z) -> x simple entry */ /* if exists f(n) <-> EPSILON, EPSILON, save n */ /* symbol(x) x>=1 */ /* Forward mapping: */ /* *(double_sigma_array+maxsigma*in+out) */ /* Backmapping: */ /* *(single_sigma_array+(symbol*2) = in(symbol) */ /* *(single_sigma_array+(symbol*2+1) = out(symbol) */ /* Table for checking whether a state is final */ finals = xxcalloc(num_states, sizeof(_Bool)); x = 0; num_finals = 0; net->arity = 1; for (i=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->final_state == 1 && finals[(fsm+i)->state_no] != 1) { num_finals++; finals[(fsm+i)->state_no] = 1; } y = (fsm+i)->in; z = (fsm+i)->out; if (y != z || y == UNKNOWN || z == UNKNOWN) net->arity = 2; if ((y == -1) || (z == -1)) continue; if (*(double_sigma_array+maxsigma*y+z) == -1) { *(double_sigma_array+maxsigma*y+z) = x; *(single_sigma_array+next_x) = y; next_x++; *(single_sigma_array+next_x) = z; next_x++; if (y == EPSILON && z == EPSILON) { epsilon_symbol = x; } x++; } } num_symbols = x; }
struct fsm *fsm_coaccessible(struct fsm *net) { struct invtable *inverses, *temp_i, *temp_i_prev, *current_ptr; int i, j, s, t, *coacc, current_state, markcount, *mapping, terminate, new_linecount, new_arccount, *added, old_statecount; struct fsm_state *fsm; fsm = net->states; new_arccount = 0; /* printf("statecount %i\n",net->statecount); */ old_statecount = net->statecount; inverses = xxcalloc(net->statecount, sizeof(struct invtable)); coacc = xxmalloc(sizeof(int)*(net->statecount)); mapping = xxmalloc(sizeof(int)*(net->statecount)); added = xxmalloc(sizeof(int)*(net->statecount)); for (i=0; i < (net->statecount); i++) { (inverses+i)->state = -1; *(coacc+i) = 0; *(added+i) = 0; } for (i=0; (fsm+i)->state_no != -1; i++) { s = (fsm+i)->state_no; t = (fsm+i)->target; if (t != -1 && s != t) { if (((inverses+t)->state) == -1) { (inverses+t)->state = s; } else { temp_i = xxmalloc(sizeof(struct invtable)); temp_i->next = (inverses+t)->next; (inverses+t)->next = temp_i; temp_i->state = s; } } } /* Push & mark finals */ markcount = 0; for (i=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->final_state && (!*(coacc+((fsm+i)->state_no)))) { int_stack_push((fsm+i)->state_no); *(coacc+(fsm+i)->state_no) = 1; markcount++; } } terminate = 0; while(!int_stack_isempty()) { current_state = int_stack_pop(); current_ptr = inverses+current_state; while(current_ptr != NULL && current_ptr->state != -1) { if (!*(coacc+(current_ptr->state))) { *(coacc+(current_ptr->state)) = 1; int_stack_push(current_ptr->state); markcount++; } current_ptr = current_ptr->next; } if (markcount >= net->statecount) { /* printf("Already coacc\n"); */ terminate = 1; int_stack_clear(); break; } } if (terminate == 0) { *mapping = 0; /* state 0 always exists */ new_linecount = 0; for (i=1,j=0; i < (net->statecount);i++) { if (*(coacc+i) == 1) { j++; *(mapping+i) = j; } } for (i=0,j=0; (fsm+i)->state_no != -1; i++) { if (i > 0 && (fsm+i)->state_no != (fsm+i-1)->state_no && (fsm+i-1)->final_state && !*(added+((fsm+i-1)->state_no))) { add_fsm_arc(fsm, j++, *(mapping+((fsm+i-1)->state_no)), -1, -1, -1, 1, (fsm+i-1)->start_state); new_linecount++; *(added+((fsm+i-1)->state_no)) = 1; /* printf("addf ad %i\n",i); */ } if (*(coacc+((fsm+i)->state_no)) && (((fsm+i)->target == -1) || *(coacc+((fsm+i)->target)))) { (fsm+j)->state_no = *(mapping+((fsm+i)->state_no)); if ((fsm+i)->target == -1) { (fsm+j)->target = -1; } else { (fsm+j)->target = *(mapping+((fsm+i)->target)); } (fsm+j)->final_state = (fsm+i)->final_state; (fsm+j)->start_state = (fsm+i)->start_state; (fsm+j)->in = (fsm+i)->in; (fsm+j)->out = (fsm+i)->out; j++; new_linecount++; *(added+(fsm+i)->state_no) = 1; if ((fsm+i)->target != -1) { new_arccount++; } } } if ((i > 1) && ((fsm+i-1)->final_state) && *(added+((fsm+i-1)->state_no)) == 0) { /* printf("addf\n"); */ add_fsm_arc(fsm, j++, *(mapping+((fsm+i-1)->state_no)), -1, -1, -1, 1, (fsm+i-1)->start_state); new_linecount++; } if (new_linecount == 0) { add_fsm_arc(fsm, j++, 0, -1, -1, -1, -1, -1); } add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1); if (markcount == 0) { /* We're dealing with the empty language */ xxfree(fsm); net->states = fsm_empty(); net->sigma = sigma_create(); } net->linecount = new_linecount; net->arccount = new_arccount; net->statecount = markcount; } /* printf("Markccount %i \n",markcount); */ for (i = 0; i < old_statecount ; i++) { for (temp_i = inverses+i; temp_i != NULL ; ) { temp_i_prev = temp_i; temp_i = temp_i->next; if (temp_i_prev != inverses+i) xxfree(temp_i_prev); } } xxfree(inverses); xxfree(coacc); xxfree(added); xxfree(mapping); net->is_pruned = YES; return(net); }
void apply_index(struct apply_handle *h, int inout, int densitycutoff, int mem_limit, int flags_only) { struct fsm_state *fsm; unsigned int cnt = 0; int i, j, maxtrans, numtrans, laststate, sym; fsm = h->gstates; struct apply_state_index **indexptr, *iptr, *tempiptr; struct pre_index { int state_no; struct pre_index *next; } *pre_index, *tp, *tpp; if (flags_only && !h->has_flags) { return; } /* get numtrans */ for (i=0, laststate = 0, maxtrans = 0, numtrans = 0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->state_no != laststate) { maxtrans = numtrans > maxtrans ? numtrans : maxtrans; numtrans = 0; } if ((fsm+i)->target != -1) { numtrans++; } laststate = (fsm+i)->state_no; } pre_index = xxcalloc(maxtrans+1, sizeof(struct pre_index)); for (i = 0; i <= maxtrans; i++) { (pre_index+i)->state_no = -1; } /* We create an array of states, indexed by how many transitions they have */ /* so that later, we can traverse them in order densest first, in case we */ /* only want to index to some predefined maximum memory usage. */ for (i = 0, laststate = 0, maxtrans = 0, numtrans = 0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->state_no != laststate) { if ((pre_index+numtrans)->state_no == -1) { (pre_index+numtrans)->state_no = laststate; } else { tp = xxcalloc(1, sizeof(struct pre_index)); tp->state_no = laststate; tp->next = (pre_index+numtrans)->next; (pre_index+numtrans)->next = tp; } maxtrans = numtrans > maxtrans ? numtrans : maxtrans; numtrans = 0; } if ((fsm+i)->target != -1) { numtrans++; } laststate = (fsm+i)->state_no; } indexptr = NULL; cnt += round_up_to_power_of_two(h->last_net->statecount*sizeof(struct apply_state_index *)); if (cnt > mem_limit) { cnt -= round_up_to_power_of_two(h->last_net->statecount*sizeof(struct apply_state_index *)); goto memlimitnoindex; } indexptr = xxcalloc(h->last_net->statecount, sizeof(struct apply_state_index *)); if (h->has_flags && flags_only) { /* Mark states that have flags */ if (!(h->flagstates)) { apply_mark_flagstates(h); } } for (i = maxtrans; i >= 0; i--) { for (tp = pre_index+i; tp != NULL; tp = tp->next) { if (tp->state_no >= 0) { if (i < densitycutoff) { if (!(h->has_flags && flags_only && BITTEST(h->flagstates, tp->state_no))) { continue; } } cnt += round_up_to_power_of_two(h->sigma_size*sizeof(struct apply_state_index)); if (cnt > mem_limit) { cnt -= round_up_to_power_of_two(h->sigma_size*sizeof(struct apply_state_index)); goto memlimit; } *(indexptr + tp->state_no) = xxmalloc(h->sigma_size*sizeof(struct apply_state_index)); /* We make the tail of all index linked lists point to the index */ /* for EPSILON, so that we automatically when EPSILON transitions */ /* also when traversing an index. */ for (j = 0; j < h->sigma_size; j++) { (*(indexptr + tp->state_no) + j)->fsmptr = -1; if (j == EPSILON) (*(indexptr + tp->state_no) + j)->next = NULL; else (*(indexptr + tp->state_no) + j)->next = (*(indexptr + tp->state_no)); /* all tails point to epsilon */ } } } } memlimit: for (i=0; (fsm+i)->state_no != -1; i++) { iptr = *(indexptr + (fsm+i)->state_no); if (iptr == NULL || (fsm+i)->target == -1) { continue; } sym = inout == APPLY_INDEX_INPUT ? (fsm+i)->in : (fsm+i)->out; if (h->has_flags && (h->flag_lookup+sym)->type) { sym = EPSILON; } if (sym == UNKNOWN) { /* We make the index of UNKNOWN point to IDENTITY */ sym = IDENTITY; /* since these are really the same symbol */ } if ((iptr+sym)->fsmptr == -1) { (iptr+sym)->fsmptr = i; } else { cnt += round_up_to_power_of_two(sizeof(struct apply_state_index)); tempiptr = xxcalloc(1, sizeof(struct apply_state_index)); tempiptr->next = (iptr+sym)->next; tempiptr->fsmptr = i; (iptr+sym)->next = tempiptr; } } /* Free preindex */ memlimitnoindex: for (i = maxtrans; i >= 0; i--) { for (tp = (pre_index+i)->next; tp != NULL; tp = tpp) { tpp = tp->next; xxfree(tp); } } xxfree(pre_index); if (inout == APPLY_INDEX_INPUT) { h->index_in = indexptr; } else { h->index_out = indexptr; } }
void apply_create_sigarray(struct apply_handle *h, struct fsm *net) { struct sigma *sig; int i, maxsigma; maxsigma = sigma_max(net->sigma); h->sigma_size = maxsigma+1; // Default size created at init, resized later if necessary h->sigmatch_array = xxcalloc(1024,sizeof(struct sigmatch_array)); h->sigmatch_array_size = 1024; h->sigs = xxmalloc(sizeof(struct sigs)*(maxsigma+1)); h->has_flags = 0; h->flag_list = NULL; /* Malloc first array of trie and store trie ptrs to be able to free later */ /* when apply_clear() is called. */ h->sigma_trie = xxcalloc(256,sizeof(struct sigma_trie)); h->sigma_trie_arrays = xxmalloc(sizeof(struct sigma_trie_arrays)); h->sigma_trie_arrays->arr = h->sigma_trie; h->sigma_trie_arrays->next = NULL; for (i=0;i<256;i++) (h->sigma_trie+i)->next = NULL; for (sig = h->gsigma; sig != NULL && sig->number != -1; sig = sig->next) { if (flag_check(sig->symbol)) { h->has_flags = 1; apply_add_flag(h, flag_get_name(sig->symbol)); } (h->sigs+(sig->number))->symbol = sig->symbol; (h->sigs+(sig->number))->length = strlen(sig->symbol); /* Add sigma entry to trie */ if (sig->number > IDENTITY) { apply_add_sigma_trie(h, sig->number, sig->symbol, (h->sigs+(sig->number))->length); } } if (maxsigma >= IDENTITY) { (h->sigs+EPSILON)->symbol = "0"; (h->sigs+EPSILON)->length = 1; (h->sigs+UNKNOWN)->symbol = "?"; (h->sigs+UNKNOWN)->length = 1; (h->sigs+IDENTITY)->symbol = "@"; (h->sigs+IDENTITY)->length = 1; } if (h->has_flags) { h->flag_lookup = xxmalloc(sizeof(struct flag_lookup)*(maxsigma+1)); for (i=0; i <= maxsigma; i++) { (h->flag_lookup+i)->type = 0; (h->flag_lookup+i)->name = NULL; (h->flag_lookup+i)->value = NULL; } for (sig = h->gsigma; sig != NULL ; sig = sig->next) { if (flag_check(sig->symbol)) { (h->flag_lookup+sig->number)->type = flag_get_type(sig->symbol); (h->flag_lookup+sig->number)->name = flag_get_name(sig->symbol); (h->flag_lookup+sig->number)->value = flag_get_value(sig->symbol); } } apply_mark_flagstates(h); } }
struct fsm *flag_twosided(struct fsm *net) { struct fsm_state *fsm; struct sigma *sigma; int i, j, tail, *isflag, maxsigma, maxstate, newarcs, change; /* Enforces twosided flag diacritics */ /* Mark flag symbols */ maxsigma = sigma_max(net->sigma); isflag = xxcalloc(maxsigma+1, sizeof(int)); fsm = net->states; for (sigma = net->sigma ; sigma != NULL; sigma = sigma->next) { if (flag_check(sigma->symbol)) { *(isflag+sigma->number) = 1; } else { *(isflag+sigma->number) = 0; } } maxstate = 0; change = 0; for (i = 0, newarcs = 0; (fsm+i)->state_no != -1 ; i++) { maxstate = (fsm+i)->state_no > maxstate ? (fsm+i)->state_no : maxstate; if ((fsm+i)->target == -1) continue; if (*(isflag+(fsm+i)->in) && (fsm+i)->out == EPSILON) { change = 1; (fsm+i)->out = (fsm+i)->in; } else if (*(isflag+(fsm+i)->out) && (fsm+i)->in == EPSILON) { change = 1; (fsm+i)->in = (fsm+i)->out; } if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) { newarcs++; } } if (newarcs == 0) { if (change == 1) { net->is_deterministic = UNK; net->is_minimized = UNK; net->is_pruned = UNK; return fsm_topsort(fsm_minimize(net)); } return net; } net->states = xxrealloc(net->states, sizeof(struct fsm)*(i+newarcs)); fsm = net->states; tail = j = i; maxstate++; for (i = 0; i < tail; i++) { if ((fsm+i)->target == -1) continue; if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) { if (*(isflag+(fsm+i)->in) && !*(isflag+(fsm+i)->out)) { j = add_fsm_arc(fsm, j, maxstate, EPSILON, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = (fsm+i)->in; (fsm+i)->target = maxstate; maxstate++; } else if (*(isflag+(fsm+i)->out) && !*(isflag+(fsm+i)->in)) { j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = EPSILON; (fsm+i)->target = maxstate; maxstate++; } else if (*(isflag+(fsm+i)->in) && *(isflag+(fsm+i)->out)) { j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = (fsm+i)->in; (fsm+i)->target = maxstate; maxstate++; } } } /* Add sentinel */ add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1); net->is_deterministic = UNK; net->is_minimized = UNK; return fsm_topsort(fsm_minimize(net)); }
int write_prolog (struct fsm *net, char *filename) { struct fsm_state *stateptr; int i, *finals, *used_symbols, maxsigma; FILE *out; char *outstring, *instring, identifier[100]; if (filename == NULL) { out = stdout; } else { if ((out = fopen(filename, "w")) == NULL) { printf("Error writing to file '%s'. Using stdout.\n", filename); out = stdout; } printf("Writing prolog to file '%s'.\n", filename); } fsm_count(net); maxsigma = sigma_max(net->sigma); used_symbols = xxcalloc(maxsigma+1,sizeof(int)); finals = xxmalloc(sizeof(int)*(net->statecount)); stateptr = net->states; identifier[0] = '\0'; strcpy(identifier, net->name); /* Print identifier */ fprintf(out, "%s%s%s", "network(",identifier,").\n"); for (i=0; (stateptr+i)->state_no != -1; i++) { if ((stateptr+i)->final_state == 1) { *(finals+((stateptr+i)->state_no)) = 1; } else { *(finals+((stateptr+i)->state_no)) = 0; } if ((stateptr+i)->in != -1) { *(used_symbols+((stateptr+i)->in)) = 1; } if ((stateptr+i)->out != -1) { *(used_symbols+((stateptr+i)->out)) = 1; } } for (i = 3; i <= maxsigma; i++) { if (*(used_symbols+i) == 0) { instring = sigma_string(i, net->sigma); if (strcmp(instring,"0") == 0) { instring = "%0"; } fprintf(out, "symbol(%s, \"", identifier); escape_print(out, instring); fprintf(out, "\").\n"); } } for (; stateptr->state_no != -1; stateptr++) { if (stateptr->target == -1) continue; fprintf(out, "arc(%s, %i, %i, ", identifier, stateptr->state_no, stateptr->target); if (stateptr->in == 0) instring = "0"; else if (stateptr->in == 1) instring = "?"; else if (stateptr->in == 2) instring = "?"; else instring = sigma_string(stateptr->in, net->sigma); if (stateptr->out == 0) outstring = "0"; else if (stateptr->out == 1) outstring = "?"; else if (stateptr->out == 2) outstring = "?"; else outstring = sigma_string(stateptr->out, net->sigma); if (strcmp(instring,"0") == 0 && stateptr->in != 0) instring = "%0"; if (strcmp(outstring,"0") == 0 && stateptr->out != 0) outstring = "%0"; if (strcmp(instring,"?") == 0 && stateptr->in > 2) instring = "%?"; if (strcmp(outstring,"?") == 0 && stateptr->in > 2) outstring = "%?"; /* Escape quotes */ if (net->arity == 2 && stateptr->in == IDENTITY && stateptr->out == IDENTITY) { fprintf(out, "\"?\").\n"); } else if (net->arity == 2 && stateptr->in == stateptr->out && stateptr->in != UNKNOWN) { fprintf(out, "\""); escape_print(out, instring); fprintf(out, "\").\n"); } else if (net->arity == 2) { fprintf(out, "\""); escape_print(out, instring); fprintf(out, "\":\""); escape_print(out, outstring); fprintf(out, "\").\n"); } else if (net->arity == 1) { fprintf(out, "\""); escape_print(out, instring); fprintf(out, "\").\n"); } } for (i = 0; i < net->statecount; i++) { if (*(finals+i)) { fprintf(out, "final(%s, %i).\n", identifier, i); } } if (filename != NULL) { fclose(out); } xxfree(finals); xxfree(used_symbols); return 1; }
struct sh_handle *sh_init() { struct sh_handle *sh; sh = xxmalloc(sizeof(struct sh_handle)); sh->hash = xxcalloc(STRING_HASH_SIZE, sizeof(struct sh_hashtable)); return(sh); }
struct fsm_read_handle *fsm_read_init(struct fsm *net) { struct fsm_read_handle *handle; struct fsm_state *fsm, **states_head; int i, j, k, num_states, num_initials, num_finals, sno, *finals_head, *initials_head, laststate; unsigned char *lookuptable; if (net == NULL) {return (NULL);} num_states = net->statecount; lookuptable = xxcalloc(num_states, sizeof(unsigned char)); num_initials = num_finals = 0; handle = xxcalloc(1,sizeof(struct fsm_read_handle)); states_head = xxcalloc(num_states+1,sizeof(struct fsm **)); laststate = -1; for (i=0, fsm=net->states; (fsm+i)->state_no != -1; i++) { sno = (fsm+i)->state_no; if ((fsm+i)->start_state) { if (!(*(lookuptable+sno) & 1)) { *(lookuptable+sno) |= 1; num_initials++; } } if ((fsm+i)->final_state) { if (!(*(lookuptable+sno) & 2)) { *(lookuptable+sno) |= 2; num_finals++; } } if ((fsm+i)->in == UNKNOWN || (fsm+i)->out == UNKNOWN || (fsm+i)->in == IDENTITY || (fsm+i)->out == IDENTITY) { handle->has_unknowns = 1; } if ((fsm+i)->state_no != laststate) { *(states_head+(fsm+i)->state_no) = fsm+i; } laststate = (fsm+i)->state_no; } finals_head = xxcalloc(num_finals+1,sizeof(int)); initials_head = xxcalloc(num_initials+1,sizeof(int)); for (i=j=k=0; i < num_states; i++) { if (*(lookuptable+i) & 1) { *(initials_head+j) = i; j++; } if (*(lookuptable+i) & 2) { *(finals_head+k) = i; k++; } } *(initials_head+j) = -1; *(finals_head+k) = -1; handle->finals_head = finals_head; handle->initials_head = initials_head; handle->states_head = states_head; handle->fsm_sigma_list = sigma_to_list(net->sigma); handle->sigma_list_size = sigma_max(net->sigma)+1; handle->arcs_head = fsm; handle->lookuptable = lookuptable; handle->net = net; return(handle); }