/* *subwaptr is intended to be a candidate subgroup word-acceptor of an *automaticgroup(butcouldbeanysingle-variabledfa). **multptrisassumedtobeamultiplierofthesameautomatic *group(butcouldbeanyn2-variabledfawithbasealphabetequalto *thealphabetof*subwaptr).Bothareassumedtobestoredindense-format. *Thisroutineconstructsthefsaofwhichthestatesaretriples(s1,s2,d), *withs1ands2statesof*subwaptranddastateof*multptr. *(Moreprecisely,if*subwaptrhasnstates,thens1ands2mayalsobeequal *ton+1,meaningthattheendofstringsymbolhasbeenreadonlhsorrhs, *with*subwaptrinanacceptedstate.) *Thealphabetis2-variablewithbasethealphabetof*subwaptr *(i.e.thesamealphabetas*multptr). *Thealphabetmember(g1,g2)maps(s1,s2,d)to(s1^g1,s2^g2,d^(g1,g2)) *ifallthreecomponentsarenonzero,andtozerootherwise. *Theaccept-statesarethoseinwhichs1,s2,dareaccept-states,or *s1ors2=n+1(seeabove). *Thetransition-tableoftheresultingfsaisoutputintheusualwayto *filetempfilenamewithtable-typespecifiedbyop_table_type,before *minimisation. *Shorthash-tableswillbeused,sothisroutinewon'tworkif*subwaptr *or*multptrhasmorethanMAXUSHORTstates. *
*/
fsa *fsa_submult(fsa *subwaptr, fsa *multptr, storage_type op_table_type,
boolean destroy, char *tempfilename, boolean readback)
{ int **subwatable, ***multtable, ngens, ngens1, nsswa1, ne, nsswa, ns, *fsarow,
nt, cstate, csswa1, csswa2, csmult, im, i, e, len = 0, ct; unsignedshort *ht_ptr;
boolean dense_op, acc;
fsa *submultptr;
short_hash_table ht;
FILE *tempfile;
gen g1, g2;
if (kbm_print_level >= 3)
printf(" #Calling fsa_submultptr.\n");
if (!subwaptr->flags[DFA] || !multptr->flags[DFA]) {
fprintf(stderr, "Error: fsa_submultptr only applies to DFA's.\n"); return0;
} if (multptr->alphabet->type != PRODUCT || multptr->alphabet->arity != 2) {
fprintf(stderr, "Error in fsa_submultptr: second fsa must be 2-variable.\n"); return0;
} if (!srec_equal(multptr->alphabet->base, subwaptr->alphabet)) {
fprintf(stderr, "Error in fsa_submultptr: fsa's alphabet's don't match.\n"); return0;
} if (subwaptr->states->size >= MAXUSHORT ||
multptr->states->size >= MAXUSHORT) {
fprintf(stderr, "Error in fsa_submultptr: one of the fsa's has too many states.\n"); return0;
}
fsa_set_is_accepting(multptr); /* We do not call fsa_ptr_is_accepting on subwaptr, since we need an extra *placeinitfortheend-of-stringstate(whichwillbeaccepting).
*/
nsswa = subwaptr->states->size;
nsswa1 = nsswa + 1;
tmalloc(subwaptr->is_accepting, boolean, nsswa + 2); if (subwaptr->num_accepting == nsswa) { for (i = 1; i <= nsswa; i++)
subwaptr->is_accepting[i] = TRUE;
} else { for (i = 1; i <= nsswa; i++)
subwaptr->is_accepting[i] = FALSE; for (i = 1; i <= subwaptr->num_accepting; i++)
subwaptr->is_accepting[subwaptr->accepting[i]] = TRUE;
}
subwaptr->is_accepting[nsswa1] = TRUE;
short_hash_init(&ht, TRUE, 3, 0, 0);
ht_ptr = ht.current_ptr;
ht_ptr[0] = subwaptr->initial[1];
ht_ptr[1] = subwaptr->initial[1];
ht_ptr[2] = multptr->initial[1];
im = short_hash_locate(&ht, 3); if (im != 1) {
fprintf(stderr, "Hash-initialisation problem in fsa_submult.\n"); return0;
} if ((tempfile = fopen(tempfilename, "w")) == 0) {
fprintf(stderr, "Error: cannot open file %s\n", tempfilename); return0;
} 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 submultptr */
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);
}
ht_ptr = short_hash_rec(&ht, cstate);
csswa1 = ht_ptr[0];
csswa2 = ht_ptr[1];
csmult = ht_ptr[2]; if (!dense_op)
len = 0;
e = 0; /* e is the number of the edge corresponding to the pair (g1,g2) */ for (g1 = 1; g1 <= ngens1; g1++) for (g2 = 1; g2 <= ngens1; g2++) {
e++; /* Calculate action of generator-pair (g1,g2) on state cstate */ if (g1 == ngens1 && g2 == ngens1) continue;
ht_ptr = ht.current_ptr;
ht_ptr[2] = dense_dtarget(multtable, g1, g2, csmult); if (ht_ptr[2] == 0)
im = 0; else { if (csswa1 == nsswa1) {
ht_ptr[0] = g1 == ngens1 ? nsswa1 : 0;
} else {
ht_ptr[0] = g1 == ngens1
? (subwaptr->is_accepting[csswa1] ? nsswa1 : 0)
: dense_target(subwatable, g1, csswa1);
} if (ht_ptr[0] == 0)
im = 0; else { if (csswa2 == nsswa1) {
ht_ptr[1] = g2 == ngens1 ? nsswa1 : 0;
} else {
ht_ptr[1] = g2 == ngens1
? (subwaptr->is_accepting[csswa2] ? nsswa1 : 0)
: dense_target(subwatable, g2, csswa2);
} if (ht_ptr[1] == 0)
im = 0; else
im = short_hash_locate(&ht, 3);
}
}
if (kbm_print_level >= 3) {
printf(" #Calculated transitions - %d states, %d transitions.\n", ns,
nt);
printf(" #Now calculating state labels.\n");
} /* Now we locate the accept states */
tmalloc(submultptr->is_accepting, boolean, ns + 1); for (i = 1; i <= ns; i++)
submultptr->is_accepting[i] = FALSE;
ct = 0; for (i = 1; i <= ns; i++) {
ht_ptr = short_hash_rec(&ht, i);
acc = submultptr->is_accepting[i] = subwaptr->is_accepting[ht_ptr[0]] &&
subwaptr->is_accepting[ht_ptr[1]] &&
multptr->is_accepting[ht_ptr[2]]; if (acc)
ct++;
}
submultptr->num_accepting = ct; if (ct == 1 || ct != ns) {
tmalloc(submultptr->accepting, int, ct + 1);
ct = 0; for (i = 1; i <= ns; i++) if (submultptr->is_accepting[i])
submultptr->accepting[++ct] = i;
}
tfree(submultptr->is_accepting);
short_hash_clear(&ht);
tfree(fsarow); /* Now read the transition table back in */ if (readback) {
tempfile = fopen(tempfilename, "r");
compressed_transitions_read(submultptr, tempfile);
fclose(tempfile);
unlink(tempfilename);
}
tfree(subwaptr->is_accepting);
tfree(multptr->is_accepting); if (destroy) {
fsa_clear(subwaptr);
fsa_clear(multptr);
}
return submultptr;
}
/* Generate at most maxwords words accepted by *fsaptr1 but not by *fsaptr2. *Storetheminwords[0],words[1],.. *fsa'smayhaveatmost65536states.
*/ int words_and_not(fsa *fsaptr1, fsa *fsaptr2, gen **words, int maxwords)
{ int **table1, **table2, ne, ns, dr1, dr2, bstate, bg, numwords, cstate, csa,
csb, im, i, g, len = 0; unsignedshort *ht_ptr;
boolean dense_ip1, dense_ip2;
short_hash_table ht; int maxv = 65536; struct vertexd {
gen g; int state;
} * definition, *newdef; /* This is used to store the defining transition for the states of the new *fsa.Ifdefinition[i]=v,thenstateiisdefinedbythetransitionfrom *statev.state,withfirstgeneratorv.g(thesecondgenerator(from **fsaptr2)doesnotneedtoberemembered).State1doesnothavea *definition.
*/
if (kbm_print_level >= 3)
printf(" #Calling words_and_not.\n"); if (!fsaptr1->flags[DFA] || !fsaptr2->flags[DFA]) {
fprintf(stderr, "Error: words_and_not only applies to DFA's.\n"); return -1;
}
if (!srec_equal(fsaptr1->alphabet, fsaptr2->alphabet)) {
fprintf(stderr, "Error in words_and_not: fsa's have different alphabets.\n"); return -1;
}
if (fsaptr1->states->size >= MAXUSHORT ||
fsaptr2->states->size >= MAXUSHORT) {
fprintf(stderr, "Sorry - one of the fsa's in words_and_not has too many states.\n"); return -1;
} if (fsaptr1->flags[RWS])
fsa_clear_rws(fsaptr1);
if (fsaptr2->flags[RWS])
fsa_clear_rws(fsaptr2);
if (fsaptr1->num_initial == 0 || fsaptr2->num_initial == 0) {
fprintf(stderr, "One of the fsa's in words_and_not has no initial states.\n");
fprintf(stderr, "Sorry - this case has not been catered for!\n"); return -1;
}
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.