/* gpgeowa.c 15/4/96.
* 28/10/98 -n option: output a new 2-variable automaton near_geopairs
* together with associated difference-machine near_geodiff,
* which accepts all pairs of geodesics which end at distance at most
* one apart. This is formed by composing with the generalised
* multiplier.
* 29/9/98 large-scale re-organisation. Abolish almost all global variables
* and make them components of the rws structure.
*
* 5/2/98 change generators from type char to type `gen'.
* SYNOPSIS:
* gpgeowa [-op1 d/s] [-op2 d/s] [-silent] [-v] [-l/-h] [-f] [-diff1/-diff2]
* [-me maxeqns] [-mwd maxwdiffs] [-n] groupname
*
* Input is from groupname.wa and groupname.diff2 (or groupname.diff1)
* Output is to groupname.geowa, groupname.geodiff and groupname.geopairs
* Also, a temporary updated diff file for geodesic reduction to
* shortlex word representative will be output to groupname.tdiff.
*
* OPTIONS:
* -op1 d/s output of geowa machine in dense or sparse format -
* dense is default
* -op2 d/s output of geodiff and geopairs machines in dense or sparse
* format - sparse is default
* -v verbose
* -silent no diagnostics
* -l/-h large/huge hash-tables (for big examples)
* -f read the transition table repeatedly from file while mimimizing.
* this avoids storing the large table, but is a little slower.
* -diff1/diff2 take input from groupname.diff1 or groupname.diff2
* (diff2 is default). Latter is usually better.
* -me maxeqns Abort the geodesic word-acceptor checking process after finding
* maxeqns offending words w - default is MAXEQNS
* -mwd maxwdiffs
* At most maxwdiffs word-differences possible in tdiff machine.
* -n output a new 2-variable automaton near_geopairs
* together with associated difference-machine near_geodiff,
*
*/
#include <stdio.h>
#include "defs.h"
#include "fsa.h"
#include "rws.h"
#include "definitions.h"
#define MAXEQNS 512
#define MAXWDIFFS 4096
static FILE *rfile, *wfile;
static void badusage(void);
int (*reduce_word)(gen *w, reduction_struct *rs_rws);
int main(int argc, char *argv[])
{
int arg, i, ct, ngens;
char inf1[100], inf2[100], inf3[100], outf1[100], outf2[100], outf3[100],
outf4[100], outf5[100], outf6[100], fsaname[100], tempfilename[100];
int maxeqns, maxwdiffs, numeqns, old_ndiff, *inv;
fsa temp, *waptr, *geowaptr, *geodiffptr, *tdiffptr, *gmptr, *gpp,
*geopairsptr, *tgpp;
reduction_equation *eqnptr;
reduction_struct rs_wd;
storage_type op_store1 = DENSE;
storage_type op_store2 = SPARSE;
boolean diff1_ip = FALSE, readback = TRUE;
boolean near_machine = FALSE;
setbuf(stdout, (char *)0);
setbuf(stderr, (char *)0);
maxeqns = MAXEQNS;
maxwdiffs = MAXWDIFFS;
inf1[0] = '\0';
arg = 1;
while (argc > arg) {
if (strcmp(argv[arg], "-op1") == 0) {
arg++;
if (arg >= argc)
badusage();
if (strcmp(argv[arg], "d") == 0)
op_store1 = DENSE;
else if (strcmp(argv[arg], "s") == 0)
op_store1 = SPARSE;
else
badusage();
}
else if (strcmp(argv[arg], "-op2") == 0) {
arg++;
if (arg >= argc)
badusage();
if (strcmp(argv[arg], "d") == 0)
op_store2 = DENSE;
else if (strcmp(argv[arg], "s") == 0)
op_store2 = SPARSE;
else
badusage();
}
else if (strcmp(argv[arg], "-silent") == 0)
kbm_print_level = 0;
else if (strcmp(argv[arg], "-v") == 0)
kbm_print_level = 2;
else if (strcmp(argv[arg], "-vv") == 0)
kbm_print_level = 3;
else if (strcmp(argv[arg], "-l") == 0)
kbm_large = TRUE;
else if (strcmp(argv[arg], "-h") == 0)
kbm_huge = TRUE;
else if (strcmp(argv[arg], "-f") == 0)
readback = FALSE;
else if (strcmp(argv[arg], "-diff1") == 0)
diff1_ip = TRUE;
else if (strcmp(argv[arg], "-diff2") == 0)
diff1_ip = FALSE;
else if (strcmp(argv[arg], "-n") == 0)
near_machine = TRUE;
else if (strcmp(argv[arg], "-me") == 0) {
arg++;
if (arg >= argc)
badusage();
maxeqns = atoi(argv[arg]);
}
else if (strcmp(argv[arg], "-mwd") == 0) {
arg++;
if (arg >= argc)
badusage();
maxwdiffs = atoi(argv[arg]);
}
else {
if (argv[arg][0] == '-')
badusage();
if (strcmp(inf1, "") != 0)
badusage();
else
strcpy(inf1, argv[arg]);
}
arg++;
}
if (stringlen(inf1) == 0)
badusage();
if (diff1_ip) {
/* We need to copy the diff1 machine to the file groupname.tdiff */
strcpy(inf2, inf1);
strcat(inf2, ".diff1");
if ((rfile = fopen(inf2, "r")) == 0) {
fprintf(stderr, "Cannot open file %s.\n", inf2);
exit(1);
}
fsa_read(rfile, &temp, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
strcpy(outf4, inf1);
strcat(outf4, ".tdiff");
base_prefix(fsaname);
strcat(fsaname, ".tdiff");
wfile = fopen(outf4, "w");
fsa_print(wfile, &temp, fsaname);
fclose(wfile);
}
tmalloc(eqnptr, reduction_equation, maxeqns);
strcpy(tempfilename, inf1);
strcat(tempfilename, "temp_triples_XXX");
strcpy(inf2, inf1);
strcat(inf2, ".diff2");
strcpy(inf3, inf1);
strcat(inf3, ".gm");
strcpy(outf1, inf1);
strcat(outf1, ".geowa");
strcpy(outf2, inf1);
strcat(outf2, ".geopairs");
strcpy(outf3, inf1);
strcat(outf3, ".geodiff");
strcpy(outf4, inf1);
strcat(outf4, ".tdiff");
strcpy(outf5, inf1);
strcat(outf5, ".near_geopairs");
strcpy(outf6, inf1);
strcat(outf6, ".near_geodiff");
strcat(inf1, ".wa");
/* First read in the second-word difference machine for word-reduction */
tmalloc(rs_wd.wd_fsa, fsa, 1);
if ((rfile = fopen(inf2, "r")) == 0) {
fprintf(stderr, "Cannot open file %s.\n", inf2);
exit(1);
}
fsa_read(rfile, rs_wd.wd_fsa, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
ngens = rs_wd.wd_fsa->alphabet->base->size;
if (fsa_table_dptr_init(rs_wd.wd_fsa) == -1)
exit(1);
reduce_word = diff_reduce;
if (!diff1_ip) {
/* Write this fsa to the temporary file as first approximation to *tdiffptr
*/
base_prefix(fsaname);
strcat(fsaname, ".tdiff");
wfile = fopen(outf4, "w");
fsa_print(wfile, rs_wd.wd_fsa, fsaname);
fclose(wfile);
}
tmalloc(waptr, fsa, 1);
tmalloc(tdiffptr, fsa, 1);
/* Now start the loop to calculate the correct geowaptr and tdiffptr */
ct = 0;
while (1) {
ct++;
/* Read in word-acceptor. */
if ((rfile = fopen(inf1, "r")) == 0) {
fprintf(stderr, "Cannot open file %s.\n", inf1);
exit(1);
}
fsa_read(rfile, waptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
if (ct > 1) {
/* Re-read in tdiffptr */
rfile = fopen(outf4, "r");
fsa_read(rfile, tdiffptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
}
else {
/* The first approximation to *tdiffptr is the diff2 machine which we
* have already read in as *wd_fsa, so we copy it.
*/
fsa_copy(tdiffptr, rs_wd.wd_fsa);
}
geopairsptr =
fsa_geopairs(waptr, tdiffptr, op_store2, TRUE, tempfilename, readback);
if (geopairsptr == 0)
exit(1);
if (kbm_print_level > 1)
printf(" #Number of states of geopairs before minimisation = %d.\n",
geopairsptr->states->size);
if (readback) {
if (fsa_minimize(geopairsptr) == -1)
exit(1);
}
else {
if (fsa_ip_minimize(geopairsptr) == -1)
exit(1);
}
if (kbm_print_level > 1)
printf(" #Number of states of geopairs after minimisation = %d.\n",
geopairsptr->states->size);
base_prefix(fsaname);
strcat(fsaname, ".geopairs");
wfile = fopen(outf2, "w");
fsa_print(wfile, geopairsptr, fsaname);
fclose(wfile);
fsa_clear(geopairsptr);
/* Next we form the updated *geowaptr. We read *geopairsptr back in again
* (since the table format required is usually different).
*/
rfile = fopen(outf2, "r");
fsa_read(rfile, geopairsptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
geowaptr = fsa_exists(geopairsptr, op_store1, TRUE, tempfilename);
if (geowaptr == 0)
exit(1);
if (kbm_print_level > 1)
printf(" #Number of states of geowa before minimisation = %d.\n",
geowaptr->states->size);
/* We will make the language prefix closed, then output
if (geowaptr->states->size > 1) {
tfree(geowaptr->accepting);
geowaptr->num_accepting=geowaptr->states->size;
}
*/
if (fsa_minimize(geowaptr) == -1)
exit(1);
if (kbm_print_level > 1)
printf(" #Number of states of geowa after minimisation = %d.\n",
geowaptr->states->size);
base_prefix(fsaname);
strcat(fsaname, ".geowa");
wfile = fopen(outf1, "w");
fsa_print(wfile, geowaptr, fsaname);
fclose(wfile);
fsa_clear(geowaptr);
/* Now we read *geowaptr and *tdiffptr back in for the correctness
* test on the former.
*/
rfile = fopen(outf1, "r");
fsa_read(rfile, geowaptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
rfile = fopen(outf4, "r");
fsa_read(rfile, tdiffptr, DENSE, 0, maxwdiffs, TRUE, fsaname);
fclose(rfile);
numeqns = fsa_checkgeowa(geowaptr, tdiffptr, eqnptr, maxeqns);
if (numeqns == -1)
exit(1);
if (numeqns == 0) {
if (kbm_print_level > 0)
printf("#Geodesic word-acceptor with %d states computed.\n",
geowaptr->states->size);
fsa_clear(geowaptr);
fsa_clear(tdiffptr);
break; /* Correctness test passed */
}
else {
fsa_clear(geowaptr);
/* We are going to reduce the words returned to their shortlex normal
* form, then adjoin the associated word-differences to *tdiffptr.
*/
tfree(geowaptr);
tfree(geopairsptr);
if (kbm_print_level > 1)
printf(" #Updating geodesic word-difference machine.\n");
old_ndiff = tdiffptr->states->size;
if (calculate_inverses(&inv, ngens, &rs_wd) == -1)
exit(1);
for (i = 0; i < numeqns; i++) {
tmalloc(eqnptr[i].rhs, gen, genstrlen(eqnptr[i].lhs) + 1);
genstrcpy(eqnptr[i].rhs, eqnptr[i].lhs);
reduce_word(eqnptr[i].rhs, &rs_wd);
if (add_wd_fsa(tdiffptr, eqnptr + i, inv, TRUE, &rs_wd) == -1)
exit(1);
tfree(eqnptr[i].lhs) tfree(eqnptr[i].rhs)
}
if (make_full_wd_fsa(tdiffptr, inv, old_ndiff + 1, &rs_wd) == -1)
exit(1);
tfree(inv);
if (kbm_print_level > 1)
printf(" #Geodesic word-difference machine now has %d states.\n",
tdiffptr->states->size);
base_prefix(fsaname);
strcat(fsaname, ".tdiff");
wfile = fopen(outf4, "w");
fsa_print(wfile, tdiffptr, fsaname);
fclose(wfile);
fsa_clear(tdiffptr);
}
}
tfree(waptr);
tfree(geowaptr);
tfree(tdiffptr);
/* The current *geopairsptr accepts (w1,w2) if w1=w2, w1 and w2 are
* geodesics, and w2 is accepted by the word-acceptor.
* To get it to accept ALL pairs of equal geodesics, we form the
* composite of itself with its transpose.
*/
tmalloc(gpp, fsa, 1);
tmalloc(tgpp, fsa, 1);
rfile = fopen(outf2, "r");
fsa_read(rfile, gpp, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
fsa_copy(tgpp, gpp);
if (fsa_swap_coords(tgpp) == -1)
exit(1);
tfree(geopairsptr);
geopairsptr =
fsa_composite(gpp, tgpp, op_store2, FALSE, tempfilename, readback);
if (geopairsptr == 0)
exit(1);
if (kbm_print_level > 1)
printf(" #Number of states of final geopairs before minimisation = %d.\n",
geopairsptr->states->size);
if (readback) {
if (fsa_minimize(geopairsptr) == -1)
exit(1);
}
else {
if (fsa_ip_minimize(geopairsptr) == -1)
exit(1);
}
if (kbm_print_level > 1)
printf(" #Number of states of final geopairs after minimisation = %d.\n",
geopairsptr->states->size);
if (kbm_print_level > 0)
printf("#Geodesic pairs machine with %d states computed.\n",
geopairsptr->states->size);
base_prefix(fsaname);
strcat(fsaname, ".geopairs");
wfile = fopen(outf2, "w");
fsa_print(wfile, geopairsptr, fsaname);
fclose(wfile);
fsa_clear(geopairsptr);
/* Now form the geodesic word-difference machine */
rfile = fopen(outf2, "r");
fsa_read(rfile, geopairsptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
geodiffptr = fsa_diff(geopairsptr, &rs_wd, op_store2);
fsa_clear(geopairsptr);
tfree(geopairsptr);
base_prefix(fsaname);
strcat(fsaname, ".geodiff");
wfile = fopen(outf3, "w");
fsa_print(wfile, geodiffptr, fsaname);
fclose(wfile);
if (kbm_print_level > 0)
printf("#Geodesic difference machine with %d states computed.\n",
geodiffptr->states->size);
fsa_clear(geodiffptr);
tfree(geodiffptr);
if (!near_machine) {
fsa_clear(gpp);
tfree(gpp);
fsa_clear(tgpp);
tfree(tgpp);
fsa_clear(rs_wd.wd_fsa);
tfree(rs_wd.wd_fsa);
tfree(eqnptr);
exit(0);
}
/* Finally, we form near_geopairs, which accepts pairs of geodesics
* that finish distance at most one apart. To do this we form the
* composite gpp * gm * tgpp.
*/
rfile = fopen(inf3, "r");
tmalloc(gmptr, fsa, 1);
fsa_read(rfile, gmptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
/* first compose gpp with gm */
geopairsptr =
fsa_composite(gpp, gmptr, op_store2, TRUE, tempfilename, readback);
if (geopairsptr == 0)
exit(1);
tfree(gpp);
tfree(gmptr);
if (kbm_print_level > 1)
printf(" #Number of states of first composite = %d.\n",
geopairsptr->states->size);
if (readback) {
if (fsa_minimize(geopairsptr) == -1)
exit(1);
}
else {
if (fsa_ip_minimize(geopairsptr) == -1)
exit(1);
}
if (kbm_print_level > 1)
printf(" #Number of states of first composite after minimisation = %d.\n",
geopairsptr->states->size);
/* write *geopairsptr and re-read to get dense storage type */
base_prefix(fsaname);
strcat(fsaname, ".near_geopairs");
wfile = fopen(outf5, "w");
fsa_print(wfile, geopairsptr, fsaname);
fclose(wfile);
fsa_clear(geopairsptr);
rfile = fopen(outf5, "r");
fsa_read(rfile, geopairsptr, DENSE, 0, 0, TRUE, fsaname);
fclose(rfile);
/* now compose result with tggp */
gpp =
fsa_composite(geopairsptr, tgpp, op_store2, TRUE, tempfilename, readback);
tfree(geopairsptr);
tfree(tgpp);
if (gpp == 0)
exit(1);
if (kbm_print_level > 1)
printf(" #Number of states of near geopairs before minimisation = %d.\n",
gpp->states->size);
/* write *gpp and re-read to get dense storage type */
/*
wfile = fopen(outf5,"w");
fsa_print(wfile,gpp,fsaname);
fclose(wfile);
fsa_clear(gpp);
rfile=fopen(outf5,"r");
fsa_read(rfile,gpp,DENSE,0,0,TRUE,fsaname);
fclose(rfile);
*/
/* Form the near geodesic word-difference machine */
/*
geodiffptr=fsa_diff(gpp,&rs_wd,op_store2);
base_prefix(fsaname);
strcat(fsaname,".near_geodiff");
wfile = fopen(outf6,"w");
fsa_print(wfile,geodiffptr,fsaname);
fclose(wfile);
if (kbm_print_level>0)
printf("#Geodesic difference machine with %d states computed.\n",
geodiffptr->states->size);
fsa_clear(geodiffptr);
tfree(geodiffptr);
*/
if (readback) {
if (fsa_minimize(gpp) == -1)
exit(1);
}
else {
if (fsa_ip_minimize(gpp) == -1)
exit(1);
}
if (kbm_print_level > 1)
printf(" #Number of states of near geopairs after minimisation = %d.\n",
gpp->states->size);
if (kbm_print_level > 0)
printf("#Geodesic near pairs machine with %d states computed.\n",
gpp->states->size);
wfile = fopen(outf5, "w");
fsa_print(wfile, gpp, fsaname);
fclose(wfile);
fsa_clear(gpp);
tfree(gpp);
fsa_clear(rs_wd.wd_fsa);
tfree(rs_wd.wd_fsa);
tfree(eqnptr);
exit(0);
}
void badusage(void)
{
fprintf(stderr,
"Usage: gpgeowa [-op1 d/s] [-op2 d/s] [-silent] [-v] [-l/-h] [-f]\n");
fprintf(stderr, " [-diff1/-diff2] [-me maxeqns] [-mwd maxwdiffs] "
"[-n] groupname\n");
exit(1);
}
¤ Dauer der Verarbeitung: 0.8 Sekunden
¤
*© Formatika GbR, Deutschland
|
|