gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnugo-devel] double dfas and prerotated dfas


From: Paul Pogonyshev
Subject: [gnugo-devel] double dfas and prerotated dfas
Date: Sun, 3 Aug 2003 03:20:22 +0000
User-agent: KMail/1.5.9

- added more robust handling of .dtr files
- removed option to build pre-rotated DFAs

i have implemented "double dfa" (a dfa with two transformations
of each patterns) only to find that there is nothing good in it.
it gave less than 1% speedup at the cost of 2.5 - 3 times dfa
size increase.  with computers becoming faster this will surely
be a disadvantage and eventually double dfa will be slower.

therefore i decided not to add another unused "feature" to gnu
go.  since prerotated dfas (dfas with all pattern transformation
included) are much worse (they are *huge* and most likely slower
than standard dfas), i removed the option to build them.  this
also simplified dfa matching code a bit.

this patch also introduces one feature: now .dtr files won't
become almost useless as quickly as they did.  i implemented a
more robust algorithm and removing/renaming a pattern from a dfa
database must no longer leed to severe increase in its size.

Paul


Index: engine/matchpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/matchpat.c,v
retrieving revision 1.57
diff -u -p -r1.57 matchpat.c
--- engine/matchpat.c   18 Jul 2003 18:59:21 -0000      1.57
+++ engine/matchpat.c   2 Aug 2003 23:59:58 -0000
@@ -886,11 +886,10 @@ dump_dfa_board(int m, int n)
 #endif
 
 
-/* 
- * Scan the board with a dfa to get 
- * all patterns matching at (m, n) with transformation l.
- * Store patterns indexes + transformation in pat_list.
- * Return the number of patterns found.
+/*
+ * Scan the board with a DFA to get all patterns matching at
+ * `dfa_pos' with transformation l.  Store patterns indexes
+ * `pat_list'.  Return the number of patterns found.
  */
 static int
 scan_for_patterns(dfa_rt_t *pdfa, int l, int *dfa_pos, int *pat_list)
