/* file fsarevmid.c 18. 4. 96. * * 16.7.98. added fsa_miexists1, fsa_miexists2 to existentialise over * the two variables of a 2-variable midfa machine. * * 11.9.97. wrote a different version of fsa_reverse * called fsa_mireverse which * returns a labeled MIDFA with the * singleton accept states of the input fsa as initial states. * * This file contains the routine fsa_reverse. * It takes a deterministic fsa F as input. * fsa_reverse returns an fsa that accepts a word a_1a_2...a_n if and only * if F accepts a_n...a_2a_1.
*/
/* *fsaptr must be a deterministic fsa. * The returned *fsa accepts words accepted by *fsaptr but read * backwards. * If subsets is true, then the returned fsa will have state-set of type * "list of integers", where the list represents the subset of the state-set * of *fsaptr that corresponds to the state of the returned fsa.
*/
fsa *fsa_reverse(fsa *fsaptr, storage_type op_table_type, boolean destroy,
boolean subsets, char *tempfilename)
{ if (kbm_print_level >= 3)
printf(" #Calling fsa_reverse.\n"); if (fsaptr->states->size < MAXUSHORT) return fsa_reverse_short(fsaptr, op_table_type, destroy, subsets,
tempfilename); else return fsa_reverse_int(fsaptr, op_table_type, destroy, subsets,
tempfilename);
}
static fsa *fsa_reverse_short(fsa *fsaptr, storage_type op_table_type,
boolean destroy, boolean subsets, char *tempfilename)
{ int **table, ne, nsi, ns, is, dr, *fsarow, nt, cstate, cs, csi, im, i, g, n,
len = 0, ct; unsignedshort *ht_ptr, *ht_chptr, *ht_ptrb, *ht_ptre, *cs_ptr, *cs_ptre,
*ptr;
boolean dense_ip, dense_op;
short_hash_table ht;
fsa *reverse;
FILE *tempfile;
if (kbm_print_level >= 3)
printf(" #Calling fsa_reverse_short.\n"); if (!fsaptr->flags[DFA]) {
fprintf(stderr, "Error: fsa_reverse only applies to DFA's.\n"); return 0;
}
/* The states of *reverse will be subsets of the state-set of *fsaptr. * The initial state consists of all accept states of *fsaptr.
*/
short_hash_init(&ht, FALSE, 0, 0, 0);
ht_ptrb = ht.current_ptr;
ht_ptre = ht_ptrb - 1;
fsa_set_is_accepting(fsaptr); for (i = 1; i <= nsi; i++) if (fsaptr->is_accepting[i])
*(++ht_ptre) = i;
tfree(fsaptr->is_accepting);
im = short_hash_locate(&ht, ht_ptre - ht_ptrb + 1); if (im != 1) {
fprintf(stderr, "Hash-initialisation problem in fsa_reverse.\n"); return 0;
} if ((tempfile = fopen(tempfilename, "w")) == 0) {
fprintf(stderr, "Error: cannot open file %s\n", tempfilename); return 0;
} if (dense_op)
tmalloc(fsarow, int, ne) else tmalloc(fsarow, int, 2 * ne + 1)
cstate = 0; if (dense_op)
len = ne; /* The length of the fsarow output. */
nt = 0; /* Number of transitions in reverse */
while (++cstate <= ht.num_recs) { if (kbm_print_level >= 3) { if ((cstate <= 1000 && cstate % 100 == 0) ||
(cstate <= 10000 && cstate % 1000 == 0) ||
(cstate <= 100000 && cstate % 5000 == 0) || cstate % 50000 == 0)
printf(" #cstate = %d; number of states = %d.\n", cstate,
ht.num_recs);
}
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = short_hash_rec(&ht, cstate) + short_hash_rec_len(&ht, cstate) - 1; if (!dense_op)
len = 0;
for (g = 1; g <= ne; g++) { /* Calculate action of label g on state cstate - to get the image, we * have to look for all inverse images under g of all states cs in the * subset cstate. The subset formed will be the image.
*/
ht_ptrb = ht.current_ptr;
ht_ptre = ht_ptrb - 1;
ptr = cs_ptr - 1; while (++ptr <= cs_ptre) {
cs = *ptr; for (csi = 1; csi <= nsi; csi++) if (target(dense_ip, table, g, csi, dr) == cs) { /* csi has to be added to the subset of states that forms the image * of cstate under g - we want to keep this subset in ascending * order.
*/ if (ht_ptrb > ht_ptre || csi > *ht_ptre) {
*(++ht_ptre) = csi;
} else {
ht_chptr = ht_ptrb; while (*ht_chptr < csi)
ht_chptr++; if (csi < *ht_chptr) {
ht_ptr = ++ht_ptre; while (ht_ptr > ht_chptr) {
*ht_ptr = *(ht_ptr - 1);
ht_ptr--;
}
*ht_ptr = csi;
}
}
}
}
im = short_hash_locate(&ht, ht_ptre - ht_ptrb + 1); if (dense_op)
fsarow[g - 1] = im; elseif (im > 0) {
fsarow[++len] = g;
fsarow[++len] = im;
} if (im > 0)
nt++;
} if (!dense_op)
fsarow[0] = len++;
fwrite((void *)fsarow, sizeof(int), (size_t)len, tempfile);
}
fclose(tempfile);
/* Locate the accept states. These are those that contain the initial * state of *fsaptr. * Also, if subsets is true, record the states in the intlist field * of reverse->states.
*/
is = fsaptr->initial[1];
tmalloc(reverse->is_accepting, boolean, ns + 1); for (i = 1; i <= ns; i++)
reverse->is_accepting[i] = FALSE; if (subsets)
tmalloc(reverse->states->intlist, int *, ns + 1);
ct = 0; for (cstate = 1; cstate <= ns; cstate++) {
len = short_hash_rec_len(&ht, cstate);
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = cs_ptr + len - 1; /* See if the set contains the initial state */
ptr = cs_ptr - 1; while (++ptr <= cs_ptre) if (*ptr == is) {
reverse->is_accepting[cstate] = TRUE;
ct++; break;
} if (subsets) {
tmalloc(reverse->states->intlist[cstate], int, len + 1);
reverse->states->intlist[cstate][0] = len;
n = 0;
ptr = cs_ptr - 1; while (++ptr <= cs_ptre)
reverse->states->intlist[cstate][++n] = *ptr;
}
}
reverse->num_accepting = ct; if (ct == 1 || ct != ns) {
tmalloc(reverse->accepting, int, ct + 1);
ct = 0; for (i = 1; i <= ns; i++) if (reverse->is_accepting[i])
reverse->accepting[++ct] = i;
}
tfree(reverse->is_accepting);
short_hash_clear(&ht);
tfree(fsarow);
if (destroy)
fsa_clear(fsaptr);
/* Now read the transition table back in */
tempfile = fopen(tempfilename, "r");
compressed_transitions_read(reverse, tempfile);
fclose(tempfile);
unlink(tempfilename);
return reverse;
}
fsa *fsa_reverse_int(fsa *fsaptr, storage_type op_table_type, boolean destroy,
boolean subsets, char *tempfilename)
{
fprintf(stderr, "Sorry - fsa_reverse is not yet implemented for machines.\n");
fprintf(stderr, "with more than 65536 states.\n"); return 0;
}
/* *fsaptr must be a deterministic fsa. * The returned *fsa accepts words accepted by *fsaptr read backwards, * and is a labeled MIDFA, with initial states the singleton accept states of * *fsaptr.
*/
fsa *fsa_mireverse(fsa *fsaptr, storage_type op_table_type, boolean destroy, char *tempfilename)
{ if (kbm_print_level >= 3)
printf(" #Calling fsa_mireverse.\n"); if (fsaptr->states->size < MAXUSHORT) return fsa_mireverse_short(fsaptr, op_table_type, destroy, tempfilename); else return fsa_mireverse_int(fsaptr, op_table_type, destroy, tempfilename);
}
if (kbm_print_level >= 3)
printf(" #Calling fsa_mireverse_short.\n"); if (!fsaptr->flags[DFA]) {
fprintf(stderr, "Error: fsa_mireverse only applies to DFA's.\n"); return 0;
}
ne = fsaptr->alphabet->size;
nsi = fsaptr->states->size;
/* set up the labels for the states of reverse */
reverse->states->type = LABELED;
tmalloc(reverse->states->labels, srec, 1);
labs = reverse->states->labels;
nai = fsaptr->num_accepting;
labs->size = nai + 2;
labs->type = LISTOFINTS; /* The labels will be [i] for all initial states i of fsa, * [0] for other accepting states of reverse, and [] for other states.
*/
tmalloc(labs->intlist, int *, nai + 3); for (i = 1; i <= nai; i++) {
tmalloc(labs->intlist[i], int, 2);
labs->intlist[i][0] = 1;
labs->intlist[i][1] = nsi == nai ? i : fsaptr->accepting[i];
}
tmalloc(labs->intlist[nai + 1], int, 2);
labs->intlist[nai + 1][0] = 1;
labs->intlist[nai + 1][1] = 0;
tmalloc(labs->intlist[nai + 2], int, 1);
labs->intlist[nai + 2][0] = 0;
reverse->num_initial = nai;
tmalloc(reverse->initial, int, nai + 1); for (i = 1; i <= nai; i++)
reverse->initial[i] = i;
/* The states of *reverse will be subsets of the state-set of *fsaptr. * The initial states consists of all singleton accept states of *fsaptr.
*/
short_hash_init(&ht, FALSE, 0, 0, 0); for (i = 1; i <= nai; i++) {
ht_ptrb = ht.current_ptr;
*ht_ptrb = nsi == nai ? i : fsaptr->accepting[i];
im = short_hash_locate(&ht, 1); if (im != i) {
fprintf(stderr, "Hash-initialisation problem in fsa_reverse.\n"); return 0;
}
} if ((tempfile = fopen(tempfilename, "w")) == 0) {
fprintf(stderr, "Error: cannot open file %s\n", tempfilename); return 0;
} if (dense_op)
tmalloc(fsarow, int, ne) else tmalloc(fsarow, int, 2 * ne + 1)
cstate = 0; if (dense_op)
len = ne; /* The length of the fsarow output. */
nt = 0; /* Number of transitions in reverse */
while (++cstate <= ht.num_recs) { if (kbm_print_level >= 3) { if ((cstate <= 1000 && cstate % 100 == 0) ||
(cstate <= 10000 && cstate % 1000 == 0) ||
(cstate <= 100000 && cstate % 5000 == 0) || cstate % 50000 == 0)
printf(" #cstate = %d; number of states = %d.\n", cstate,
ht.num_recs);
}
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = short_hash_rec(&ht, cstate) + short_hash_rec_len(&ht, cstate) - 1; if (!dense_op)
len = 0;
for (g = 1; g <= ne; g++) { /* Calculate action of label g on state cstate - to get the image, we * have to look for all inverse images under g of all states cs in the * subset cstate. The subset formed will be the image.
*/
ht_ptrb = ht.current_ptr;
ht_ptre = ht_ptrb - 1;
ptr = cs_ptr - 1; while (++ptr <= cs_ptre) {
cs = *ptr; for (csi = 1; csi <= nsi; csi++) if (target(dense_ip, table, g, csi, dr) == cs) { /* csi has to be added to the subset of states that forms the image * of cstate under g - we want to keep this subset in ascending * order.
*/ if (ht_ptrb > ht_ptre || csi > *ht_ptre) {
*(++ht_ptre) = csi;
} else {
ht_chptr = ht_ptrb; while (*ht_chptr < csi)
ht_chptr++; if (csi < *ht_chptr) {
ht_ptr = ++ht_ptre; while (ht_ptr > ht_chptr) {
*ht_ptr = *(ht_ptr - 1);
ht_ptr--;
}
*ht_ptr = csi;
}
}
}
}
im = short_hash_locate(&ht, ht_ptre - ht_ptrb + 1); if (dense_op)
fsarow[g - 1] = im; elseif (im > 0) {
fsarow[++len] = g;
fsarow[++len] = im;
} if (im > 0)
nt++;
} if (!dense_op)
fsarow[0] = len++;
fwrite((void *)fsarow, sizeof(int), (size_t)len, tempfile);
}
fclose(tempfile);
/* Initialize the state setToLabels ptr. * Then locate the accept states. These are those that contain the initial * state of *fsaptr.
*/
tmalloc(reverse->states->setToLabels, setToLabelsType, ns + 1); for (i = 1; i <= nai; i++)
reverse->states->setToLabels[i] = i;
is = fsaptr->initial[1];
tmalloc(reverse->is_accepting, boolean, ns + 1); for (i = 1; i <= ns; i++)
reverse->is_accepting[i] = FALSE;
ct = 0; for (cstate = 1; cstate <= ns; cstate++) {
len = short_hash_rec_len(&ht, cstate);
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = cs_ptr + len - 1; /* See if the set contains the initial state */
ptr = cs_ptr - 1; while (++ptr <= cs_ptre) if (*ptr == is) {
reverse->is_accepting[cstate] = TRUE;
ct++; break;
} if (cstate > nai)
reverse->states->setToLabels[cstate] =
reverse->is_accepting[cstate] ? nai + 1 : nai + 2;
}
reverse->num_accepting = ct; if (ct == 1 || ct != ns) {
tmalloc(reverse->accepting, int, ct + 1);
ct = 0; for (i = 1; i <= ns; i++) if (reverse->is_accepting[i])
reverse->accepting[++ct] = i;
}
tfree(reverse->is_accepting);
short_hash_clear(&ht);
tfree(fsarow);
if (destroy)
fsa_clear(fsaptr);
/* Now read the transition table back in */
tempfile = fopen(tempfilename, "r");
compressed_transitions_read(reverse, tempfile);
fclose(tempfile);
unlink(tempfilename);
return reverse;
}
static fsa *fsa_mireverse_int(fsa *fsaptr, storage_type op_table_type,
boolean destroy, char *tempfilename)
{
fprintf(stderr, "Sorry - fsa_mireverse is not yet implemented for machines.\n");
fprintf(stderr, "with more than 65536 states.\n"); return 0;
}
/* *fsaptr must be a 2-variable MIDFA fsa. * The returned midfa accepts a word w_1 iff (w_1,w_2) is accepted by *fsaptr, * for some word w_2 - but here the padding symbol is part of the * alphabet of the output midfa. * In fact, fsa_miexists1 calls fsa_miexists1_int or (more usually) * fsa_miexists1_short, the latter using the short hash table functions.
*/
fsa *fsa_miexists1(fsa *fsaptr, storage_type op_table_type, boolean destroy, char *tempfilename)
{ if (kbm_print_level >= 3)
printf(" #Calling fsa_miexists1.\n"); if (fsaptr->states->size < MAXUSHORT) return fsa_miexists1_short(fsaptr, op_table_type, destroy, tempfilename); else return fsa_miexists1_int(fsaptr, op_table_type, destroy, tempfilename);
}
if (kbm_print_level >= 3)
printf(" #Calling fsa_miexists1_short.\n"); if (!fsaptr->flags[MIDFA]) {
fprintf(stderr, "Error: fsa_miexists1 only applies to MIDFA's.\n"); exit(1);
}
if (fsaptr->alphabet->type != PRODUCT || fsaptr->alphabet->arity != 2) {
fprintf(stderr, "Error in fsa_miexists1: fsa must be 2-variable.\n"); exit(1);
}
ni = fsaptr->num_initial;
miexists1->num_initial = ni;
tmalloc(miexists1->initial, int, ni + 1); for (i = 1; i <= ni; i++)
miexists1->initial[i] = i;
short_hash_init(&ht, FALSE, 0, 0, 0); for (i = 1; i <= ni; i++) {
ht_ptrb = ht.current_ptr;
*ht_ptrb = nsi == ni ? i : fsaptr->initial[i];
im = short_hash_locate(&ht, 1); if (im != i) {
fprintf(stderr, "Hash-initialisation problem in fsa_miexists.\n"); exit(1);
}
} /* Each state in 'miexists1' will be represented as a subset of the states * of *fsaptr. The initial states are one-element set containing the initial * states of *fsaptr. A subset is an accept-state if it contains an accept * state of *fsaptr. * The subsets will be stored as variable-length records in the hash-table, * always in increasing order.
*/ if ((tempfile = fopen(tempfilename, "w")) == 0) {
fprintf(stderr, "Error: cannot open file %s\n", tempfilename); exit(1);
} if (dense_op)
tmalloc(fsarow, int, ngens) else tmalloc(fsarow, int, 2 * ngens + 1)
cstate = 0; if (dense_op)
len = ngens + 1; /* The length of the fsarow output. */
nt = 0; /* Number of transitions in miexists1 */
while (++cstate <= ht.num_recs) { if (kbm_print_level >= 3) { if ((cstate <= 1000 && cstate % 100 == 0) ||
(cstate <= 10000 && cstate % 1000 == 0) ||
(cstate <= 100000 && cstate % 5000 == 0) || cstate % 50000 == 0)
printf(" #cstate = %d; number of states = %d.\n", cstate,
ht.num_recs);
}
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = short_hash_rec(&ht, cstate) + short_hash_rec_len(&ht, cstate) - 1; if (!dense_op)
len = 0;
for (g1 = 1; g1 <= ngens + 1; g1++) { /* Calculate action of generator g1 on state cstate - to get the image, * we have to apply (g1,g2) to each element in the subset corresponding to * cstate, and this for each generator g2 of the base-alphabet (including * the padding symbol).
*/
ht_ptrb = ht.current_ptr;
ht_ptre = ht_ptrb - 1;
ptr = cs_ptr - 1;
es = (g1 - 1) * (ngens + 1) + 1;
ef = g1 == ngens + 1 ? g1 * (ngens + 1) - 1 : g1 * (ngens + 1); /* As g2 ranges from 1 to ngens+1 in the pair (g1,g2), for fixed g1, the * corresponding edge number in the fsa ranges from es to ef.
*/ while (++ptr <= cs_ptre) {
cs = *ptr; for (e = es; e <= ef; e++) {
csi = target(dense_ip, table, e, cs, dr); if (csi == 0) continue; if (ht_ptrb > ht_ptre || csi > *ht_ptre) { /* We have a new state for the image subset to be added to the end
*/
*(++ht_ptre) = csi;
} else {
ht_chptr = ht_ptrb; while (*ht_chptr < csi)
ht_chptr++; if (csi < *ht_chptr) { /* we have a new state for the image subset to be added in the
* middle */
ht_ptr = ++ht_ptre; while (ht_ptr > ht_chptr) {
*ht_ptr = *(ht_ptr - 1);
ht_ptr--;
}
*ht_ptr = csi;
}
}
}
}
im = short_hash_locate(&ht, ht_ptre - ht_ptrb + 1); if (dense_op)
fsarow[g1 - 1] = im; elseif (im > 0) {
fsarow[++len] = g1;
fsarow[++len] = im;
} if (im > 0)
nt++;
} if (!dense_op)
fsarow[0] = len++;
fwrite((void *)fsarow, sizeof(int), (size_t)len, tempfile);
}
fclose(tempfile);
/* Locate the initial and accept states, and assign labels. * A state is an accept state if the * corresponding subset contains an accept state of *fsaptr. * We will need to use the array miexists1->is_accepting.
*/
tmalloc(miexists1->states->setToLabels, setToLabelsType, ns + 1); for (i = 1; i <= ni; i++)
miexists1->states->setToLabels[i] =
fsaptr->states->setToLabels[fsaptr->initial[i]];
tmalloc(miexists1->is_accepting, boolean, ns + 1); for (i = 1; i <= ns; i++)
miexists1->is_accepting[i] = FALSE;
ct = 0; for (cstate = ns; cstate >= 1; cstate--) {
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = short_hash_rec(&ht, cstate) + short_hash_rec_len(&ht, cstate) - 1; /* See if the set an accept-state */
ptr = cs_ptr - 1; while (++ptr <= cs_ptre) if (fsaptr->is_accepting[*ptr]) {
miexists1->is_accepting[cstate] = TRUE;
ct++; break;
} if (cstate > ni)
miexists1->states->setToLabels[cstate] =
miexists1->is_accepting[cstate] ? ni + 1 : ni + 2;
}
miexists1->num_accepting = ct; if (ct == 1 || ct != ns) {
tmalloc(miexists1->accepting, int, ct + 1);
ct = 0; for (i = 1; i <= ns; i++) if (miexists1->is_accepting[i])
miexists1->accepting[++ct] = i;
}
tfree(fsaptr->is_accepting);
tfree(miexists1->is_accepting);
short_hash_clear(&ht);
tfree(fsarow);
if (destroy)
fsa_clear(fsaptr);
/* Now read the transition table back in */
tempfile = fopen(tempfilename, "r");
compressed_transitions_read(miexists1, tempfile);
fclose(tempfile);
unlink(tempfilename);
return miexists1;
}
static fsa *fsa_miexists1_int(fsa *fsaptr, storage_type op_table_type,
boolean destroy, char *tempfilename)
{
fprintf(stderr, "Sorry - fsa_miexists1 is not yet implemented for machines.\n");
fprintf(stderr, "with more than 65536 states.\n"); exit(1);
}
/* *fsaptr must be a 2-variable MIDFA fsa. * The returned midfa accepts a word w_1 iff (w_1,w_2) is accepted by *fsaptr, * for some word w_2 - but here the padding symbol is part of the * alphabet of the output midfa. * In fact, fsa_miexists2 calls fsa_miexists2_int or (more usually) * fsa_miexists2_short, the latter using the short hash table functions.
*/
fsa *fsa_miexists2(fsa *fsaptr, storage_type op_table_type, boolean destroy, char *tempfilename)
{ if (kbm_print_level >= 3)
printf(" #Calling fsa_miexists2.\n"); if (fsaptr->states->size < MAXUSHORT) return fsa_miexists2_short(fsaptr, op_table_type, destroy, tempfilename); else return fsa_miexists2_int(fsaptr, op_table_type, destroy, tempfilename);
}
if (kbm_print_level >= 3)
printf(" #Calling fsa_miexists2_short.\n"); if (!fsaptr->flags[MIDFA]) {
fprintf(stderr, "Error: fsa_miexists2 only applies to MIDFA's.\n"); exit(1);
}
if (fsaptr->alphabet->type != PRODUCT || fsaptr->alphabet->arity != 2) {
fprintf(stderr, "Error in fsa_miexists2: fsa must be 2-variable.\n"); exit(1);
}
ni = fsaptr->num_initial;
miexists2->num_initial = ni;
tmalloc(miexists2->initial, int, ni + 1); for (i = 1; i <= ni; i++)
miexists2->initial[i] = i;
short_hash_init(&ht, FALSE, 0, 0, 0); for (i = 1; i <= ni; i++) {
ht_ptrb = ht.current_ptr;
*ht_ptrb = nsi == ni ? i : fsaptr->initial[i];
im = short_hash_locate(&ht, 1); if (im != i) {
fprintf(stderr, "Hash-initialisation problem in fsa_miexists.\n"); exit(1);
}
} /* Each state in 'miexists2' will be represented as a subset of the states * of *fsaptr. The initial states are one-element set containing the initial * states of *fsaptr. A subset is an accept-state if it contains an accept * state of *fsaptr. * The subsets will be stored as variable-length records in the hash-table, * always in increasing order.
*/ if ((tempfile = fopen(tempfilename, "w")) == 0) {
fprintf(stderr, "Error: cannot open file %s\n", tempfilename); exit(1);
} if (dense_op)
tmalloc(fsarow, int, ngens) else tmalloc(fsarow, int, 2 * ngens1)
cstate = 0; if (dense_op)
len = ngens1; /* The length of the fsarow output. */
nt = 0; /* Number of transitions in miexists2 */
while (++cstate <= ht.num_recs) { if (kbm_print_level >= 3) { if ((cstate <= 1000 && cstate % 100 == 0) ||
(cstate <= 10000 && cstate % 1000 == 0) ||
(cstate <= 100000 && cstate % 5000 == 0) || cstate % 50000 == 0)
printf(" #cstate = %d; number of states = %d.\n", cstate,
ht.num_recs);
}
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = short_hash_rec(&ht, cstate) + short_hash_rec_len(&ht, cstate) - 1; if (!dense_op)
len = 0;
for (g2 = 1; g2 <= ngens1; g2++) { /* Calculate action of generator g2 on state cstate - to get the image, * we have to apply (g1,g2) to each element in the subset corresponding to * cstate, and this for each generator g1 of the base-alphabet (including * the padding symbol).
*/
ht_ptrb = ht.current_ptr;
ht_ptre = ht_ptrb - 1;
ptr = cs_ptr - 1;
es = g2;
ef = g2 == ngens1 ? ngens * ngens + g2 : ngens * ngens1 + g2; /* As g2 ranges from 1 to ngens+1 in the pair (g2,g2), for fixed g2, the * corresponding edge number in the fsa ranges from es to ef.
*/ while (++ptr <= cs_ptre) {
cs = *ptr; for (e = es; e <= ef; e += ngens1) {
csi = target(dense_ip, table, e, cs, dr); if (csi == 0) continue; if (ht_ptrb > ht_ptre || csi > *ht_ptre) { /* We have a new state for the image subset to be added to the end
*/
*(++ht_ptre) = csi;
} else {
ht_chptr = ht_ptrb; while (*ht_chptr < csi)
ht_chptr++; if (csi < *ht_chptr) { /* we have a new state for the image subset to be added in the
* middle */
ht_ptr = ++ht_ptre; while (ht_ptr > ht_chptr) {
*ht_ptr = *(ht_ptr - 1);
ht_ptr--;
}
*ht_ptr = csi;
}
}
}
}
im = short_hash_locate(&ht, ht_ptre - ht_ptrb + 1); if (dense_op)
fsarow[g2 - 1] = im; elseif (im > 0) {
fsarow[++len] = g2;
fsarow[++len] = im;
} if (im > 0)
nt++;
} if (!dense_op)
fsarow[0] = len++;
fwrite((void *)fsarow, sizeof(int), (size_t)len, tempfile);
}
fclose(tempfile);
/* Locate the initial and accept states, and assign labels. * A state is an accept state if the * corresponding subset contains an accept state of *fsaptr. * We will need to use the array miexists2->is_accepting.
*/
tmalloc(miexists2->states->setToLabels, setToLabelsType, ns + 1); for (i = 1; i <= ni; i++)
miexists2->states->setToLabels[i] =
fsaptr->states->setToLabels[fsaptr->initial[i]];
tmalloc(miexists2->is_accepting, boolean, ns + 1); for (i = 1; i <= ns; i++)
miexists2->is_accepting[i] = FALSE;
ct = 0; for (cstate = ns; cstate >= 1; cstate--) {
cs_ptr = short_hash_rec(&ht, cstate);
cs_ptre = short_hash_rec(&ht, cstate) + short_hash_rec_len(&ht, cstate) - 1; /* See if the set an accept-state */
ptr = cs_ptr - 1; while (++ptr <= cs_ptre) if (fsaptr->is_accepting[*ptr]) {
miexists2->is_accepting[cstate] = TRUE;
ct++; break;
} if (cstate > ni)
miexists2->states->setToLabels[cstate] =
miexists2->is_accepting[cstate] ? ni + 1 : ni + 2;
}
miexists2->num_accepting = ct; if (ct == 1 || ct != ns) {
tmalloc(miexists2->accepting, int, ct + 1);
ct = 0; for (i = 1; i <= ns; i++) if (miexists2->is_accepting[i])
miexists2->accepting[++ct] = i;
}
tfree(fsaptr->is_accepting);
tfree(miexists2->is_accepting);
short_hash_clear(&ht);
tfree(fsarow);
if (destroy)
fsa_clear(fsaptr);
/* Now read the transition table back in */
tempfile = fopen(tempfilename, "r");
compressed_transitions_read(miexists2, tempfile);
fclose(tempfile);
unlink(tempfilename);
return miexists2;
}
static fsa *fsa_miexists2_int(fsa *fsaptr, storage_type op_table_type,
boolean destroy, char *tempfilename)
{
fprintf(stderr, "Sorry - fsa_miexists2 is not yet implemented for machines.\n");
fprintf(stderr, "with more than 65536 states.\n"); exit(1);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.36 Sekunden
(vorverarbeitet)
¤
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.