Impressum fsaipmin.c
Interaktion und PortierbarkeitC
/* file fsaipmin.c - 12. 12. 94. * This file contains the routines fsa_ip_minimize and fsa_ip_labeled_minimize. * They are based on the minimization functions in fsa.c, but instead of * holding the whole of the transition table of the fsa to be minimized in * store, they read it in from file with each iteration. * The reading part is as in "compressed_transitions_read".
*/
/* Minimize the fsa *fsaptr, of which transitions are stored externally */ int fsa_ip_minimize(fsa *fsaptr)
{ int *block_numa, *block_numb, *block_swap, i, j, k, l, len, *ptr, *ptr2,
*ptr2e, *ht_ptr, ne, ns_orig, *fsarow, **table, ns_final, ns_new,
num_iterations;
hash_table ht;
boolean fixed;
FILE *rfile;
if (fsaptr->table->table_type == SPARSE && fsaptr->table->denserows > 0) {
fprintf(stderr, "Sorry: fsa_minimize unavailable for sparse storage with " "dense rows.\n"); return -1;
}
if (kbm_print_level >= 3)
printf(" #Calling fsa_ip_minimize.\n"); if (!fsaptr->flags[DFA]) {
fprintf(stderr, "Error: fsa_minimize only applies to DFA's.\n"); return -1;
} if (!fsaptr->flags[ACCESSIBLE]) {
fprintf(stderr, "Error: fsa in fsa_labeled_minimize must be accessible.\n"); return -1;
}
ne = fsaptr->alphabet->size;
ns_orig = fsaptr->states->size; if (ns_orig == 0) {
fsaptr->flags[TRIM] = TRUE;
fsaptr->flags[MINIMIZED] = TRUE; return 0;
}
/* First throw away any existing structure on the state-set. */
srec_clear(fsaptr->states);
fsaptr->states->type = SIMPLE;
tmalloc(block_numa, int, ns_orig + 1);
tmalloc(block_numb, int, ns_orig + 1); /* Start with block_numa equal to the accept/reject division * Remember that state/block number 0 is always failure with no hope.
*/ if (fsaptr->num_accepting == ns_orig) {
block_numa[0] = 0; for (i = 1; i <= ns_orig; i++)
block_numa[i] = 1;
} else { for (i = 0; i <= ns_orig; i++)
block_numa[i] = 0; for (i = 1; i <= fsaptr->num_accepting; i++)
block_numa[fsaptr->accepting[i]] = 1;
}
fixed = fsaptr->table->table_type == DENSE;
if (fixed)
tmalloc(fsarow, int, ne + 1) else tmalloc(fsarow, int, 2 * ne)
ns_new = 1;
num_iterations = 0; /* The main refinement loop follows. */ do { if ((rfile = fopen(fsaptr->table->filename, "r")) == 0) {
fprintf(stderr, "#Cannot open file %s.\n", fsaptr->table->filename); return -1;
}
num_iterations++;
ns_final = ns_new; /* Turn off excessive printing at this point */
j = kbm_print_level;
kbm_print_level = 1;
hash_init(&ht, fixed, ne + 1, 0, 0);
kbm_print_level = j; if (kbm_print_level >= 3)
printf(" #Iterating - number of state categories = %d.\n", ns_new);
block_numb[0] = 0; for (i = 1; i <= ns_orig; i++) { /* Insert the encoded form of the transitions from state i into the * hashtable preceded by the current block number of i.
*/
ptr = ht.current_ptr;
*ptr = block_numa[i]; if (fixed) {
fread((void *)(fsarow + 1), sizeof(int), (size_t)ne, rfile); for (j = 1; j <= ne; j++)
ptr[j] = block_numa[fsarow[j]];
l = ne + 1;
} else {
fread((void *)&len, sizeof(int), (size_t)1, rfile); if (len > 0)
fread((void *)fsarow, sizeof(int), (size_t)len, rfile);
l = 0; for (j = 1; j < len; j += 2) {
k = block_numa[fsarow[j]]; if (k > 0) {
ptr[++l] = fsarow[j - 1];
ptr[++l] = k;
}
} if (l > 0 || *ptr > 0)
l++; /* For technical reasons, we want the zero record to be empty */
}
block_numb[i] = hash_locate(&ht, l);
}
fclose(rfile);
ns_new = ht.num_recs;
block_swap = block_numa;
block_numa = block_numb;
block_numb = block_swap; if (ns_new > ns_final)
hash_clear(&ht);
} while (ns_new > ns_final);
tfree(fsarow);
/* At this stage, either ns_final = ns_new, or the fsa has empty accepted * language, ns_new=0 and ns_final=1.
*/
if (ns_new == 0) { /* This is the awkward case of no states - always causes problems! */
fsaptr->states->size = 0;
fsaptr->num_initial = 0;
tfree(fsaptr->initial);
fsaptr->num_accepting = 0;
tfree(fsaptr->accepting);
unlink(fsaptr->table->filename);
tfree(fsaptr->table->filename);
} else { /* Re-define the fsa fields */
fsaptr->states->size = ns_final;
if (fsaptr->num_accepting == ns_orig) {
fsaptr->num_accepting = ns_final; if (ns_final == 1) {
tmalloc(fsaptr->accepting, int, 2);
fsaptr->accepting[1] = 1;
}
} else {
tmalloc(fsaptr->is_accepting, boolean, ns_final + 1); for (i = 1; i <= ns_final; i++)
fsaptr->is_accepting[i] = FALSE; for (i = 1; i <= fsaptr->num_accepting; i++)
fsaptr->is_accepting[block_numa[fsaptr->accepting[i]]] = TRUE;
fsaptr->num_accepting = 0; for (i = 1; i <= ns_final; i++) if (fsaptr->is_accepting[i])
fsaptr->num_accepting++;
tfree(fsaptr->accepting);
tmalloc(fsaptr->accepting, int, fsaptr->num_accepting + 1);
j = 0; for (i = 1; i <= ns_final; i++) if (fsaptr->is_accepting[i])
fsaptr->accepting[++j] = i;
tfree(fsaptr->is_accepting);
}
/* Finally copy the transition table data from the hash-table back to the
* fsa */
unlink(fsaptr->table->filename);
tfree(fsaptr->table->filename); if (fixed) {
fsa_table_init(fsaptr->table, ns_final, ne);
table = fsaptr->table->table_data_ptr; for (i = 1; i <= ns_final; i++) {
ht_ptr = hash_rec(&ht, i); for (j = 1; j <= ne; j++)
table[j][i] = ht_ptr[j];
}
} else {
tmalloc(fsaptr->table->table_data_ptr, int *, ns_final + 2);
tmalloc(fsaptr->table->table_data_ptr[0], int, ht.tot_space - ns_final);
table = fsaptr->table->table_data_ptr;
table[1] = ptr = table[0]; for (i = 1; i <= ns_final; i++) {
ht_ptr = hash_rec(&ht, i);
ptr2 = ht_ptr + 1;
ptr2e = ht_ptr + hash_rec_len(&ht, i) - 1; while (ptr2 <= ptr2e)
*(ptr++) = *(ptr2++);
table[i + 1] = ptr;
}
}
}
hash_clear(&ht);
tfree(block_numa);
tfree(block_numb); if (kbm_print_level >= 3)
printf(" #Number of iterations = %d.\n", num_iterations); return 0;
}
/* This is the minimization function for fsa's which misght have more than * two categories of states. * We use the labeled set-record type to identify the categories, so *fsaptr * must have state-set of labeled type. * Minimize the fsa *fsaptr, of which transitions are stored externally.
*/ int fsa_ip_labeled_minimize(fsa *fsaptr)
{ int *block_numa, *block_numb, *block_swap, i, j, k, l, len, *ptr, *ptr2,
*ptr2e, *ht_ptr, ne, ns_orig, *fsarow, **table, ns_final, ns_new,
num_iterations;
hash_table ht;
boolean fixed, *occurs;
FILE *rfile;
if (fsaptr->table->table_type == SPARSE && fsaptr->table->denserows > 0) {
fprintf(stderr, "Sorry: fsa_minimize unavailable for sparse storage with " "dense rows.\n"); return -1;
} if (kbm_print_level >= 3)
printf(" #Calling fsa_ip_labeled_minimize.\n"); if (!fsaptr->flags[DFA]) {
fprintf(stderr, "Error: fsa_labeled_minimize only applies to DFA's.\n"); return -1;
} if (!fsaptr->flags[ACCESSIBLE]) {
fprintf(stderr, "Error: fsa in fsa_labeled_minimize must be accessible.\n"); return -1;
}
if (fsaptr->states->type != LABELED) {
fprintf(
stderr, "Error: in fsa_labeled_minimize state=set must have type labeled.\n"); return -1;
}
ne = fsaptr->alphabet->size;
ns_orig = fsaptr->states->size; if (ns_orig == 0) return 0;
/* Start with block_numa equal to the subdivision defined by the labeling. */
tmalloc(occurs, boolean, fsaptr->states->labels->size + 1); for (i = 1; i <= fsaptr->states->labels->size; i++)
occurs[i] = FALSE;
tmalloc(block_numa, int, ns_orig + 1);
tmalloc(block_numb, int, ns_orig + 1);
ns_new = 0;
block_numa[0] = 0; /* The zero state is always regarded as having label 0 */ for (i = 1; i <= ns_orig; i++) {
j = fsaptr->states->setToLabels[i]; if (j > 0 && !occurs[j]) {
occurs[j] = TRUE;
ns_new++;
}
block_numa[i] = j;
}
tfree(occurs); if (ns_new == 0)
ns_new = 1; /* a patch for the case when there are no labels */
fixed = fsaptr->table->table_type == DENSE;
if (fixed)
tmalloc(fsarow, int, ne + 1) else tmalloc(fsarow, int, 2 * ne)
num_iterations = 0; /* The main refinement loop follows. */ do { if ((rfile = fopen(fsaptr->table->filename, "r")) == 0) {
fprintf(stderr, "#Cannot open file %s.\n", fsaptr->table->filename); return -1;
}
num_iterations++;
ns_final = ns_new; /* Turn off excessive printing at this point */
j = kbm_print_level;
kbm_print_level = 1;
hash_init(&ht, fixed, ne + 1, 0, 0);
kbm_print_level = j; if (kbm_print_level >= 3)
printf(" #Iterating - number of state categories = %d.\n", ns_new);
block_numb[0] = 0; for (i = 1; i <= ns_orig; i++) { /* Insert the encoded form of the transitions from state i into the * hashtable preceded by the current block number of i. First read in the * transitions for this row from the file.
*/
ptr = ht.current_ptr;
*ptr = block_numa[i]; if (fixed) {
fread((void *)(fsarow + 1), sizeof(int), (size_t)ne, rfile); for (j = 1; j <= ne; j++)
ptr[j] = block_numa[fsarow[j]];
l = ne + 1;
} else {
fread((void *)&len, sizeof(int), (size_t)1, rfile); if (len > 0)
fread((void *)fsarow, sizeof(int), (size_t)len, rfile);
l = 0; for (j = 1; j < len; j += 2) {
k = block_numa[fsarow[j]]; if (k > 0) {
ptr[++l] = fsarow[j - 1];
ptr[++l] = k;
}
} if (l > 0 || *ptr > 0)
l++; /* For technical reasons, we want the zero record to be empty */
}
block_numb[i] = hash_locate(&ht, l);
}
fclose(rfile);
ns_new = ht.num_recs;
block_swap = block_numa;
block_numa = block_numb;
block_numb = block_swap; if (ns_new > ns_final)
hash_clear(&ht);
} while (ns_new > ns_final);
tfree(fsarow);
/* At this stage, either ns_final = ns_new, or the fsa has empty accepted * language, ns_new=0 and ns_final=1.
*/
fsaptr->flags[ACCESSIBLE] = TRUE;
if (ns_new == 0) { /* This is the awkward case of no states - always causes problems! */
fsaptr->states->size = 0;
fsaptr->num_initial = 0;
tfree(fsaptr->initial);
fsaptr->num_accepting = 0;
tfree(fsaptr->accepting);
unlink(fsaptr->table->filename);
tfree(fsaptr->table->filename);
} else { /* Re-define the fsa fields */
fsaptr->states->size = ns_final;
for (i = 1; i <= ns_orig; i++)
block_numb[block_numa[i]] = fsaptr->states->setToLabels[i]; for (i = 1; i <= ns_final; i++)
fsaptr->states->setToLabels[i] = block_numb[i];
if (fsaptr->num_accepting == ns_orig) {
fsaptr->num_accepting = ns_final; if (ns_final == 1) {
tmalloc(fsaptr->accepting, int, 2);
fsaptr->accepting[1] = 1;
}
} else {
tmalloc(fsaptr->is_accepting, boolean, ns_final + 1); for (i = 1; i <= ns_final; i++)
fsaptr->is_accepting[i] = FALSE; for (i = 1; i <= fsaptr->num_accepting; i++)
fsaptr->is_accepting[block_numa[fsaptr->accepting[i]]] = TRUE;
fsaptr->num_accepting = 0; for (i = 1; i <= ns_final; i++) if (fsaptr->is_accepting[i])
fsaptr->num_accepting++;
tfree(fsaptr->accepting);
tmalloc(fsaptr->accepting, int, fsaptr->num_accepting + 1);
j = 0; for (i = 1; i <= ns_final; i++) if (fsaptr->is_accepting[i])
fsaptr->accepting[++j] = i;
tfree(fsaptr->is_accepting);
}
/* Finally copy the transition table data from the hash-table back to the
* fsa */
unlink(fsaptr->table->filename);
tfree(fsaptr->table->filename); if (fixed) {
fsa_table_init(fsaptr->table, ns_final, ne);
table = fsaptr->table->table_data_ptr; for (i = 1; i <= ns_final; i++) {
ht_ptr = hash_rec(&ht, i); for (j = 1; j <= ne; j++)
table[j][i] = ht_ptr[j];
}
} else {
tmalloc(fsaptr->table->table_data_ptr, int *, ns_final + 2);
tmalloc(fsaptr->table->table_data_ptr[0], int, ht.tot_space - ns_final);
table = fsaptr->table->table_data_ptr;
table[1] = ptr = table[0]; for (i = 1; i <= ns_final; i++) {
ht_ptr = hash_rec(&ht, i);
ptr2 = ht_ptr + 1;
ptr2e = ht_ptr + hash_rec_len(&ht, i) - 1; while (ptr2 <= ptr2e)
*(ptr++) = *(ptr2++);
table[i + 1] = ptr;
}
}
}
hash_clear(&ht);
tfree(block_numa);
tfree(block_numb); if (kbm_print_level >= 3)
printf(" #Number of iterations = %d.\n", num_iterations); return 0;
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.