@@ -898,8 +897,8 @@ scan_for_patterns(dfa_rt_t *pdfa, int l,
   int delta;
   int state = 1; /* initial state */
   int row = 0; /* initial row */
-  int id = 0; /* position in id_list */ 
-  
+  int id = 0; /* position in id_list */
+
   do {
     /* collect patterns indexes */
     int att = pdfa->states[state].att;
@@ -908,7 +907,7 @@ scan_for_patterns(dfa_rt_t *pdfa, int l,
       id++;
       att = pdfa->indexes[att].next;
     }
-      
+
     /* go to next state */
     delta = pdfa->states[state].next[dfa_pos[spiral[row][l]]];
     state += delta;
@@ -920,51 +919,49 @@ scan_for_patterns(dfa_rt_t *pdfa, int l,
 }
 
 
-/* Perform pattern matching with dfa filtering. */
-static void 
+/* Perform pattern matching with DFA filtering. */
+static void
 do_dfa_matchpat(dfa_rt_t *pdfa,
                int anchor, matchpat_callback_fn_ptr callback,
                int color, struct pattern *database,
                void *callback_data, char goal[BOARDMAX],
-                int anchor_in_goal)
+               int anchor_in_goal)
 {
-  int k = 0;
+  int k;
   int ll;      /* Iterate over transformations (rotations or reflections)  */
-  int patterns[DFA_MAX_MATCHED];
-  int *ll_patterns = patterns;
+  int patterns[DFA_MAX_MATCHED + 8];
   int num_matched = 0;
-  int num_transformations = (pdfa->pre_rotated ? 1 : 8);
-  int transformation_end[8];
   int *dfa_pos = dfa_p + DFA_POS(I(anchor), J(anchor)) + DFA_OFFSET;
 
   /* Basic sanity checks. */
   ASSERT_ON_BOARD1(anchor);
 
   /* One scan by transformation */
-  for (ll = 0; ll < num_transformations; ll++) {
-    int ll_matched = scan_for_patterns(pdfa, ll, dfa_pos,
-                                      patterns + num_matched);
-    
-    ll_patterns += ll_matched;
-    num_matched += ll_matched;
-    transformation_end[ll] = num_matched;
+  for (ll = 0; ll < 8; ll++) {
+    num_matched += scan_for_patterns(pdfa, ll, dfa_pos,
+                                    patterns + num_matched);
+    patterns[num_matched++] = -1;
   }
 
-  ASSERT1(num_matched <= DFA_MAX_MATCHED, anchor);
+  ASSERT1(num_matched <= DFA_MAX_MATCHED + 8, anchor);
 
   /* Constraints and other tests. */
-  for (ll = 0; ll < num_transformations; ll++) {
-    while (k < transformation_end[ll]) {
-      int matched = patterns[k];
+  for (ll = 0, k = 0; ll < 8; k++) {
+    int matched;
+
+    if (patterns[k] == -1) {
+      ll++;
+      continue;
+    }
+
+    matched = patterns[k];
 
 #if PROFILE_PATTERNS
-      database[matched].dfa_hits++;
+    database[matched].dfa_hits++;
 #endif
-    
-      check_pattern_light(anchor, callback, color, database + matched,
-                         ll, callback_data, goal, anchor_in_goal);
-      k++;
-    }
+
+    check_pattern_light(anchor, callback, color, database + matched,
+                       ll, callback_data, goal, anchor_in_goal);
   }
 }
 
Index: patterns/dfa.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/dfa.c,v
retrieving revision 1.32
diff -u -p -r1.32 dfa.c
--- patterns/dfa.c      18 Jul 2003 18:59:22 -0000      1.32
+++ patterns/dfa.c      3 Aug 2003 00:00:03 -0000
@@ -576,11 +576,9 @@ print_c_dfa(FILE *of, const char *name, 
 
   fprintf(of, "static dfa_rt_t dfa_%s = {\n", name);
   fprintf(of, " \"%s\",\n", name);
-  fprintf(of, " %d,\n", pdfa->pre_rotated);
   fprintf(of, "state_%s,\n", name);
   fprintf(of, "idx_%s", name);
   fprintf(of, "};\n");
-
 }
 
 
@@ -1057,9 +1055,6 @@ dfa_add_string(dfa_t *pdfa, const char *
   assert(dfa_was_initialized > 0);
   assert(pdfa != NULL);
 
-  if (pdfa->pre_rotated)
-    pattern_index = pattern_index * 8 + ll;
-
   create_dfa(&aux_temp, str, pattern_index);
 
   /* then we do the synchronization product with dfa */
@@ -1285,12 +1280,12 @@ pattern_2_string(struct pattern *pat, st
 
 
 /**************************************
- *     Experimental dfa builder      *
+ *     Experimental DFA builder      *
  **************************************/
 
 /* This builder differs from the one above in that it builds the whole dfa
  * at once. That is, it must have all the patterns to build and cannot add
- * pattern by pattern. Currently, it is only used in dfa size optimization
+ * pattern by pattern. Currently, it is only used in DFA size optimization
  * (it seems to be significantly faster).
  */
 
@@ -1359,7 +1354,7 @@ dfa_attrib_array_clear(dfa_attrib_array 
 }
 
 
-/* Allocate a new dfa_node structure in a dfa graph. */
+/* Allocate a new dfa_node structure in a DFA graph. */
 static dfa_node *
 dfa_node_new(dfa_graph *graph)
 {
@@ -1382,7 +1377,7 @@ dfa_node_new(dfa_graph *graph)
 }
 
 
-/* This is a hash table used to quickly find a dfa node using a linked list
+/* This is a hash table used to quickly find a DFA node using a linked list
  * of its attributes as a key.
  */
 static dfa_hash_entry *dfa_hash_table[DFA_HASH_TABLE_SIZE];
@@ -1490,7 +1485,7 @@ dfa_hash_add_node(dfa_node *node)
 }
 
 
-/* Dfa iterator. Used to walk the array of nodes in backward direction. */
+/* DFA iterator. Used to walk the array of nodes in backward direction. */
 static dfa_node_block *dfa_iterator_block;
 static int dfa_iterator_node_num;
 
@@ -1545,7 +1540,7 @@ dfa_graph_reset(dfa_graph *graph)
 }
 
 
-/* Free all resources associated with the specified dfa graph. */
+/* Free all resources associated with the specified DFA graph. */
 static void
 dfa_graph_clear(dfa_graph *graph)
 {
@@ -1634,7 +1629,7 @@ dfa_graph_build_level(dfa_graph *graph, 
       else {
        /* If the string ends at this level, add its index to the list of
         * matched strings of the current node. Not used at the moment,
-        * since this builder isn't used for actual dfa building.
+        * since this builder isn't used for actual DFA building.
         */
        *link = dfa_attrib_new(&(graph->attributes), index);
        link = &((*link)->next);
@@ -1676,9 +1671,9 @@ dfa_graph_build_level(dfa_graph *graph, 
 
        dfa_hash_add_node(new_node);
       }
- 
+
       /* At this moment we convert the masks to actual transitions. These are
-       * also unused till we use this builder for actual dfa creation.
+       * also unused till we use this builder for actual DFA creation.
        */
       for (i = 0; i < 4; i++) {
        if (mask[k] & (1 << i))
@@ -1688,7 +1683,7 @@ dfa_graph_build_level(dfa_graph *graph, 
   }
 
   /* Free the lists of passing strings for the previous level. Useful if we
-   * building an exceptionally huge dfa (e.g. a pre-rotated one).
+   * building an exceptionally huge DFA.
    */
   dfa_attrib_array_partially_clear(cutoff_point);
 
@@ -1809,7 +1804,7 @@ dfa_patterns_add_pattern(dfa_patterns *p
 }
 
 
-/* Set the variation of the last pattern. Can be used in actual dfa building
+/* Set the variation of the last pattern. Can be used in actual DFA building
  * or to set a hint (results of the previous optimization) for optimization.
  */
 void
@@ -1823,7 +1818,7 @@ dfa_patterns_set_last_pattern_variation(
 
 
 /* Make the shortest variation of the last pattern its current variation. It
- * is used as a starting point in dfa optimization process.
+ * is used as a starting point in DFA optimization process.
  */
 void
 dfa_patterns_select_shortest_variation(dfa_patterns *patterns)
@@ -1846,7 +1841,7 @@ dfa_patterns_select_shortest_variation(d
 }
 
 
-/* Build a dfa graph for a list of patterns. */
+/* Build a DFA graph for a list of patterns. */
 void
 dfa_patterns_build_graph(dfa_patterns *patterns)
 {
@@ -1889,7 +1884,7 @@ dfa_patterns_build_graph(dfa_patterns *p
 }
 
 
-/* dfa_patterns_optimize_variations() tries to reduce the size of dfa by
+/* dfa_patterns_optimize_variations() tries to reduce the size of DFA by
  * altering pattern variations (in fact, transformations). The algorithm
  * is to change several patterns' variations and if this happens to give
  * size reduction, to keep the change, otherwise, revert.
@@ -1923,7 +1918,7 @@ dfa_patterns_optimize_variations(dfa_pat
   num_nodes_original = patterns->graph.num_nodes;
   min_nodes_so_far = num_nodes_original;
 
-  fprintf(stderr, "Original number of dfa states: %d\n", min_nodes_so_far - 1);
+  fprintf(stderr, "Original number of DFA states: %d\n", min_nodes_so_far - 1);
   fprintf(stderr, "Trying to optimize in %d iterations\n", iterations);
 
   gg_srand(num_nodes_original + patterns->num_patterns);
@@ -1934,7 +1929,7 @@ dfa_patterns_optimize_variations(dfa_pat
     
     /* Randomly change some variations. */
     for (pattern = patterns->patterns; pattern; pattern = pattern->next, k++) {
-      if (gg_drand() < change_probability && pattern->num_variations != 1) {
+      if (gg_drand() < change_probability && pattern->num_variations > 1) {
        int new_variation = gg_rand() % (pattern->num_variations - 1);
        if (new_variation >= pattern->current_variation)
          new_variation++;
Index: patterns/dfa.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/dfa.h,v
retrieving revision 1.24
diff -u -p -r1.24 dfa.h
--- patterns/dfa.h      18 Jul 2003 18:59:22 -0000      1.24
+++ patterns/dfa.h      3 Aug 2003 00:00:04 -0000
@@ -79,8 +79,7 @@ typedef struct dfa
 {
   /* file header */
   char name[80];
-  int pre_rotated;
-  
+
   /* transition graph */
   state_t *states;
   int max_states;
@@ -114,8 +113,7 @@ typedef struct dfa_rt
 {
   /* file header */
   const char name[80];
-  const int pre_rotated;
-  
+
   /* transition graph */
   const state_rt_t *states;
 
Index: patterns/mkpat.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
retrieving revision 1.123
diff -u -p -r1.123 mkpat.c
--- patterns/mkpat.c    18 Jul 2003 18:59:22 -0000      1.123
+++ patterns/mkpat.c    3 Aug 2003 00:00:14 -0000
@@ -48,26 +48,25 @@ Usage : mkpat [options] <prefix>\n\
   General options:\n\
        -i = one or more input files (typically *.db)\n\
        -o = output file (typically *.c)\n\
-       -t = dfa transformations file (typically *.dtr)\n\
+       -t = DFA transformations file (typically *.dtr)\n\
        -v = verbose\n\
-       -V <level> = dfa verbiage level\n\
+       -V <level> = DFA verbiage level\n\
   Database type:\n\
        -p = compile general pattern database (the default)\n\
        -c = compile connections database\n\
        -f = compile a fullboard pattern database\n\
        -C = compile a corner pattern database\n\
-       -D = compile a dfa database (allows fast matching)\n\
+       -D = compile a DFA database (allows fast matching)\n\
        -T = compile a tree based pattern database (even faster)\n\
-       -d <iterations> = don't generate database, but optimize a dfa\n\
+       -d <iterations> = don't generate database, but optimize a DFA\n\
                          transformation file instead\n\
   Pattern generation options:\n\
        -O = allow only O to be anchor (the default)\n\
        -X = allow only X to be anchor\n\
        -b = allow both colors to be anchor\n\
        -m = try to place the anchor in the center of the pattern\n\
-            (works best with dfa databases)\n\
+            (works best with DFA databases)\n\
        -a = require anchor in all patterns. Sets fixed_anchor flag in db\n\
-       -r = pre-rotate patterns before storing in database (dfa only)\n\
 If no input files specified, reads from stdin.\n\
 If output file is not specified, writes to stdout.\n\
 "
@@ -106,13 +105,14 @@ If output file is not specified, writes 
 #define ANCHOR_X    ATT_X
 #define ANCHOR_BOTH (ATT_O | ATT_X)
 
-#define MAXLINE 500
-#define MAXCONSTRAINT 10000
-#define MAXACTION 10000
-#define MAXPATNO 5000
-#define MAXLABELS 20
-#define MAXPARAMS 15
-#define MAX_INPUT_FILE_NAMES 10
+#define MAXLINE                        500
+#define MAXCONSTRAINT          10000
+#define MAXACTION              10000
+#define MAXPATNO               5000
+#define MAXLABELS              20
+#define MAXPARAMS              15
+#define MAX_INPUT_FILE_NAMES   10
+#define MAXNAME                        80
 
 /* Avoid compiler warnings with unused parameters */
 #define UNUSED(x)  (void)x
@@ -172,10 +172,10 @@ static char constraint_diagram[MAX_BOARD
 /* stuff to maintain info about patterns while reading */
 static char *prefix;
 static struct pattern pattern[MAXPATNO]; /* accumulate the patterns into here 
*/
-static char pattern_names[MAXPATNO][80]; /* with optional names here, */
-static char helper_fn_names[MAXPATNO][80]; /* helper fn names here */
+static char pattern_names[MAXPATNO][MAXNAME]; /* with optional names here, */
+static char helper_fn_names[MAXPATNO][MAXNAME]; /* helper fn names here */
 static char autohelper_code[MAXPATNO*300]; /* code for automatically generated 
*/
-                                    /* helper functions here */
+                                          /* helper functions here */
 static char *code_pos;              /* current position in code buffer */
 struct autohelper_func {
   const char *name;
@@ -195,6 +195,7 @@ struct autohelper_func {
 static const char *current_file = NULL;
 static int current_line_number = 0;
 
+
 /* ================================================================ */
 /*                                                                  */
 /*                Autohelper function definitions                   */
@@ -423,12 +424,58 @@ static int choose_best_anchor = 0;  /* -
  *       checks for anchor validity.
  */
 static int fixed_anchor = 0;        /* -a */
-static int pre_rotate = 0;          /* -p */
 
 static dfa_t dfa;
 static dfa_patterns dfa_pats;
 
-static int transformation_hint = 0;
+static int transformation_hint;
+
+
+struct hint_data {
+  char             name[MAXNAME];
+  int              transformation_hint;
+  struct hint_data  *next;
+};
+
+static struct hint_data *first_hint = NULL;
+
+
+static void
+parse_transformations_file(FILE *file)
+{
+  struct hint_data **link = &first_hint;
+
+  while (!feof(file)) {
+    int n;
+    struct hint_data *hint = malloc(sizeof(struct hint_data));
+
+    n = fscanf(file, "%s %d", hint->name, &hint->transformation_hint);
+    if (n == 2) {
+      hint->next = NULL;
+      *link = hint;
+      link = &hint->next;
+    }
+    else
+      free(hint);
+  }
+}
+
+
+static int
+find_transformation_hint(const char *pattern_name)
+{
+  struct hint_data *hint;
+
+  if (database_type == DB_DFA || database_type == OPTIMIZE_DFA) {
+    for (hint = first_hint; hint; hint = hint->next) {
+      if (!strcmp(hint->name, pattern_name))
+       return hint->transformation_hint;
+    }
+  }
+
+  return database_type == OPTIMIZE_DFA ? -1 : 0;
+}
+
 
 /**************************
  *
@@ -566,16 +613,12 @@ static void
 write_to_dfa(int index)
 {
   char str[MAX_ORDER + 1], strrot[MAX_ORDER + 1];
-  float ratio;
-  int ll;
-  int rot_start = 0;
-  int rot_stop = 1;
-  
+
   assert(ci != -1 && cj != -1);
 #if 0
   pattern[index].patn = elements; /* a little modification : keep in touch! */
 #endif
-  pattern[index].name = &(pattern_names[index][0]); 
+  pattern[index].name = &(pattern_names[index][0]);
 
   /* First we create the string from the actual pattern. */
   pattern_2_string(pattern + index, elements, str, ci, cj);
@@ -583,47 +626,45 @@ write_to_dfa(int index)
   if (verbose)
     fprintf(stderr, "Add   :%s\n", pattern[index].name);
 
-  if (pre_rotate || database_type == OPTIMIZE_DFA) {
-    if (pattern[index].trfno != 5)
-      rot_stop = pattern[index].trfno;
-    else {
-      rot_start = 2;
-      rot_stop = 6;
+  if (database_type == DB_DFA) {
+    float ratio;
+
+    dfa_rotate_string(strrot, str, transformation_hint);
+    ratio = ((dfa_add_string(&dfa, strrot, index, transformation_hint) - 1.0)
+            * 100);
+
+    /* Complain when there is more than 10% of increase */
+    if (dfa_size(&dfa) > 100 && ratio > 10.0) {
+      fprintf(stderr, "Pattern %s => %3.1f%% increase: ",
+             pattern[index].name, ratio);
+      fprintf(stderr, "another orientation may save memory.\n");
     }
+    if (dfa_verbose > 2)
+      dump_dfa(stderr, &dfa);
   }
   else {
-    rot_start = transformation_hint;
-    rot_stop = transformation_hint + 1;
-  }
+    int ll;
+    int rot_start = 0;
+    int rot_stop = pattern[index].trfno;
 
-  for (ll = rot_start; ll < rot_stop; ll++) {
-    /* Create appropriate transformation of `str'. */
-    dfa_rotate_string(strrot, str, ll);
-
-    if (database_type != OPTIMIZE_DFA) {
-      /* Then We add this string to the DFA */
-      ratio = (dfa_add_string(&dfa, strrot, index, ll) - 1)*100;
-
-      /* Complain when there is more than 10% of increase */ 
-      if (dfa_size(&dfa) > 100 && ratio > 10.0) {
-       fprintf(stderr, "Pattern %s => %3.1f%% increase: ",
-               pattern[index].name, ratio);
-       fprintf(stderr, "another orientation may save memory.\n");
-      }
-      if (dfa_verbose > 2)
-       dump_dfa(stderr, &dfa);
+    assert(database_type == OPTIMIZE_DFA);
+
+    if (rot_stop == 5) {
+      rot_start = 2;
+      rot_stop = 6;
     }
-    else
+
+    for (ll = rot_start; ll < rot_stop; ll++) {
+      dfa_rotate_string(strrot, str, ll);
       dfa_patterns_add_pattern(&dfa_pats, strrot, index);
-  }
+    }
 
-  if (database_type == OPTIMIZE_DFA) {
     if (transformation_hint == -1)
       dfa_patterns_select_shortest_variation(&dfa_pats);
-    else if (pattern[index].trfno != 5)
-      dfa_patterns_set_last_pattern_variation(&dfa_pats, transformation_hint);
-    else
-      dfa_patterns_set_last_pattern_variation(&dfa_pats, transformation_hint - 
2);
+    else {
+      dfa_patterns_set_last_pattern_variation(&dfa_pats, (transformation_hint
+                                                         - rot_start));
+    }
   }
 }
 
@@ -659,6 +700,7 @@ compute_grids(void)
       TRANSFORM2(elements[k].x - ci, elements[k].y - cj, &ti, &tj,
                 transformation_hint);
       TRANSFORM2(ti, tj, &di, &dj, ll);
+
       ++di;
       ++dj;
       if (di >= 0 && di < 4 && dj >= 0 && dj < 4) {
@@ -1207,8 +1249,6 @@ finish_pattern(char *line)
              "%s(%d) : Warning : symmetry inconsistent with edge constraints 
(pattern %s)\n",
              current_file, current_line_number, pattern_names[patno]);
     pattern[patno].trfno = 5;  /* Ugly special convention. */
-    if (database_type == DB_DFA)
-      transformation_hint += 2;
     break;
 
   default:
@@ -2605,16 +2645,6 @@ write_patterns(FILE *outfile)
      * the pattern, relative to the pattern origin. These just transform same
      * as the elements.
      */
-    if (transformation_hint == 1 || transformation_hint == 3
-       || transformation_hint == 4 || transformation_hint == 6) {
-      int temp = p->mini;
-      p->mini = p->minj;
-      p->minj = temp;
-      temp = p->maxi;
-      p->maxi = p->maxj;
-      p->maxj = temp;
-    }
-    
     fprintf(outfile, "  {%s%d,%d,%d, \"%s\",%d,%d,%d,%d,%d,%d,0x%x,%d",
            prefix, j,
            p->patlen,
@@ -2751,7 +2781,7 @@ main(int argc, char *argv[])
     int multiple_anchor_options = 0;
 
     /* Parse command-line options */
-    while ((i = gg_getopt(argc, argv, "i:o:t:vV:pcfCDTd:OXbmar")) != EOF) {
+    while ((i = gg_getopt(argc, argv, "i:o:t:vV:pcfCDTd:A:OXbma")) != EOF) {
       switch (i) {
       case 'i': 
        if (input_files == MAX_INPUT_FILE_NAMES) {
@@ -2780,8 +2810,13 @@ main(int argc, char *argv[])
          return 1;
        }
        database_type = i;
-       if (i == 'd')
+       if (i == 'd') {
          iterations = strtol(gg_optarg, NULL, 10);
+         if (iterations < 0) {
+           fprintf(stderr, "Error : Expected a non-negative number of 
iterations\n");
+           return 1;
+         }
+       }
 
 #if EXPERIMENTAL_READING == 0
        if (i == 'T') {
@@ -2808,18 +2843,16 @@ main(int argc, char *argv[])
        anchor = ANCHOR_BOTH;
        break;
 
-      case 'm': 
-        choose_best_anchor = 1;
-        if (fixed_anchor)
-          fprintf(stderr, "Warning : -m and -a are mutually exclusive.\n");
+      case 'm':
+       choose_best_anchor = 1;
+       if (fixed_anchor)
+         fprintf(stderr, "Warning : -m and -a are mutually exclusive.\n");
+       break;
+      case 'a':
+       fixed_anchor = 1;
+       if (choose_best_anchor)
+         fprintf(stderr, "Warning : -m and -a are mutually exclusive.\n");
        break;
-      case 'a': 
-        fixed_anchor = 1; 
-        if (choose_best_anchor)
-          fprintf(stderr, "Warning : -m and -a are mutually exclusive.\n");
-        break;
-
-      case 'r': pre_rotate = 1; break;
 
       default:
        fprintf(stderr, "\b ; ignored\n");
@@ -2843,7 +2876,11 @@ main(int argc, char *argv[])
     if (transformations_file_name
        && (database_type == DB_DFA || database_type == OPTIMIZE_DFA)) {
       transformations_FILE = fopen(transformations_file_name, "r");
-      if (transformations_FILE == NULL && database_type == DB_DFA) {
+      if (transformations_FILE) {
+       parse_transformations_file(transformations_FILE);
+       fclose(transformations_FILE);
+      }
+      else if (database_type == DB_DFA) {
        fprintf(stderr, "Error : Cannot read file %s\n",
                transformations_file_name);
        return 1;
@@ -2864,7 +2901,6 @@ main(int argc, char *argv[])
   if (database_type == DB_DFA) {
     dfa_init();
     new_dfa(&dfa, "mkpat's dfa");
-    dfa.pre_rotated = pre_rotate;
   }
 
   if (database_type == DB_CORNER)
@@ -2909,9 +2945,6 @@ main(int argc, char *argv[])
 
   for (ifc = 0; ifc < input_files && !fatal_errors; ifc++) {
     char line[MAXLINE];  /* current line from file */
-    int have_pending_name = 0;
-    char pending_name[MAXLINE];
-    int pending_transformation;
 
     if (input_file_names[ifc] != stdin_name) {
       input_FILE = fopen(input_file_names[ifc], "r");
@@ -2993,30 +3026,14 @@ main(int argc, char *argv[])
            code_pos = save_code_pos;
          reset_pattern();
 
-         if (strlen(command_data) > 79) {
+         if (strlen(command_data) > MAXNAME - 1) {
            fprintf(stderr, "%s(%d) : Warning : pattern name is too long, 
truncated\n",
                    current_file, current_line_number);
-           command_data[79] = 0;
+           command_data[MAXNAME - 1] = 0;
          }
          strcpy(pattern_names[patno], command_data);
 
-         /* Special case. Choose shortest transformation later. */
-         if (database_type == OPTIMIZE_DFA)
-           transformation_hint = -1;
-
-         if (transformations_FILE) {
-           if (!have_pending_name && !feof(transformations_FILE)) {
-             fscanf(transformations_FILE, "%s %d", pending_name,
-                    &pending_transformation);
-             have_pending_name = 1;
-           }
-
-           transformation_hint = 0;
-           if (have_pending_name && !strcmp(pending_name, command_data)) {
-             transformation_hint = pending_transformation;
-             have_pending_name = 0;
-           }
-         }
+         transformation_hint = find_transformation_hint(pattern_names[patno]);
 
          state = 1;
          discard_pattern = 0;
@@ -3222,13 +3239,10 @@ main(int argc, char *argv[])
       dfa_finalize(&dfa);
       dfa_shuffle(&dfa);
 
-      fprintf(stderr, "dfa for %s\n", prefix);
+      fprintf(stderr, "DFA for %s\n", prefix);
       fprintf(stderr, "size: %d kB for ", dfa_size(&dfa));
       fprintf(stderr, "%d patterns", patno);
-      fprintf(stderr, "(%d states)\n", dfa.last_state);
-
-      if (0 && dfa.pre_rotated)
-       dump_dfa(stderr, &dfa);
+      fprintf(stderr, " (%d states)\n", dfa.last_state);
 
       strcpy(dfa.name, prefix);
       print_c_dfa(output_FILE, prefix, &dfa);
@@ -3266,8 +3280,6 @@ main(int argc, char *argv[])
     int k;
     int *optimized_variations;
 
-    if (transformations_FILE)
-      fclose(transformations_FILE);
     transformations_FILE = fopen(transformations_file_name, "wb");
     if (transformations_FILE == NULL) {
       fprintf(stderr, "error : cannot write to file %s\n",
@@ -3295,4 +3308,3 @@ main(int argc, char *argv[])
  * c-basic-offset: 2
  * End:
  */
-




reply via email to

[Prev in Thread] Current Thread [Next in Thread]