Ticket #25: gunnar_7_7.1.diff

File gunnar_7_7.1.diff, 49.8 KB (added by gunnar, 6 years ago)

gunnar_7_7.1, removal of EXPERIMENTAL_READING and "tree" pattern matcher

Line 
1Index: configure.in
2===================================================================
3RCS file: /cvsroot/gnugo/gnugo/configure.in,v
4retrieving revision 1.122
5diff -u -r1.122 configure.in
6--- configure.in        21 Sep 2005 22:06:50 -0000      1.122
7+++ configure.in        23 Sep 2005 22:26:56 -0000
8@@ -100,10 +100,6 @@
9  [  --enable-experimental-owl-ext      use the experimental GAIN/LOSS codes
10   --disable-experimental-owl-ext     use standard owl module (default)])
11 
12-AC_ARG_ENABLE(experimental-reading,
13- [  --enable-experimental-reading      use experimental pattern-based reading
14-  --disable-experimental-reading     use standard reading (default)])
15-
16 AC_ARG_ENABLE(cosmic-gnugo,
17  [  --enable-cosmic-gnugo              use center-oriented influence code
18   --disable-cosmic-gnugo             use standard influence code (default)])
19@@ -467,17 +463,6 @@
20    AC_DEFINE(EXPERIMENTAL_OWL_EXT, 1)
21 else
22    AC_DEFINE(EXPERIMENTAL_OWL_EXT, 0)
23-fi
24-
25-dnl ------------ Reading -------------------
26-
27-AH_TEMPLATE([EXPERIMENTAL_READING],
28-[Experimental pattern based reading. Disabled by default.])
29-
30-if test "$enable_experimental_reading" = "yes" ; then
31-   AC_DEFINE(EXPERIMENTAL_READING, 1)
32-else
33-   AC_DEFINE(EXPERIMENTAL_READING, 0)
34 fi
35 
36 dnl ------------ Cosmic Consciousness -------------------
37Index: engine/gnugo.h
38===================================================================
39RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
40retrieving revision 1.119
41diff -u -r1.119 gnugo.h
42--- engine/gnugo.h      12 Jun 2005 09:34:14 -0000      1.119
43+++ engine/gnugo.h      23 Sep 2005 22:26:56 -0000
44@@ -238,11 +238,6 @@
45 extern int mirror_stones_limit;      /* but stop at this number of stones */
46 extern int gtp_version;              /* version of Go Text Protocol */
47 
48-#if EXPERIMENTAL_READING
49-extern int defend_by_pattern;  /* use patterns for tactical reading defense */
50-extern int attack_by_pattern;  /* use patterns for tactical reading attack */
51-#endif
52-
53 /* Mandatory values of reading parameters. Normally -1, if set at
54  * these override the values derived from the level. */
55 extern int mandated_depth;
56Index: engine/interface.c
57===================================================================
58RCS file: /cvsroot/gnugo/gnugo/engine/interface.c,v
59retrieving revision 1.54
60diff -u -r1.54 interface.c
61--- engine/interface.c  14 Sep 2005 18:33:20 -0000      1.54
62+++ engine/interface.c  23 Sep 2005 22:26:57 -0000
63@@ -51,9 +51,6 @@
64 
65   transformation_init();
66   dfa_match_init();
67-#if EXPERIMENTAL_READING
68-  tree_match_init();
69-#endif
70 
71   clear_approxlib_cache();
72   clear_accuratelib_cache();
73Index: engine/liberty.h
74===================================================================
75RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
76retrieving revision 1.238
77diff -u -r1.238 liberty.h
78--- engine/liberty.h    12 Jun 2005 09:34:14 -0000      1.238
79+++ engine/liberty.h    23 Sep 2005 22:26:57 -0000
80@@ -175,8 +175,6 @@
81 struct corner_db;
82 struct half_eye_data;
83 struct movelist;
84-struct tree_node_list;
85-struct match_node;
86 
87 /*
88  * Try to match a pattern in the database to the board. Callbacks for
89@@ -203,11 +201,6 @@
90 void corner_matchpat(corner_matchpat_callback_fn_ptr callback, int color,
91                     struct corner_db *database);
92 void dfa_match_init(void);
93-void tree_match_init(void);
94-void tree_initialize_pointers(struct tree_node_list *tnl,
95-                              struct match_node *matches,
96-                              int tnl_size,
97-                              int matches_size);
98 
99 void reading_cache_init(int bytes);
100 void reading_cache_clear(void);
101Index: engine/matchpat.c
102===================================================================
103RCS file: /cvsroot/gnugo/gnugo/engine/matchpat.c,v
104retrieving revision 1.70
105diff -u -r1.70 matchpat.c
106--- engine/matchpat.c   14 Sep 2005 18:33:20 -0000      1.70
107+++ engine/matchpat.c   23 Sep 2005 22:26:57 -0000
108@@ -520,195 +520,6 @@
109   }
110 }
111 
112-#if EXPERIMENTAL_READING
113-
114-/**************************************************************************/
115-/* Tree matcher:                                                           */
116-/**************************************************************************/
117-static void tree_prepare_for_match(int color);
118-static void tree_matchpat_loop(matchpat_callback_fn_ptr callback,
119-                              int color, int anchor,
120-                              struct pattern_db *pdb, void *callback_data,
121-                              char goal[BOARDMAX], int anchor_in_goal);
122-static void tree_do_matchpat(int m, int n, matchpat_callback_fn_ptr callback,
123-                            int color, struct pattern_db *database,
124-                            void *callback_data, char goal[BOARDMAX],
125-                             int anchor_in_goal);
126-
127-
128-void
129-tree_match_init(void)
130-{
131-  init_tree_read_attack();
132-  init_tree_read_defend();
133-  init_tree_owl_attackpat();
134-  init_tree_owl_defendpat();
135-  init_tree_owl_vital_apat();
136-}
137-
138-
139-static void
140-tree_prepare_for_match(int color)
141-{
142-  UNUSED(color);
143-  /* Nothing to prepare! */
144-}
145-
146-static void
147-tree_matchpat_loop(matchpat_callback_fn_ptr callback,
148-                  int color, int anchor,
149-                  struct pattern_db *pdb, void *callback_data,
150-                  char goal[BOARDMAX], int anchor_in_goal)
151-{
152-  int i, j;
153-
154-  for (i = 0; i != board_size; i++)
155-    for (j = 0; j != board_size; j++)
156-      if (BOARD(i, j) == anchor
157-          && (!anchor_in_goal || goal[POS(i, j)] != 0))
158-       tree_do_matchpat(i, j, callback, color,
159-                        pdb, callback_data, goal, anchor_in_goal);
160-
161-}
162-
163-/* Possibly cheaper to pass a little less recursively.
164- * Note: This could even just be static data, unless the
165- * tree pattern matcher is itself used recursively.*/
166-struct rec_data {
167-  matchpat_callback_fn_ptr callback;
168-  struct pattern_db *database;
169-  void *callback_data;
170-};
171-
172-
173-/* Recursively walks the tree data structure, calling the callback
174- * for all patterns matched at location (m,n).
175- */
176-static void
177-do_tree_matchpat_rec(int color, int m, int n, int goal_found,
178-                     char goal[BOARDMAX],
179-                     struct tree_node_list *tnl,
180-                     struct rec_data *pdata)
181-{
182-  if (0 && !tnl)
183-    return;
184-
185-  tnl = tnl->next;
186-  while (tnl) {
187-    struct tree_node *node = &(tnl->node);
188-    int x = m + node->x;
189-    int y = n + node->y;
190-    if (ON_BOARD2(x, y)) {
191-      int att = node->att;
192-      int point_color = BOARD(x, y);
193-      if ((att == EMPTY && point_color == EMPTY)
194-          || (att == ATT_X && point_color == OTHER_COLOR(color))
195-          || (att == ATT_O && point_color == color)) {
196-        goal_found = goal_found || goal[POS(x, y)];
197-        if (node->matches) {
198-          struct match_node *match = node->matches->next;
199-          while (match) {
200-            struct pattern *pattern =
201-             &(pdata->database->patterns[match->patnum]);
202-            int ll = match->orientation;
203-           int mi, mj, xi, xj;
204-           TRANSFORM2(pattern->mini, pattern->minj, &mi, &mj, ll);
205-           TRANSFORM2(pattern->maxi, pattern->maxj, &xi, &xj, ll);
206-           /* now do the range-check */
207-            if (!goal_found
208-                || !ON_BOARD2(m+mi, n+mj)
209-                || !ON_BOARD2(m+xi, n+xj)) {
210-             ;/* goal not found, or out of range */
211-            }
212-           else {
213-              if (0) {
214-                gprintf("  P[%s, %d] matches at %m)\n",
215-                       pattern->name, match->orientation, x, y);
216-              }
217-              /* A match! */
218-              pdata->callback(POS(m, n), color, pattern, ll,
219-                             pdata->callback_data);
220-            }
221-
222-            match = match->next;
223-          }
224-        }
225-        if (node->next_list && node->next_list->next) {
226-          do_tree_matchpat_rec(color, m, n, goal_found, goal,
227-                              node->next_list, pdata);
228-        }
229-      }
230-    }
231-    tnl = tnl->next;
232-  }
233-}
234-
235-/* Stub for matchpat function.  Work done in recursive helper. */
236-static void
237-tree_do_matchpat(int m, int n, matchpat_callback_fn_ptr callback,
238-                int color, struct pattern_db *database,
239-                void *callback_data, char goal[BOARDMAX],
240-                int anchor_in_goal)
241-{
242-  struct tree_node_list *tree = database->tnl;
243-  struct rec_data data;
244-
245-  if (0) {
246-    if (0)
247-      showboard(0);
248-    gprintf("Trying to match at %m\n", m, n);
249-  }
250-  data.callback = callback;
251-  data.callback_data = callback_data;
252-  data.database = database;
253-
254-  /* note: If anchor_in_goal is 0, then the goal_found parameter is
255-   *   always trivially true.  This will short-circuit some array
256-   *   lookups in the recursive version.
257-   */
258-  do_tree_matchpat_rec(color, m, n, !anchor_in_goal, goal, tree, &data);
259-}
260-
261-/**************************************************************************/
262-/* Tree initialization helper                                             */
263-/**************************************************************************/
264-
265-/* The tree data structure is output with raw integer offsets
266- * relative to a single array of tree_node_list and match_node
267- * elements.  These offsets need to be added to the actual base
268- * address of the list of elements for the pointers to be
269- * meaningful.
270- *
271- * FIXME: This code is not portable. On certain platforms the size of
272- *        a pointer and the size of an int differ.
273- */
274-void
275-tree_initialize_pointers(struct tree_node_list *tnl,
276-                         struct match_node *matches,
277-                         int tnl_size,
278-                         int matches_size)
279-{
280-  struct tree_node_list *tnl_walk = tnl;
281-  struct match_node *matches_walk = matches;
282-
283-  do {
284-    if (tnl_walk->next)
285-      tnl_walk->next = tnl + (int)(tnl_walk->next);
286-    if (tnl_walk->node.matches)
287-      tnl_walk->node.matches = matches + (int)(tnl_walk->node.matches);
288-    if (tnl_walk->node.next_list)
289-      tnl_walk->node.next_list = tnl + (int)(tnl_walk->node.next_list);
290-  } while (++tnl_walk < tnl + tnl_size);
291-
292-
293-  do {
294-    if (matches_walk->next)
295-      matches_walk->next = matches + (int)(matches_walk->next);
296-  } while (++matches_walk < matches + matches_size); 
297-}
298-
299-#endif
300-
301 
302 /**************************************************************************/
303 /* DFA matcher:                                                           */
304@@ -1066,13 +877,6 @@
305     loop = dfa_matchpat_loop;
306     prepare = dfa_prepare_for_match;
307   }
308-
309-#if EXPERIMENTAL_READING
310-  if (pdb->tnl) {
311-    loop = tree_matchpat_loop;
312-    prepare = tree_prepare_for_match;
313-  }
314-#endif
315 
316   /* select strategy */
317   switch (color) {
318Index: engine/reading.c
319===================================================================
320RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
321retrieving revision 1.160
322diff -u -r1.160 reading.c
323--- engine/reading.c    9 Sep 2005 21:56:01 -0000       1.160
324+++ engine/reading.c    23 Sep 2005 22:26:59 -0000
325@@ -29,7 +29,6 @@
326 
327 #include "liberty.h"
328 #include "cache.h"
329-#include "patterns.h"
330 #include "gg_utils.h"
331 
332 /* If nonzero, attack() and find_defense() write all results to
333@@ -51,18 +50,6 @@
334 #define DUMP_ALL_RESULTS       0
335 
336 
337-#if EXPERIMENTAL_READING
338-
339-/* When to use pattern-base reading */
340-int defend_by_pattern = 0;
341-int attack_by_pattern = 1;
342-
343-static int do_tactical_pat(int is_attack, int str, int *move);
344-static int do_defend_pat(int str, int *move);
345-static int do_attack_pat(int str, int *move);
346-
347-#endif
348-
349 /* Size of array where candidate moves are stored. */
350 #define MAX_MOVES 50
351 
352@@ -1207,14 +1194,6 @@
353     return retval;
354   }
355 
356-#if EXPERIMENTAL_READING
357-  if (defend_by_pattern) {
358-    dcode = do_defend_pat(str, &xpos);
359-    /* We set liberties to 0 to pass over the non-pattern code below. */
360-    liberties = 0;
361-  }
362-#endif
363-
364   if (liberties == 1)
365     dcode = defend1(str, &xpos);
366   else if (liberties == 2)
367@@ -2798,417 +2777,6 @@
368 /*                       Attacking functions                        */
369 /* ================================================================ */
370 
371-/* FIXME: These two globals should be wrapped up in accessors, at least. */
372-char *rgoal;
373-int goallib;
374-
375-#if EXPERIMENTAL_READING
376-#define MAX_READING_MOVES 99
377-struct reading_move_data {
378-  int pos;          /* move coordinate */
379-  int value;        /* value */
380-  const char *name; /* name of the pattern suggesting the move */
381-};
382-
383-
384-/* reading_callback helper
385- * returns 1 if the move need not be tried, because there's
386- * already a move in the collected list with a higher value.
387- */
388-static int
389-r_scan_moves(int move, int value, struct reading_move_data *moves)
390-{
391-  int k;
392-  for (k = 0; k < MAX_READING_MOVES; k++) {
393-    if (moves[k].pos == NO_MOVE)
394-      break;
395-   
396-    if (moves[k].pos == move) {
397-      if (value <= moves[k].value)
398-       return 1;
399-      else
400-       break;
401-    }
402-  }
403
404-  return 0;
405-}
406-
407-/* reading_callback helper.
408- * pushes moves onto the move list. */
409-static void
410-r_push_move(int move, int value, const char *name,
411-            struct reading_move_data *moves)
412-{
413-  int k;
414-  for (k = 0; k < MAX_READING_MOVES; k++) {
415-    if (!moves[k].pos) {
416-      moves[k].pos = move;
417-      moves[k].value = value;
418-      moves[k].name = name;
419-      moves[++k].pos = 0;
420-      break;
421-    }
422-   
423-    if (moves[k].value < value) {
424-      int j = k;
425-      while (moves[j].pos != NO_MOVE && moves[j].pos != move)
426-       j++;
427-     
428-      if (moves[j].pos != NO_MOVE)
429-       j--;
430-     
431-      for (; j >= k; j--) {
432-       moves[j+1].pos = moves[j].pos;
433-       moves[j+1].value = moves[j].value;
434-       moves[j+1].name = moves[j].name;
435-      }
436-     
437-      moves[k].pos = move;
438-      moves[k].value = value;
439-      moves[k].name = name;
440-      break;
441-    }
442-  }
443-}
444-
445-/* Callback function for pattern-based tactical reading */
446-static void
447-reading_callback(int anchor, int color,
448-                 struct pattern *pattern, int ll, void *data)
449-{
450-  int k;
451-  int move;
452-  int value = pattern->value;
453-  struct reading_move_data *moves = data;
454-  struct pattern_attribute *attribute;
455-  UNUSED(data);
456-  UNUSED(k);
457-
458-  move = AFFINE_TRANSFORM(pattern->move_offset, ll, anchor);
459-
460-  if (0)
461-    gprintf("  Pattern %s called back at %1m (variation %d) orientation %d.\n",
462-            pattern->name, move, count_variations, ll);
463-
464-  for (attribute = pattern->attributes; attribute->type != LAST_ATTRIBUTE;
465-       attribute++) {
466-    if (attribute->type == MAX_VALUE && attribute->value > value) {
467-      value = attribute->value;
468-      break;
469-    }
470-  }
471-
472
473-  if (r_scan_moves(move, value, moves))
474-    return;
475-
476-  if (0 && !strcmp("none3", pattern->name))
477-    gprintf("Pattern %s contraint to be checked at %1m (variation %d) orientation %d.\n",
478-            pattern->name, move, count_variations, ll);
479-
480-  /* If the pattern has a constraint, call the autohelper to see
481-   * if the pattern must be rejected.
482-   */
483-  if (pattern->autohelper_flag & HAVE_CONSTRAINT)
484-    if (!pattern->autohelper(ll, move, color, 0))
485-      return;
486-
487-  /* If the pattern has a helper, call it.  The helper change the
488-   * pattern-> value.
489-   */
490-  if (pattern->autohelper_flag & HAVE_ACTION)
491-    pattern->autohelper(ll, move, color, 1);
492-
493-  /* Note: The reading code allows helper to change pattern->value */
494-  value = pattern->value;
495-  if (value <= 0)
496-    return;
497-
498-  if (0)
499-    gprintf("  Pattern %s MATCHED  at %1m (variation %d) orientation %d.\n",
500-            pattern->name, move, count_variations, ll);
501-
502-  if (r_scan_moves(move, value, moves))
503-    return;
504-
505-  r_push_move(move, value, pattern->name, moves);
506-
507-}
508-
509-
510-static void
511-set_goal_worm(int str, int value, char goal[BOARDMAX])
512-{
513-  int k;
514-  int color = board[str];
515-  if (goal[str])
516-    return;
517
518-  goal[str] = value;
519-  for (k = 0; k < 4; k++) {
520-    int pos = str + delta[k];
521-    if (board[pos] == color)
522-      set_goal_worm(pos, value, goal);
523-  }
524-}
525-
526-static void
527-set_larger_goal_worm(int str, char goal[BOARDMAX])
528-{
529-  int k;
530-  int color = board[str];
531-  /*Note: over-ride possible 3 values here.*/
532-  if (goal[str] == 1)
533-    return;
534
535-  goal[str] = 1;
536-  for (k = 0; k < 4; k++) {
537-    int pos = str + delta[k];
538-    if (board[pos] == color) {
539-      set_larger_goal_worm(pos, goal);
540-    }
541-    else if (board[pos] == OTHER_COLOR(color)
542-            && (stackp < (depth+4) || countlib(pos) <= 2)) {
543-      set_goal_worm(pos, 2, goal);
544-    }
545-    else if (stackp < (12+2) && board[pos] == EMPTY) {
546-      int j;
547-      for (j = 0; j < 4; j++) {
548-       int jpos = pos + delta[j];
549-       if (board[jpos] == color) {
550-         set_goal_worm(jpos, 3, goal);
551-        }
552-       else if (board[jpos] == OTHER_COLOR(color)) {
553-          /* Added for defense - not needed for attack (?) */
554-         set_goal_worm(jpos, 2, goal);
555-        }
556-      }
557-    }
558-  }
559-}
560-
561-static int
562-do_attack_pat(int str, int *move)
563-{
564-  return do_tactical_pat(1, str, move);
565-}
566-
567-static int
568-do_defend_pat(int str, int *move)
569-{
570-  return do_tactical_pat(0, str, move);
571-}
572-
573-
574-static int
575-do_tactical_pat(int is_attack, int str, int *move)
576-{
577-  char goal[BOARDMAX];
578-  struct reading_move_data moves[MAX_READING_MOVES];
579-  int k;
580-  int color = board[str];
581-  int next_color = is_attack ? OTHER_COLOR(color) : color;
582-  int best_other_tactic = WIN;
583-  int best_move = 0;
584-  int ko_move = 0;
585-  int libs;
586-  int skipped = 0;
587-  const char *trace_str = is_attack ? "attack_pat" : "defend_pat";
588-
589-
590-  SETUP_TRACE_INFO(trace_str, str);
591-
592-  ASSERT1(move != NULL, str);
593-
594-  if (reading_node_counter - nodes_when_called > 15000) {
595-    SGFTRACE(0, 0, "Way too many variations");
596-    return 0;
597-  }
598-
599-  libs = countlib(str);
600-
601-  if (stackp > depth && libs > 2) {
602-    SGFTRACE(0, 0, "Too deep");
603-    return 0;
604-  }
605-
606-  if (libs == 1) {
607-    if (is_attack)
608-      return attack1(str, move);
609-    else
610-      return defend1(str, move);
611-  }
612-
613-  if (libs == 4) {
614-    if (is_attack)
615-      return attack4(str, move);
616-    else
617-      return defend4(str, move);
618-  }
619-
620-  memset(goal, 0, BOARDMAX);
621-
622-  reading_node_counter++;
623-  set_larger_goal_worm(str, goal);
624-  moves[0].pos = 0;
625-  if (verbose > 1) {
626-    TRACE("Stack: ");
627-    dump_stack();
628-  }
629-  rgoal = goal;
630-  goallib = libs;
631-  if (is_attack)
632-    matchpat_goal_anchor(reading_callback, OTHER_COLOR(color),
633-                        &read_attack_db, moves, goal, 1);
634-  else
635-    matchpat_goal_anchor(reading_callback, OTHER_COLOR(color),
636-                        &read_defend_db, moves, goal, 1);
637-
638-  if (verbose > 1) {
639-    TRACE("Moves (variation %d): ", count_variations);
640-    for (k = 0; k < MAX_READING_MOVES; k++) {
641-      if (!moves[k].pos)
642-       break;
643-      TRACE("%o%s@%1m ", moves[k].name, moves[k].pos);
644-    }
645-    TRACE("\n");
646-  }
647-
648-  if (sgf_dumptree) {
649-    char buf[500];
650-    char *pos;
651-    int chars;
652-    gg_snprintf(buf, 500, "Move order for %s: %n",
653-               read_function_name, &chars);
654-   
655-    pos = buf + chars;
656-    for (k = 0; k < MAX_READING_MOVES; k++) {
657-      if (moves[k].pos == NO_MOVE)
658-       break;
659-      sprintf(pos, "%s (%s-%d) %n", location_to_string(moves[k].pos),
660-              moves[k].name, moves[k].value, &chars);
661-      pos += chars;
662-    }
663-    sgftreeAddComment(sgf_dumptree, buf);
664-  }
665-
666-  for (k = 0; MAX_READING_MOVES; k++) {
667-    char namebuf[128];
668-    if (moves[k].pos == NO_MOVE)
669-      break;
670-
671-    gg_snprintf(namebuf, 128, "%s(%d)", moves[k].name, moves[k].value);
672-    if (k > 3 + skipped && k > 12 - stackp + skipped) {
673-      if (sgf_dumptree) {
674-        if (trymove(moves[k].pos, next_color, namebuf, str)) {
675-          sgftreeAddComment(sgf_dumptree, "move trimmed to reduce variations");
676-          popgo();
677-        }
678-      }
679-      continue;
680-    }
681-
682-    if (komaster_trymove(moves[k].pos, next_color, namebuf, str, &ko_move,
683-                        stackp <= ko_depth && best_other_tactic == WIN)) {
684-      int other_tactic;
685-      ASSERT1(countlib(str) >= 1, str);
686-      if (sgf_dumptree) {
687-        char buf[500];
688-        sprintf(buf, "tactical_pat komaster: %d %d  ko_move: %d",
689-               get_komaster(), get_kom_pos(), ko_move);
690-        sgftreeAddComment(sgf_dumptree, buf);
691-      }
692-     
693-      if (stackp > 100) {
694-        popgo();
695-       if (0)
696-         gprintf("komaster: %d %1m  ko_move: %d\n",
697-                 get_komaster(), get_kom_pos(), ko_move);
698-        continue;  /* Short circuit */
699-      }
700-     
701-      if (is_attack)
702-        other_tactic = do_find_defense(str, 0);
703-      else
704-        other_tactic = do_attack(str, 0);
705-
706-      if (is_attack && other_tactic != WIN) {
707-        int same_tactic;
708-        /* HINT: add 1 || here to generate stack errors in reading:60
709-         *    (not positive of problem number) */
710-        if (stackp < depth + 6 || countlib(str) <= 2) {
711-          if (is_attack)
712-           same_tactic = do_attack(str, 0);
713-         else
714-           same_tactic = do_find_defense(str, 0);
715-
716-         if (!ko_move && other_tactic == 0 && same_tactic != 0) {
717-           *move = moves[k].pos;
718-           popgo();
719-           SGFTRACE(moves[k].pos, WIN,
720-                    "tactic successful - no defense, ko sub-attack");
721-           return WIN;
722-         }
723-        }
724-       else {
725-          same_tactic = 0;
726-          SGFTRACE(moves[k].pos, 0, "Too deep, aborting attack");
727-        }
728-       /* This defense assignment may be incorrect. */
729-       other_tactic = gg_max(other_tactic, REVERSE_RESULT(same_tactic));
730-      }
731-      if (!other_tactic) {
732-       if (ko_move) {
733-         TRACE("Ko move good: %1m\n", moves[k].pos);
734-         other_tactic = KO_A;
735-         if (other_tactic < best_other_tactic) {
736-           best_move = moves[k].pos;
737-           best_other_tactic = other_tactic;
738-         }
739-       }
740-       else {
741-         popgo();
742-          /* FIXME: add explicit attack/defense verbage here */
743-         SGFTRACE(moves[k].pos, WIN, "tactic successful - no counter.");
744-         *move = moves[k].pos;
745-         return WIN;
746-       }
747-      }
748-      else if (other_tactic < best_other_tactic) {
749-       /* May need to check ko_move in this case, too */
750-       best_move = moves[k].pos;
751-       best_other_tactic = other_tactic;
752-      }
753-      popgo();
754-    }
755-    else {
756-      /* FIXME: Add this back to allow up to 3 legal moves when deep. */
757-      /* Current implementation counts illegal moves. */
758-      if (0)
759-       skipped++;
760-    }
761-  }
762-
763-  if (!is_attack) {
764-    /* Force attacker to capture - i.e. might be seki. */
765-    int attack;
766-    attack = do_attack(str, 0);
767-    if (attack < best_other_tactic) {
768-      best_move = PASS_MOVE;
769-      best_other_tactic = attack;
770-    }
771-  }
772-
773-
774-  /* FIXME: Add explicit attack/defense verbage here. */
775-  SGFTRACE(best_move, REVERSE_RESULT(best_other_tactic), "No good tactic.");
776-  *move = best_move;
777-  return REVERSE_RESULT(best_other_tactic);
778-}
779-
780-#endif /*EXPERIMENTAL_READING*/
781-
782 
783 /* Like attack. If the opponent is komaster reading functions will not try
784  * to take ko.
785@@ -3266,14 +2834,6 @@
786       *move = xpos;
787     return retval;
788   }
789-
790-#if EXPERIMENTAL_READING
791-  if (attack_by_pattern) {
792-    result = do_attack_pat(str, &xpos);
793-    /* Set liberties to 0 to pass over the non-pattern code below. */
794-    liberties = 0;
795-  }
796-#endif
797 
798   /* Treat the attack differently depending on how many liberties the
799      string at (str) has. */
800Index: interface/main.c
801===================================================================
802RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v
803retrieving revision 1.114
804diff -u -r1.114 main.c
805--- interface/main.c    12 Jun 2005 09:34:14 -0000      1.114
806+++ interface/main.c    23 Sep 2005 22:27:00 -0000
807@@ -148,8 +148,6 @@
808       OPT_ALLOW_SUICIDE,
809       OPT_CAPTURE_ALL_DEAD,
810       OPT_PLAY_OUT_AFTERMATH,
811-      OPT_ATTACK_BY_PATTERN,
812-      OPT_DEFEND_BY_PATTERN,
813       OPT_MIRROR,
814       OPT_MIRROR_LIMIT,
815       OPT_METAMACHINE,
816@@ -292,8 +290,6 @@
817   {"score",          required_argument, 0, OPT_SCORE},
818   {"printsgf",       required_argument, 0, OPT_PRINTSGF},
819   {"profile-patterns", no_argument,     0, OPT_PROFILE_PATTERNS},
820-  {"attack-by-pattern", no_argument,    0, OPT_ATTACK_BY_PATTERN},
821-  {"defend-by-pattern", no_argument,    0, OPT_DEFEND_BY_PATTERN},
822   {"mirror",         no_argument,       0, OPT_MIRROR},
823   {"mirror-limit",   required_argument, 0, OPT_MIRROR_LIMIT},
824   {"metamachine",    no_argument,       0, OPT_METAMACHINE},
825@@ -508,9 +504,6 @@
826        if (EXPERIMENTAL_OWL_EXT)
827          fprintf(stdout,
828                  "configure option enabled: experimental GAIN/LOSS codes\n");
829-       if (EXPERIMENTAL_READING)
830-         fprintf(stdout,
831-                 "configure option enabled: experimental reading\n");
832        if (OWL_THREATS)
833          fprintf(stdout,
834                  "configure option enabled: owl threats\n");
835@@ -938,18 +931,6 @@
836        return EXIT_SUCCESS;
837        break;
838       
839-#if EXPERIMENTAL_READING
840-
841-      case OPT_ATTACK_BY_PATTERN:
842-        attack_by_pattern = 1;
843-        break;
844-
845-      case OPT_DEFEND_BY_PATTERN:
846-        defend_by_pattern = 1;
847-        break;
848-
849-#endif
850-
851       case OPT_MIRROR:
852         play_mirror_go = 1;
853         break;
854@@ -1614,9 +1595,6 @@
855    --decide-eye <string>        evaluate the eye\n\
856    --decide-combination         search for combination attack (try with -o)\n\
857    --genmove <color>            generate a move for color\n\
858-Other options:\n\
859-   --attack-by-pattern          use pattern-based tactical reading for attack\n\
860-   --defend-by-pattern          use pattern-based tactical reading for defense\n\
861 "
862 
863 #define DEBUG_FLAGS "\
864Index: patterns/Makefile.am
865===================================================================
866RCS file: /cvsroot/gnugo/gnugo/patterns/Makefile.am,v
867retrieving revision 1.36
868diff -u -r1.36 Makefile.am
869--- patterns/Makefile.am        18 Sep 2005 12:04:36 -0000      1.36
870+++ patterns/Makefile.am        23 Sep 2005 22:27:00 -0000
871@@ -34,8 +34,6 @@
872        fuseki13.dbz\
873        fuseki19.dbz\
874        handicap.db\
875-       read_attack.db\
876-       read_defend.db\
877        oracle.db
878 
879 mkpat_SOURCES  = mkpat.c transform.c dfa.c
880@@ -73,7 +71,7 @@
881                  owl_attackpat.c\
882                 owl_vital_apat.c owl_defendpat.c fusekipat.c\
883                  fuseki9.c fuseki13.c fuseki19.c josekidb.c\
884-                read_attack.c read_defend.c handipat.c oraclepat.c
885+                handipat.c oraclepat.c
886 
887 DBBUILT = gogo.db hoshi_keima.db hoshi_other.db komoku.db sansan.db \
888          mokuhazushi.db takamoku.db
889@@ -85,7 +83,7 @@
890            endgame.db eyes.db fuseki.db fuseki9.dbz fuseki13.dbz fuseki19.dbz\
891            handicap.db influence.db oracle.db owl_attackpats.db\
892            owl_defendpats.db owl_vital_apats.db patterns.db patterns2.db\
893-           read_attack.db read_defend.db $(DBBUILT)
894+           $(DBBUILT)
895 
896 # Remove these files here... they are created locally
897 DISTCLEANFILES = $(GGBUILTSOURCES) $(DBBUILT) *~
898@@ -186,12 +184,6 @@
899 
900 handipat.c : $(srcdir)/handicap.db mkpat$(EXEEXT)
901        ./mkpat -b handipat -i $(srcdir)/handicap.db -o handipat.c
902-
903-read_attack.c : $(srcdir)/read_attack.db mkpat$(EXEEXT)
904-       ./mkpat -b read_attack -i $(srcdir)/read_attack.db -o read_attack.c
905-
906-read_defend.c : $(srcdir)/read_defend.db mkpat$(EXEEXT)
907-       ./mkpat -b read_defend -i $(srcdir)/read_defend.db -o read_defend.c
908 
909 
910 ETAGS_ARGS = --language none --regex '/^Pattern[ \t]+[a-zA-Z0-9]+/' $(DB_TO_TAG)\
911Index: patterns/Makefile.in
912===================================================================
913RCS file: /cvsroot/gnugo/gnugo/patterns/Makefile.in,v
914retrieving revision 1.55
915diff -u -r1.55 Makefile.in
916--- patterns/Makefile.in        18 Sep 2005 12:04:36 -0000      1.55
917+++ patterns/Makefile.in        23 Sep 2005 22:27:00 -0000
918@@ -112,8 +112,6 @@
919        fuseki13.dbz\
920        fuseki19.dbz\
921        handicap.db\
922-       read_attack.db\
923-       read_defend.db\
924        oracle.db
925 
926 
927@@ -150,7 +148,7 @@
928                  owl_attackpat.c\
929                 owl_vital_apat.c owl_defendpat.c fusekipat.c\
930                  fuseki9.c fuseki13.c fuseki19.c josekidb.c\
931-                read_attack.c read_defend.c handipat.c oraclepat.c
932+                handipat.c oraclepat.c
933 
934 
935 DBBUILT = gogo.db hoshi_keima.db hoshi_other.db komoku.db sansan.db \
936@@ -165,7 +163,7 @@
937            endgame.db eyes.db fuseki.db fuseki9.dbz fuseki13.dbz fuseki19.dbz\
938            handicap.db influence.db oracle.db owl_attackpats.db\
939            owl_defendpats.db owl_vital_apats.db patterns.db patterns2.db\
940-           read_attack.db read_defend.db $(DBBUILT)
941+           $(DBBUILT)
942 
943 
944 # Remove these files here... they are created locally
945@@ -202,8 +200,8 @@
946        aa_attackpat.$(OBJEXT) owl_attackpat.$(OBJEXT) \
947        owl_vital_apat.$(OBJEXT) owl_defendpat.$(OBJEXT) \
948        fusekipat.$(OBJEXT) fuseki9.$(OBJEXT) fuseki13.$(OBJEXT) \
949-       fuseki19.$(OBJEXT) josekidb.$(OBJEXT) read_attack.$(OBJEXT) \
950-       read_defend.$(OBJEXT) handipat.$(OBJEXT) oraclepat.$(OBJEXT)
951+       fuseki19.$(OBJEXT) josekidb.$(OBJEXT) \
952+       handipat.$(OBJEXT) oraclepat.$(OBJEXT)
953 libpatterns_a_OBJECTS = $(am_libpatterns_a_OBJECTS)
954 EXTRA_PROGRAMS = extract_fuseki$(EXEEXT) transpat$(EXEEXT) \
955        compress_fuseki$(EXEEXT)
956@@ -267,8 +265,8 @@
957 @AMDEP_TRUE@   $(DEPDIR)/oraclepat.Po $(DEPDIR)/owl_attackpat.Po \
958 @AMDEP_TRUE@   $(DEPDIR)/owl_defendpat.Po \
959 @AMDEP_TRUE@   $(DEPDIR)/owl_vital_apat.Po $(DEPDIR)/patlib.Po \
960-@AMDEP_TRUE@   $(DEPDIR)/patterns.Po $(DEPDIR)/read_attack.Po \
961-@AMDEP_TRUE@   $(DEPDIR)/read_defend.Po $(DEPDIR)/transform.Po \
962+@AMDEP_TRUE@   $(DEPDIR)/patterns.Po \
963+@AMDEP_TRUE@   $(DEPDIR)/transform.Po \
964 @AMDEP_TRUE@   $(DEPDIR)/transpat.Po \
965 @AMDEP_TRUE@   $(DEPDIR)/uncompress_fuseki.Po
966 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
967@@ -364,8 +362,6 @@
968 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/owl_vital_apat.Po@am__quote@
969 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/patlib.Po@am__quote@
970 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/patterns.Po@am__quote@
971-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/read_attack.Po@am__quote@
972-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/read_defend.Po@am__quote@
973 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/transform.Po@am__quote@
974 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/transpat.Po@am__quote@
975 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/uncompress_fuseki.Po@am__quote@
976@@ -608,12 +604,6 @@
977 
978 handipat.c : $(srcdir)/handicap.db mkpat$(EXEEXT)
979        ./mkpat -b handipat -i $(srcdir)/handicap.db -o handipat.c
980-
981-read_attack.c : $(srcdir)/read_attack.db mkpat$(EXEEXT)
982-       ./mkpat -b read_attack -i $(srcdir)/read_attack.db -o read_attack.c
983-
984-read_defend.c : $(srcdir)/read_defend.db mkpat$(EXEEXT)
985-       ./mkpat -b read_defend -i $(srcdir)/read_defend.db -o read_defend.c
986 # Tell versions [3.59,3.63) of GNU make to not export all variables.
987 # Otherwise a system limit (for SysV at least) may be exceeded.
988 .NOEXPORT:
989Index: patterns/mkpat.c
990===================================================================
991RCS file: /cvsroot/gnugo/gnugo/patterns/mkpat.c,v
992retrieving revision 1.149
993diff -u -r1.149 mkpat.c
994--- patterns/mkpat.c    18 Sep 2005 12:56:49 -0000      1.149
995+++ patterns/mkpat.c    23 Sep 2005 22:27:02 -0000
996@@ -57,7 +57,6 @@
997        -f = compile a fullboard pattern database\n\
998        -C = compile a corner pattern database\n\
999        -D = compile a DFA database (allows fast matching)\n\
1000-       -T = compile a tree based pattern database (even faster)\n\
1001        -d <iterations> = don't generate database, but optimize a DFA\n\
1002                          transformation file instead\n\
1003   Pattern generation options:\n\
1004@@ -96,7 +95,6 @@
1005 #define DB_FULLBOARD   ((int) 'f')
1006 #define DB_CORNER      ((int) 'C')
1007 #define DB_DFA         ((int) 'D')
1008-#define DB_TREE        ((int) 'T')
1009 #define OPTIMIZE_DFA   ((int) 'd')
1010 
1011 /* code assumes that ATT_O and ATT_X are 1 and 2 (in either order)
1012@@ -1769,35 +1767,6 @@
1013     - order[((const struct patval_b *)b)->att];
1014 }
1015 
1016-#if EXPERIMENTAL_READING
1017-
1018-/* For the tree-based algorithm, it works best to sort the elements
1019- * by distance from the anchor, making the search tree smaller.
1020- * Similarly, it's best to match the most common elements first.
1021- * Note: This will therefore not work for the connections database
1022- */
1023-
1024-static int
1025-compare_elements_closest(const void *a, const void *b)
1026-{
1027-  const struct patval_b *pa = (const struct patval_b *)a;
1028-  const struct patval_b *pb = (const struct patval_b *)b;
1029-
1030-  int ax = pa->x - ci;
1031-  int bx = pb->x - ci;
1032-  int ay = pa->y - cj;
1033-  int by = pb->y - cj;
1034-  int metric = (ax*ax + ay*ay) - (bx*bx + by*by);
1035-  if (metric == 0)
1036-    return -compare_elements(a, b);
1037-  else
1038-    return metric;
1039-}
1040-
1041-static void tree_push_pattern(void);
1042-
1043-#endif
1044-
1045 struct element_node {
1046   struct patval_b e;
1047   struct element_node *next;
1048@@ -1864,8 +1833,6 @@
1049       /* DFA pattern matcher doesn't itself need these elements at all. But
1050        * they might be needed for goal checking or by callback function, so
1051        * we check it before discarding an element.
1052-       *
1053-       * FIXME: What about tree matcher?
1054        */
1055       if (database_type == DB_DFA)
1056        continue;
1057@@ -1889,468 +1856,10 @@
1058     fprintf(outfile, "\n};\n\n");
1059 
1060   pattern[patno].patlen = used_nodes;
1061-
1062-#if EXPERIMENTAL_READING
1063-  if (database_type == DB_TREE)
1064-    tree_push_pattern();
1065-#endif
1066-}
1067-
1068-#if EXPERIMENTAL_READING
1069-
1070-struct tree_node graph[2];
1071-int tree_next = 0;
1072-
1073-/* The elements of a "simplified" pattern, which has already been
1074- * copied in the following ways:
1075- *  1) All rotations
1076- *  2) All ATT_x & ATT_o elements reduced to ATT_dot, ATT_X, and ATT_O
1077- *
1078- * This simplification allows for very simple searching of the
1079- * pre-digested patterns. 
1080- *
1081- * For example, a pattern with 8 symmetry and one ATT_x element will
1082- * have 16 copies located in various places throughout the tree.
1083- * This function adds only one of the 16 copies.
1084- */
1085-static void
1086-tree_push_elements(struct element_node *elist,
1087-                  struct tree_node *tree_start, int ll)
1088-{
1089-  struct tree_node_list *grptr;
1090-  struct element_node *elist_next;
1091-  struct element_node *elist_prev;
1092-
1093-   if (!tree_start->next_list) {
1094-     tree_start->next_list = malloc(sizeof(*(tree_start->next_list)));
1095-     tree_start->next_list->next = 0;
1096-   }
1097-
1098-    elist_prev = elist_next = elist;
1099-    while (elist_next->next) {
1100-      elist_prev = elist_next;
1101-      elist_next = elist_next->next;
1102-      for (grptr = tree_start->next_list; grptr != 0; grptr = grptr->next) {
1103-        if (elist_next->e.x == grptr->node.x
1104-           && elist_next->e.y == grptr->node.y
1105-           && elist_next->e.att == grptr->node.att)
1106-        {
1107-          if (verbose)
1108-            fprintf(stderr, "  element matched.\n");
1109-          elist_prev->next = elist_next->next;
1110-          tree_push_elements(elist, &(grptr->node), ll);
1111-          return;
1112-        }
1113-      }
1114-    }
1115-
1116-    if (elist->next) {
1117-      /* Still elements to add to tree */
1118-      for (grptr = tree_start->next_list;
1119-          grptr->next != NULL;
1120-          grptr = grptr->next)
1121-       ;
1122-     
1123-      grptr->next = malloc(sizeof(*(grptr->next)));
1124-      grptr = grptr->next;
1125-      grptr->node.matches = 0;
1126-      grptr->node.att = elist->next->e.att;
1127-      if (!(grptr->node.att == ATT_dot
1128-           || grptr->node.att == ATT_X
1129-           || grptr->node.att == ATT_O)) {
1130-        fprintf(stderr,
1131-               "%s(%d) : error : Internal error; unexpected att = %d\n",
1132-                current_file, current_line_number, grptr->node.att);
1133-        fatal_errors++;
1134-      }
1135-      grptr->node.x = elist->next->e.x;
1136-      grptr->node.y = elist->next->e.y;
1137-      grptr->node.next_list = 0;
1138-      grptr->next = 0;
1139-      elist->next = elist->next->next;
1140-      if (verbose) {
1141-        fprintf(stderr, "  Added node %c, x=%2d, y=%2d\n",
1142-               *(VALID_PATTERN_CHARS + grptr->node.att),
1143-               grptr->node.x, grptr->node.y);
1144-      }
1145-      tree_push_elements(elist, &grptr->node, ll);
1146-    }
1147-    else {
1148-      /* patten matches here! */
1149-      struct match_node *matches;
1150-      if (verbose)
1151-        fprintf(stderr, "  pattern complete.\n");
1152-      matches = tree_start->matches;
1153-     
1154-      if (!matches) {
1155-        matches = malloc(sizeof(*matches));
1156-        matches->next = 0;
1157-        tree_start->matches = matches;
1158-      }
1159-     
1160-      while (matches->next != NULL)
1161-        matches = matches->next;
1162-
1163-      matches->next = malloc(sizeof(*(matches->next)));
1164-      matches = matches->next;
1165-      matches->patnum = patno;
1166-      matches->next = 0;
1167-      matches->orientation = ll;
1168-    }
1169-}
1170-
1171-
1172-/* By this point, the pattern is rotated.  Now, recursively
1173- * copy the entries as necessary, expanding o & x to ., O, & X
1174- */
1175-static void
1176-tree_push_pattern_DOX(struct element_node *elist, int ll)
1177-{
1178-  struct element_node *elist_next = 0;
1179-  struct element_node *elist_prev = 0;
1180-  int need_copy = 0;
1181-
1182-  elist_next = elist->next;
1183-  while (elist_next) {
1184-    if (elist_next->e.att == ATT_o
1185-        || elist_next->e.att == ATT_x) {
1186-      need_copy = 1;
1187-      break;
1188-    }
1189-    elist_next = elist_next->next;
1190-  }
1191-   
1192-  if (need_copy) {
1193-    struct element_node *elist_copy1 = malloc(sizeof(*elist_copy1));
1194-    struct element_node *elist_copy2 = malloc(sizeof(*elist_copy2));
1195-    struct element_node *elist1_next = elist_copy1;
1196-    struct element_node *elist2_next = elist_copy2;
1197-    int found_copy_element = 0;
1198-   
1199-    elist_next = elist->next;
1200-    while (elist_next) {
1201-      elist1_next->next = malloc(sizeof(*(elist1_next->next)));
1202-      elist1_next = elist1_next->next;
1203-      elist1_next->e = elist_next->e;
1204-      elist2_next->next = malloc(sizeof(*(elist2_next->next)));
1205-      elist2_next = elist2_next->next;
1206-      elist2_next->e = elist_next->e;
1207-      if (!found_copy_element) {
1208-        if (elist_next->e.att == ATT_o
1209-            || elist_next->e.att == ATT_x) {
1210-          found_copy_element = 1;
1211-          elist1_next->e.att = ATT_dot;
1212-          elist2_next->e.att = (elist_next->e.att == ATT_o ? ATT_O : ATT_X);
1213-        }
1214-      }
1215-      elist1_next->next = 0;
1216-      elist2_next->next = 0;
1217-      elist_next = elist_next->next;
1218-    }
1219-    assert(found_copy_element);
1220-    tree_push_pattern_DOX(elist_copy1, ll);
1221-    tree_push_pattern_DOX(elist_copy2, ll);
1222-    return;
1223-  }
1224-
1225-  {
1226-    if (verbose)
1227-      fprintf(stderr, "P[%s %d]:\n", pattern_names[patno], ll);
1228-    elist_prev = elist_next = elist;
1229-    while (elist_next->next) {
1230-      int i;
1231-      elist_prev = elist_next;
1232-      elist_next = elist_next->next;
1233-      for (i = 0; i <= 1; i++) {
1234-        if (elist_next->e.x == graph[i].x
1235-            && elist_next->e.y == graph[i].y
1236-            && elist_next->e.att == graph[i].att)
1237-        {
1238-          elist_prev->next = elist_next->next;
1239-          tree_push_elements(elist, &graph[i], ll);
1240-          assert(!elist->next);  /* Element list should get exhausted */
1241-          return;
1242-        }
1243-      }
1244-    }
1245-  }
1246-  assert(0 && "Anchor not matched.");
1247-}
1248-
1249-/* Rotate the pattern and push it onto the tree once for each
1250- * appropriate rotation.
1251- */
1252-static void
1253-tree_push_pattern_rot(int ll)
1254-{
1255-  struct element_node *elist = 0;
1256-  struct element_node *elist_next = 0;
1257-  int i;
1258
1259-  elist = malloc(sizeof(*elist));
1260-  elist_next = elist;
1261-  for (i = 0; i < el; i++) {
1262-    elist_next->next = malloc(sizeof(*(elist_next->next))); /*or die*/
1263-    elist_next = elist_next->next;
1264-    elist_next->e.att = elements[i].att;
1265-    /* or continue if we don't need this transformation */
1266-    TRANSFORM2(elements[i].x - ci, elements[i].y - cj,
1267-               &(elist_next->e.x), &(elist_next->e.y), ll);
1268-    elist_next->next = 0;
1269-  }
1270-  tree_push_pattern_DOX(elist, ll);
1271-}
1272-
1273-/* For each pattern, this is the entry point to add the pattern
1274- * to the tree-based pattern matching data structure.
1275- *
1276- * The pattern will be rotated and copied possibly many times,
1277- * as explained in tree_push_elements().
1278- *
1279- * Conceptually, each node of the tree corresponds to either
1280- * ATT_dot, ATT_X, or ATT_O, with an x and y coordinate relative
1281- * to the anchor.  When the pattern matcher is run, if
1282- * board[POS(node.x, node.y)] == node.att, then proceed to the
1283- * next node.  If you find a node with a match_node pointer,
1284- * then a pattern has matched (with a given orientation).
1285- */
1286-static void
1287-tree_push_pattern(void)
1288-{
1289-  static int init = 0;
1290-  int ll;
1291-  int start_transformation = 0;
1292-  int end_transformation;
1293-
1294-  if (!init) {
1295-    memset(graph, 0, sizeof(struct tree_node));
1296-    graph[0].att = ATT_X;
1297-    graph[1].att = ATT_O;
1298-    graph[0].next_list = 0;
1299-    graph[1].next_list = 0;
1300-    tree_next = 2;
1301-    init = 1;
1302-  }
1303-
1304-  if (pattern->trfno == 5) {
1305-    start_transformation = 2;
1306-    end_transformation = 6;
1307-  }
1308-
1309-  end_transformation = pattern[patno].trfno;
1310-
1311-  /* sort the elements so that MOST likely elements are tested first. */
1312-  gg_sort(elements, el, sizeof(struct patval_b), compare_elements_closest);
1313-
1314-  if (0) {
1315-  int i;
1316-    for (i = 0; i < el; i++) {
1317-      fprintf(stderr, "E[%d, %d, %c]\n",
1318-             elements[i].x - ci, elements[i].y - cj,
1319-             *(VALID_PATTERN_CHARS + elements[i].att));
1320-    }
1321-    fprintf(stderr, "\n");
1322-  }
1323-
1324-  for (ll = start_transformation; ll < end_transformation; ++ll)
1325-    tree_push_pattern_rot(ll);
1326 }
1327 
1328 
1329 /* ================================================================ */
1330-/*         stuff to write out the stored pattern structures         */
1331-/* ================================================================ */
1332-
1333-static int mn_count;
1334-static int tnl_count;
1335-
1336-struct tree_node_list *tnl_dump;
1337-struct match_node *matches_dump;
1338-
1339-#define PASS_COUNT 1
1340-#define PASS_FILL 2
1341-
1342-
1343-/* Note: Currently the tree_node_list & match_node lists contain
1344- * dummy headers in their lists, which isn't at all necessary when
1345- * being used by GNU Go, but are very handy when building them up
1346- * in mkpat.  Probably can strip these out when writing out the
1347- * final data structure.
1348- *
1349- * Does the hard work to outputs the tree data structure data as C code
1350- * for GNU Go.
1351- */
1352-static void
1353-dump_tree_node(FILE *outfile, struct tree_node *gn, int depth, int pass)
1354-{
1355-  static int as_text = 0;
1356-  struct tree_node_list *gl;
1357-  tnl_count++;
1358-
1359-  if (as_text) {
1360-    if (depth > 0)
1361-      fprintf(stderr, "%.*s", depth*2, "                                             ");
1362-    fprintf(stderr, "GN[att=%c, x=%d, y=%d",
1363-           *(VALID_PATTERN_CHARS + gn->att), gn->x, gn->y);
1364-  }
1365
1366-  if (pass == PASS_FILL) {
1367-    tnl_dump[tnl_count].node.att = gn->att;
1368-    tnl_dump[tnl_count].node.x = gn->x;
1369-    tnl_dump[tnl_count].node.y = gn->y;
1370-  }
1371-
1372-  if (gn->matches) {
1373-    struct match_node *m = gn->matches->next;
1374-    if (pass == PASS_FILL) {
1375-      tnl_dump[tnl_count].node.matches = (void *) mn_count;
1376-      matches_dump[mn_count].patnum = -1; /*Unused*/
1377-      matches_dump[mn_count].orientation = 0; /*Unused*/
1378-      matches_dump[mn_count].next = (void *) (mn_count + 1);
1379-    }
1380-   
1381-    if (as_text)
1382-      fprintf(stderr, ", matches[%d]: ", mn_count);
1383-
1384-    mn_count++;
1385-    while (m) {
1386-      if (pass == PASS_FILL) {
1387-        matches_dump[mn_count].patnum = m->patnum;
1388-        matches_dump[mn_count].orientation = m->orientation;
1389-        if (m->next)
1390-          matches_dump[mn_count].next = (void *) (mn_count + 1);
1391-       else
1392-          matches_dump[mn_count].next = 0;
1393-      }
1394-     
1395-      if (as_text)
1396-        fprintf(stderr, "P[%s, %d]", pattern_names[m->patnum],
1397-               m->orientation);
1398-
1399-      mn_count++;
1400-      m = m->next;
1401-    }
1402-  }
1403-  else {
1404-    if (pass == PASS_FILL)
1405-      tnl_dump[tnl_count].node.matches = 0;
1406-  }
1407-
1408-  if (as_text)
1409-    fprintf(stderr, "]\n");
1410-
1411-  gl = gn->next_list;
1412-  if (gl) {
1413-    int prev_tnl_count = tnl_count;
1414-    if (pass == PASS_FILL) {
1415-      tnl_dump[tnl_count].node.next_list = (void *) (tnl_count + 1);
1416-      /*tnl_dump[tnl_count+1].node data is unused.*/
1417-      tnl_dump[tnl_count+1].node.matches = 0;   /*Unused*/
1418-      tnl_dump[tnl_count+1].node.att = -1;      /*Unused*/
1419-      tnl_dump[tnl_count+1].node.x = -99;       /*Unused*/
1420-      tnl_dump[tnl_count+1].node.y = -99;       /*Unused*/
1421-      tnl_dump[tnl_count+1].node.next_list = 0; /*Unused*/
1422-
1423-    }
1424-    prev_tnl_count = tnl_count;
1425-    tnl_count++;
1426-    while (gl->next) {
1427-      if (pass == PASS_FILL)
1428-        tnl_dump[prev_tnl_count+1].next = (void *) (tnl_count + 1);
1429-
1430-      prev_tnl_count = tnl_count;
1431-      dump_tree_node(outfile, &gl->next->node, depth + 1, pass);
1432-      gl = gl->next;
1433-    }
1434-    if (pass == PASS_FILL)
1435-      tnl_dump[prev_tnl_count + 1].next = 0;
1436-  }
1437-  else {
1438-    if (pass == PASS_FILL) {
1439-      assert(0 && "Strange bug here");
1440-      /* This may be where we crash if we're missing an anchor color
1441-       * in the database */
1442-      if (0)
1443-       fprintf(outfile, "  tnl[%d].node.next_list = 0;\n", tnl_count);
1444-    }
1445-  }
1446-
1447-
1448-}
1449
1450-/*
1451- * Outputs the tree data structure data as C code for GNU Go.
1452- */
1453-static void
1454-tree_write_patterns(FILE *outfile)
1455-{
1456-  int oanchor_index = 0;
1457-  int i;
1458-  fprintf(outfile, "#include \"patterns.h\"\n\n");
1459-
1460-  mn_count = 1;
1461-  tnl_count = 0;
1462-  dump_tree_node(outfile, &graph[0], 0, PASS_COUNT);
1463-
1464-  oanchor_index = tnl_count+1;
1465-  dump_tree_node(outfile, &graph[1], 0, PASS_COUNT);
1466-
1467-  tnl_dump = malloc(sizeof(*tnl_dump) * tnl_count);
1468-  matches_dump = malloc(sizeof(*matches_dump) * mn_count);
1469-
1470-  tnl_dump[0].next = (void *) 1;  /* X anchor node */
1471-  tnl_dump[0].node.att = -1;    /* Not used */
1472-  tnl_dump[0].node.matches = 0; /* Not used */
1473-  tnl_dump[0].node.x = -99;     /* Not used */
1474-  tnl_dump[0].node.y = -99;     /* Not used */
1475-  tnl_dump[0].node.next_list = 0; /* Not used */
1476-  tnl_dump[1].next = (void *) oanchor_index;
1477-  tnl_dump[oanchor_index].next = 0;
1478
1479-  mn_count = 1;
1480-  tnl_count = 0;
1481-  dump_tree_node(outfile, &graph[0], 0, PASS_FILL);
1482-  dump_tree_node(outfile, &graph[1], 0, PASS_FILL);
1483-
1484-  fprintf(outfile, "struct tree_node_list tnl_%s[] =\n{\n", prefix);
1485-  for (i = 0; i < tnl_count+1; i++) {
1486-    fprintf(outfile,
1487-           "  { {(void *)%d, %d, %d, %d, (void *)%d}, (void *)%d}, /*#%d*/\n",
1488-           (int)tnl_dump[i].node.matches,
1489-           tnl_dump[i].node.att,
1490-           tnl_dump[i].node.x,
1491-           tnl_dump[i].node.y,
1492-           (int)tnl_dump[i].node.next_list,
1493-           (int)tnl_dump[i].next,
1494-           i);
1495-  }
1496-  fprintf(outfile, "};\n\n");
1497-
1498-  fprintf(outfile, "struct match_node matches_%s[] = \n{\n", prefix);
1499-  for (i = 0; i < mn_count; i++) {
1500-    fprintf(outfile, "  {%d, %d, (void *)%d}, /*#%d*/\n",
1501-           matches_dump[i].patnum,
1502-           matches_dump[i].orientation,
1503-           (int) matches_dump[i].next,
1504-           i);
1505-  }
1506-  fprintf(outfile, "};\n\n");
1507-
1508-  fprintf(outfile, "void\ninit_tree_%s(void)\n{\n", prefix);
1509-  fprintf(outfile, "  gg_assert(sizeof(tnl_%s) / sizeof(struct tree_node_list) == %d);\n",
1510-         prefix, tnl_count+1);
1511-  fprintf(outfile, "  gg_assert(sizeof(matches_%s) / sizeof(struct match_node) == %d);\n",
1512-         prefix, mn_count);
1513-  fprintf(outfile,
1514-         "  tree_initialize_pointers(tnl_%s, matches_%s, %d, %d);\n",
1515-         prefix, prefix, tnl_count+1, mn_count+1);
1516-  fprintf(outfile, "}\n\n");
1517-}
1518-
1519-#endif
1520-
1521-
1522-/* ================================================================ */
1523 /*                 Corner database creation stuff                  */
1524 /* ================================================================ */
1525 
1526@@ -2836,15 +2345,6 @@
1527 {
1528   int j;
1529 
1530-#if EXPERIMENTAL_READING
1531-  if (database_type == DB_TREE)
1532-    tree_write_patterns(outfile);
1533-  else
1534-    fprintf(outfile, "\nvoid\ninit_tree_%s(void)\n{\n"
1535-           "  /* nothing to do - tree option not compiled */\n"
1536-           "}\n\n", prefix);
1537-#endif
1538-
1539   /* Write out the patterns. */
1540   if (database_type == DB_CORNER)
1541     fprintf(outfile, "static struct corner_pattern %s[] = {\n", prefix);
1542@@ -2979,12 +2479,6 @@
1543     fprintf(outfile, " ,& dfa_%s\n", prefix); /* pointer to the wired dfa */
1544   else
1545     fprintf(outfile, " , NULL\n"); /* pointer to a possible dfa */
1546-#if EXPERIMENTAL_READING
1547-  if (database_type == DB_TREE)
1548-    fprintf(outfile, " , tnl_%s", prefix);
1549-  else
1550-    fprintf(outfile, " , NULL\n");
1551-#endif
1552 
1553   fprintf(outfile, "};\n");
1554 }
1555@@ -3013,13 +2507,13 @@
1556     int multiple_anchor_options = 0;
1557 
1558     /* Parse command-line options */
1559-    while ((i = gg_getopt(argc, argv, "i:o:t:vV:pcfCDTd:A:OXbma")) != EOF) {
1560+    while ((i = gg_getopt(argc, argv, "i:o:t:vV:pcfCDd:A:OXbma")) != EOF) {
1561       switch (i) {
1562       case 'i':
1563        if (input_files == MAX_INPUT_FILE_NAMES) {
1564          fprintf(stderr, "Error : Too many input files (maximum %d supported)\n",
1565            MAX_INPUT_FILE_NAMES);
1566-         return 1;
1567+         return EXIT_FAILURE;
1568         }
1569        input_file_names[input_files++] = gg_optarg;
1570        break;
1571@@ -3034,29 +2528,20 @@
1572       case 'f':
1573       case 'C':
1574       case 'D':
1575-      case 'T':
1576       case 'd':
1577        if (database_type) {
1578          fprintf(stderr, "Error : More than one database type specified (-%c and -%c)\n",
1579                  database_type, i);
1580          return 1;
1581        }
1582        database_type = i;
1583        if (i == 'd') {
1584          iterations = strtol(gg_optarg, NULL, 10);
1585          if (iterations < 0) {
1586            fprintf(stderr, "Error : Expected a non-negative number of iterations\n");
1587            return 1;
1588          }
1589        }
1590-
1591-#if EXPERIMENTAL_READING == 0
1592-       if (i == 'T') {
1593-         fprintf(stderr, "Error : Tree based matcher is unsupported in this configuration\n");
1594-         fprintf(stderr, "        Try `configure --enable-experimental-reading'\n");
1595-         return 1;
1596-       }
1597-#endif
1598        break;
1599 
1600       case 'O':
1601@@ -3384,8 +2869,8 @@
1602          }
1603 
1604          if (attributes_needed
1605-             && (database_type == DB_FULLBOARD || database_type == DB_TREE)) {
1606-           fprintf(stderr, "%s(%d) : Error : attributes other than `value' are not allowed in fullboard and tree databases\n",
1607+             && database_type == DB_FULLBOARD) {
1608+           fprintf(stderr, "%s(%d) : Error : attributes other than `value' are not allowed in fullboard databases\n",
1609                    current_file, current_line_number);
1610            fatal_errors++;
1611          }
1612Index: patterns/patterns.h
1613===================================================================
1614RCS file: /cvsroot/gnugo/gnugo/patterns/patterns.h,v
1615retrieving revision 1.70
1616diff -u -r1.70 patterns.h
1617--- patterns/patterns.h 16 Sep 2005 22:53:40 -0000      1.70
1618+++ patterns/patterns.h 23 Sep 2005 22:27:02 -0000
1619@@ -275,18 +275,11 @@
1620 };
1621 
1622 
1623-#if EXPERIMENTAL_READING
1624-struct tree_node_list;
1625-#endif
1626-
1627 struct pattern_db {
1628   int fixed_for_size;
1629   const int fixed_anchor;
1630   struct pattern *patterns;
1631   struct dfa_rt *pdfa;
1632-#if EXPERIMENTAL_READING
1633-  struct tree_node_list *tnl; /* For tree-based pattern matching */
1634-#endif
1635 };
1636 
1637 
1638@@ -334,23 +327,6 @@
1639 int break_mirror_helper(int str, int color);
1640 
1641 
1642-void init_tree_conn(void);
1643-void init_tree_pat(void);
1644-void init_tree_attpat(void);
1645-void init_tree_defpat(void);
1646-void init_tree_influencepat(void);
1647-void init_tree_barrierspat(void);
1648-void init_tree_endpat(void);
1649-void init_tree_aa_attackpat(void);
1650-void init_tree_owl_attackpat(void);
1651-void init_tree_owl_vital_apat(void);
1652-void init_tree_owl_defendpat(void);
1653-void init_tree_fusekipat(void);
1654-void init_tree_joseki(void);
1655-void init_tree_read_attack(void);
1656-void init_tree_read_defend(void);
1657-void init_tree_oracle(void);
1658-
1659 /* pattern arrays themselves */
1660 extern struct pattern_db pat_db;
1661 extern struct pattern_db aa_attackpat_db;
1662@@ -372,40 +348,6 @@
1663 extern struct fullboard_pattern fuseki19[];
1664 extern struct fullboard_pattern fuseki13[];
1665 extern struct fullboard_pattern fuseki9[];
1666-
1667-#if EXPERIMENTAL_READING
1668-
1669-/* Experimental reading */
1670-extern struct pattern_db read_attack_db;
1671-extern struct pattern_db read_defend_db;
1672-
1673-#endif
1674-
1675-/* Tree-based pattern matching structures*/
1676-
1677-struct match_node;
1678-struct tree_node_list;
1679-
1680-struct match_node {
1681-  int patnum;
1682-  int orientation;
1683-  struct match_node *next;
1684-};
1685-
1686-
1687-struct tree_node {
1688-  struct match_node *matches;
1689-  int att;
1690-  int x;
1691-  int y;
1692-  struct tree_node_list *next_list;
1693-};
1694-
1695-struct tree_node_list {
1696-  struct tree_node node;
1697-  struct tree_node_list *next;
1698-};
1699-
1700 
1701 struct corner_db;
1702 struct corner_variation;