Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

soarkernel.h

Go to the documentation of this file.
00001 /* This is silently disabling the msvc header file bug with warning level
00002    4 turned on.  See bugzilla bug 167 */
00003 #ifdef _MSC_VER
00004 #pragma warning(disable : 4115)
00005 #endif
00006 
00007 /*************************************************************************
00008  *
00009  *  file:  soarkernel.h
00010  *
00011  * =======================================================================
00012  *
00013  *                         Soar 6 Include File
00014  *
00015  * This file gets #included in all Soar 6 source files.  It defines all
00016  * sorts of constants and data structures, and gives prototype declarations
00017  * for various functions.
00018  * It also has insightful comments and detailed explanations and is
00019  * recommended reading for anyone who would like to know more about
00020  * the source code.
00021  * =======================================================================
00022  *
00023  *
00024  * Copyright 1995-2003 Carnegie Mellon University,
00025  *                                                                               University of Michigan,
00026  *                                                                               University of Southern California/Information
00027  *                                                                               Sciences Institute. All rights reserved.
00028  *                                                                              
00029  * Redistribution and use in source and binary forms, with or without
00030  * modification, are permitted provided that the following conditions are met:
00031  *
00032  * 1.   Redistributions of source code must retain the above copyright notice,
00033  *              this list of conditions and the following disclaimer. 
00034  * 2.   Redistributions in binary form must reproduce the above copyright notice,
00035  *              this list of conditions and the following disclaimer in the documentation
00036  *              and/or other materials provided with the distribution. 
00037  *
00038  * THIS SOFTWARE IS PROVIDED BY THE SOAR CONSORTIUM ``AS IS'' AND ANY EXPRESS OR
00039  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00040  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00041  * EVENT SHALL THE SOAR CONSORTIUM  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00042  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00043  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00044  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00045  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00046  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00047  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00048  * The views and conclusions contained in the software and documentation are
00049  * those of the authors and should not be interpreted as representing official
00050  * policies, either expressed or implied, of Carnegie Mellon University, the
00051  * University of Michigan, the University of Southern California/Information
00052  * Sciences Institute, or the Soar consortium.
00053  * =======================================================================
00054  */
00055 
00056 #ifndef _SOAR_H_INCLUDED        /* ExcludeFromBuildInfo */
00057 #define _SOAR_H_INCLUDED
00058 
00059 #ifndef _MSC_VER
00060 #define _GNU_SOURCE
00061 #endif
00062 
00063 #if defined(MACINTOSH)          /* excludeFromBuildInfo */
00064 #include <utime.h>
00065 #include <signal.h>
00066 #include <stdlib.h>
00067 #include <time.h>
00068 
00069 #elif defined(WIN32)            /* excludeFromBuildInfo */
00070 #include <stdlib.h>
00071 #include <time.h>
00072 #include <windows.h>
00073 
00074 #else
00075 #include <sys/time.h>
00076 #include <stdlib.h>
00077 #endif
00078 
00079 #include <string.h>
00080 #include <stdio.h>
00081 #include <stddef.h>
00082 
00083 #ifdef UNIX
00084 #include <unistd.h>
00085 #endif
00086 
00087 #include "soarBuildOptions.h"
00088 
00089 #ifndef MAX_SIMULTANEOUS_AGENTS
00090 #define MAX_SIMULTANEOUS_AGENTS 128
00091 #endif
00092 
00093 /*  kjc:  I don't understand what's up with all this __hpux stuff.
00094  *  when I took out all the embedded old stuff about THINK_C and
00095  *  __SC__, I'm left with __hpux defines and undefines that cancel
00096  *  each other out.  so this should be tested in HP's and this
00097  *  stuff should be removed if not needed...
00098  */
00099 /*  I changed the goofy stuff to this from agent.c : */
00100 #ifdef __hpux                   /* excludeFromBuildInfo */
00101 #ifndef _INCLUDE_POSIX_SOURCE   /* excludeFromBuildInfo */
00102 #define _INCLUDE_POSIX_SOURCE
00103 #endif
00104 #define _INCLUDE_XOPEN_SOURCE   /* excludeFromBuildInfo */
00105 #define _INCLUDE_HPUX_SOURCE    /* excludeFromBuildInfo */
00106 #include <sys/types.h>
00107 #undef  _INCLUDE_POSIX_SOURCE
00108 #undef  _INCLUDE_XOPEN_SOURCE
00109 #undef  _INCLUDE_HPUX_SOURCE
00110 #endif                          /* __hpux */
00111 
00112 #ifndef tolower
00113 /* I can't believe Sun's ctype.h doesn't have this. */
00114 extern int tolower(int);
00115 #endif
00116 
00117 #ifdef _MSC_VER
00118 #define snprintf _snprintf
00119 #define vsnprintf _vsnprintf
00120 #endif
00121 
00122 /* this is the size of the buffers used to print out error messages, etc */
00123 #define MESSAGE_SIZE 512
00124 /* size of the action attribute; used in rete.c, osupport.c */
00125 #define ACTION_ATTR_SIZE 50
00126 
00127 #include "sysdep.h"
00128 
00129 #ifdef __cplusplus              /* excludeFromBuildInfo */
00130 #define extern extern "C"
00131 #endif
00132 
00133 #define ABSTRACT_REPLAY 1
00134 
00135 #define current_agent(x) (soar_agent->x)
00136 
00137 #ifdef DC_HISTOGRAM
00138 
00139 #define increment_current_agent_d_cycle_count { \
00140   soar_agent->d_cycle_count++; \
00141   if ( soar_agent->d_cycle_count > soar_agent->dc_histogram_offset && \
00142        soar_agent->d_cycle_count % soar_agent->dc_histogram_freq == 0 && \
00143        (soar_agent->d_cycle_count / soar_agent->dc_histogram_freq) < \
00144        soar_agent->dc_histogram_sz ) { \
00145      soar_agent->dc_histogram_now = TRUE; \
00146   } \
00147 }
00148 
00149 #else
00150 
00151 #define increment_current_agent_d_cycle_count { \
00152   soar_agent->d_cycle_count++; \
00153 }
00154 
00155 #endif                          /* DC_HISTOGRAM */
00156 
00157 /* --------------------------- */
00158 /* Current Soar version number */
00159 /* --------------------------- */
00160 
00161 #define MAJOR_VERSION_NUMBER 8
00162 #define MINOR_VERSION_NUMBER 5
00163 #define MICRO_VERSION_NUMBER 0
00164 #define GREEK_VERSION_NUMBER ""
00165 
00166 extern char *soar_version_string;
00167 extern char *soar_news_string;
00168 
00169 /* REW: begin 05.05.97 */
00170 #define OPERAND2_MODE_NAME "Operand2/Waterfall"
00171 /* REW: end   05.05.97 */
00172 
00173 /* --------------------------------------------------------- */
00174 /* Line width of terminal (used for neatly formatted output) */
00175 /* --------------------------------------------------------- */
00176 
00177 #define COLUMNS_PER_LINE 80
00178 
00179 /* ------------------------------ */
00180 /* Global type declarations, etc. */
00181 /* ------------------------------ */
00182 
00183 typedef unsigned char byte;
00184 #ifndef HAVE_BOOL
00185 typedef char bool;
00186 #endif
00187 
00188 /* Some compilers define these. */
00189 #ifndef TRUE                    /* excludeFromBuildInfo */
00190 #define TRUE (1)
00191 #endif
00192 #ifndef FALSE                   /* excludeFromBuildInfo */
00193 #define FALSE (0)
00194 #endif
00195 
00196 #define NIL (0)
00197 
00198 #define EOF_AS_CHAR ((char)EOF)
00199 
00200 #ifdef PII_TIMERS
00201 #define TIMER_VALUE unsigned long long int
00202 #else
00203 #define TIMER_VALUE struct timeval
00204 #endif
00205 
00206 enum agent_id_state {
00207     UNTOUCHED,
00208     TOUCHED,
00209     ALLOCATED
00210 };
00211 
00212 /* Possible modes for numeric indifference */
00213 enum ni_mode {
00214     NUMERIC_INDIFFERENT_MODE_AVG,
00215     NUMERIC_INDIFFERENT_MODE_SUM,
00216 };
00217 
00218 /* ---------------------------------------------------------------------
00219      Macros for Inserting and Removing Stuff from Doubly-Linked Lists 
00220 
00221    Note: fast_remove_from_dll() is the same as remove_from_dll() except
00222    slightly faster.  I (RBD) only realized this after writing all the 
00223    original code.  With fast_remove_from_dll(), you have to tell it
00224    the type (i.e., structure name) of the item being spliced out of
00225    the list.  At some point we might want to go through all the code
00226    and have it use fast_remove_from_dll(), but it's probably not worth
00227    the effort right now.
00228 -------------------------------------------------------------------- */
00229 
00230 #define insert_at_head_of_dll(header,item,next_field_name,prev_field_name) { \
00231   ((item)->next_field_name) = (header) ; \
00232   ((item)->prev_field_name) = NIL ; \
00233   if (header) ((header)->prev_field_name) = (item) ; \
00234   (header) = (item) ; }
00235 
00236 #define remove_from_dll(header,item,next_field_name,prev_field_name) { \
00237   if ((item)->next_field_name) \
00238     ((item)->next_field_name->prev_field_name) = ((item)->prev_field_name); \
00239   if ((item)->prev_field_name) { \
00240     ((item)->prev_field_name->next_field_name) = ((item)->next_field_name); \
00241   } else { \
00242     (header) = ((item)->next_field_name); \
00243   } }
00244 
00245 #define fast_remove_from_dll(header,item,typename,next_field_name,prev_field_name) { \
00246   typename *tempnext, *tempprev; \
00247   tempnext = (item)->next_field_name; \
00248   tempprev = (item)->prev_field_name; \
00249   if (tempnext) tempnext->prev_field_name = tempprev; \
00250   if (tempprev) { \
00251     tempprev->next_field_name = tempnext; \
00252   } else { \
00253     (header) = tempnext; } }
00254 
00255 /* ----------------- */
00256 /* Goal Stack Levels */
00257 /* ----------------- */
00258 
00259 typedef signed short goal_stack_level;
00260 #define TOP_GOAL_LEVEL 1
00261 #define ATTRIBUTE_IMPASSE_LEVEL 32767
00262 #define LOWEST_POSSIBLE_GOAL_LEVEL 32767
00263 
00264 /* -------------------------------------------------- */
00265 /*              Names of Rete Structures              */
00266 /* (only pointers to these are used outside the rete) */
00267 /* -------------------------------------------------- */
00268 
00269 struct token_struct;
00270 struct rete_node_struct;
00271 
00272 /* REW: begin 08.20.97 */
00273 /* The ms_change_struct is exported to the entire system
00274    (for better or worse) so
00275    this restricted definition is no longer necessary. */
00276 /* struct ms_change_struct; */
00277 /* REW: end 08.20.97 */
00278 
00279 struct node_varnames_struct;
00280 
00281 /* --------------------------------------------------------------------
00282                     Transitive Closure Numbers
00283 
00284    In many places, we do transitive closures or some similar process in
00285    which we mark identifiers and/or variables so as not to repeat them
00286    later.  Marking is done by setting the "tc_num" field of the symbol
00287    to the "current transitive closure number".  We don't have to go
00288    back and unmark stuff when done--we just increment the current
00289    transitive closure number next time.  Whenever we need to start a
00290    new marking, we call get_new_tc_number() (see production.c comments
00291    below).
00292 -------------------------------------------------------------------- */
00293 
00294 typedef unsigned long tc_number;
00295 
00296 /* ======================================================================
00297                                  mem.c
00298 
00299    Init_memory_utilities() should be called before any of these routines
00300    are used.
00301 
00302    Basic memory allocation utilities:
00303 
00304      All memory blocks are allocated via calls to allocate_memory().  It
00305      calls malloc() and aborts if we run out of memory.  Free_memory() is
00306      the inverse of allocate_memory().  Allocate_memory_and_zerofill()
00307      does the obvious thing.  These routines take a usage_code indicating
00308      what purpose the memory is for (hash tables, strings, etc.).  This
00309      is used purely for statistics keeping.
00310 
00311      the API function, soar_ecPrintMemoryStatistics(), prints out
00312      stats on the memory usage.
00313 
00314    String utilities:
00315 
00316      Make_memory_block_for_string() takes a pointer to a string, allocates
00317      a memory block just large enough to hold the string, and copies the
00318      string into the block.   Free_memory_block_for_string() frees the
00319      block.
00320      
00321      "Growable strings" provide a convenient way of building up a string
00322      piece by piece without having to pre-allocate the right amount of
00323      memory.  To initialize one, say "gs = make_blank_growable_string()"
00324      where "gs" is of type "growable_string".  To concatenate a new string
00325      onto the end of an existing growable string, call
00326      add_to_growable_string(&gs,new_string) [note the "&"].  When you're
00327      done using it, call free_growable_string(gs).  Growable strings are
00328      implemented by allocating a block of memory large enough to hold
00329      (1) the memory block's size, (2) the current string length, and (3)
00330      the current text of the string.  Add_to_growable_string() may result
00331      in a new (larger) memory block being allocated and the text of the 
00332      string being copied.  Three macros provide access to a growable string's
00333      parts:  memsize_of_growable_string(), length_of_growable_string(),
00334      and (most importantly) text_of_growable_string(), which is of type
00335      (char *).
00336      
00337    Memory pools:
00338 
00339      To allocate and free memory items efficiently at run time, we use
00340      pools of small fixed-size items and do allocation and freeing using
00341      inline macros.  Different memory pools are used for different things
00342      and contain different size items.  Each pool consists of a memory_pool
00343      structure (used for maintaining the pool) and a chain of big blocks
00344      of memory (currently about 32K per block) obtained from allocate_memory().
00345      We maintain a free_list of small items not being used, and allocate by
00346      grabbing the first item on the free list.  If the free list is empty,
00347      we add another big block to the pool.
00348 
00349      Init_memory_pool() should be called to initialize a memory_pool
00350      structure before it is used.  After that, the macro forms
00351      allocate_with_pool (&mem_pool, &pointer_to_be_set_to_new_item)
00352      and free_with_pool (&mem_pool, pointer_to_item) are used to
00353      allocate and free items.  The API Function,
00354      soar_ecPrintMemoryPoolStatistics(), prints stats about the
00355      various pools in use and how much memory each is using.
00356 
00357    Cons cell and list utilities:
00358 
00359      This provides a simple facility for manipulating generic lists, just
00360      like in Lisp.  A "cons" is a pair of pointers; a "list" is just a cons
00361      (or NIL).  We maintain a memory pool (see above) of conses.
00362      Allocate_cons() is like allocate_with_pool() for conses; free_cons()
00363      is like free_with_pool.  Push(new_item,my_list) is a macro for adding
00364      a new item onto the front of an existing list.
00365 
00366      In addition to the regular conses, we also have a pool of "dl_cons"es--
00367      these are like conses, only doubly-linked.  A "dl_list" is a just a
00368      dl_cons (or NIL).
00369 
00370      Some (consed) list utility functions:  destructively_reverse_list()
00371      does just what it says, and returns a pointer to the new head of the
00372      list (formerly the tail).  Member_of_list() tests membership, using
00373      "==" as the equality predicates.  Add_if_not_member() is like Lisp's
00374      "pushnew"; it returns the new list (possibly unchanged) list.
00375      Free_list() frees all the cons cells in the list.
00376 
00377      Sometimes we need to surgically extract particular elements from a
00378      list.  Extract_list_elements() and extract_dl_list_elements() do this.
00379      They use a callback function that indicates which elements to extract:
00380      the callback function is called on each element of the list, and should
00381      return TRUE for the elements to be extracted.  The two extraction
00382      functions return a list (or dl_list) of the extracted elements.
00383 
00384    Hash table routines:
00385 
00386      We use hash tables in various places, and don't want to have to fix
00387      their size ahead of time.  These routines provide hash tables that
00388      are dynamically resized as items are added and removed.  We use
00389      "open hashing" with a hash table whose size is a power of two.  We
00390      keep track of how many items are in the table.  The table grows
00391      when # of items >= 2*size, and shrinks when # of items < size/2.
00392      To resize a hash table, we rehash every item in it.
00393 
00394      Each item must be a structure whose first field is reserved for use
00395      by these hash table routines--it points to the next item in the hash
00396      bucket.  Hash tables are created and initialized via make_hash_table();
00397      you give it a hash function (i.e., a C function) that finds the hash
00398      value for a given item, hashing it to a value num_bits wide.  For aid
00399      in this, we provide masks_for_n_low_order_bits[] that select out the
00400      low-order bits of a value:  (x & masks_for_n_low_order_bits[23]) picks
00401      out the 23 low-order bits of x.
00402      
00403      Items are added/removed from a hash table via add_to_hash_table() and
00404      remove_from_hash_table().  These calls resize the hash table if
00405      necessary.
00406      
00407      The contents of a hash table (or one bucket in the table) can be
00408      retrieved via do_for_all_items_in_hash_table() and
00409      do_for_all_items_in_hash_bucket().  Each uses a callback function,
00410      invoking it with each successive item.  The callback function should
00411      normally return FALSE.  If the callback function ever returns TRUE,
00412      iteration over the hash table items stops and the do_for_xxx()
00413      routine returns immediately.  
00414 ====================================================================== */
00415 
00416 extern void init_memory_utilities(void);
00417 
00418 /* ----------------------- */
00419 /* basic memory allocation */
00420 /* ----------------------- */
00421 
00422 #define MISCELLANEOUS_MEM_USAGE  0
00423 #define HASH_TABLE_MEM_USAGE     1
00424 #define STRING_MEM_USAGE         2
00425 #define POOL_MEM_USAGE           3
00426 #define STATS_OVERHEAD_MEM_USAGE 4
00427 
00428 #define NUM_MEM_USAGE_CODES 5
00429 
00430 #ifdef DEBUG_MEMORY
00431 #define fill_with_garbage(block,size) memset((void *)(block), 0xBB, (size))
00432 #else
00433 #define fill_with_garbage(block,size) { }
00434 #endif
00435 
00436 extern void *allocate_memory(unsigned long size, int usage_code);
00437 extern void *allocate_memory_and_zerofill(unsigned long size, int usage_code);
00438 extern void free_memory(void *mem, int usage_code);
00439 
00440 /* ---------------- */
00441 /* string utilities */
00442 /* ---------------- */
00443 
00444 #define savestring(x) (char *) strcpy ( (char *)malloc (strlen (x) + 1), (x))   /* this is relatively safe since the proper amount of memory is allocated */
00445 
00446 extern char *make_memory_block_for_string(const char *s);
00447 extern void free_memory_block_for_string(char *p);
00448 
00449 typedef void *growable_string;
00450 
00451 #define memsize_of_growable_string(gs) (*((int *)(gs)))
00452 #define length_of_growable_string(gs) (*(((int *)(gs))+1))
00453 #define text_of_growable_string(gs) (((char *)(gs)) + 2*sizeof(int *))
00454 
00455 extern growable_string make_blank_growable_string(void);
00456 extern void add_to_growable_string(growable_string * gs, char *string_to_add);
00457 extern void free_growable_string(growable_string gs);
00458 
00459 /* ------------ */
00460 /* memory pools */
00461 /* ------------ */
00462 
00463 #define MAX_POOL_NAME_LENGTH 15
00464 
00465 typedef struct memory_pool_struct {
00466     void *free_list;            /* header of chain of free items */
00467 #ifdef MEMORY_POOL_STATS
00468     long used_count;            /* for statistics only */
00469 #endif
00470 #ifdef TRACK_MEMORY_USAGE
00471     long free_list_length;
00472     long pool_size;
00473 #endif
00474 
00475     long item_size;             /* bytes per item */
00476     long items_per_block;       /* number of items in each big block */
00477     long num_blocks;            /* number of big blocks in use by this pool */
00478     void *first_block;          /* header of chain of blocks */
00479     char name[MAX_POOL_NAME_LENGTH];    /* name of the pool (for memory-stats) */
00480     struct memory_pool_struct *next;    /* next in list of all memory pools */
00481 } memory_pool;
00482 
00483 extern void add_block_to_memory_pool(memory_pool * p);
00484 extern void init_memory_pool(memory_pool * p, long item_size, char *name);
00485 
00486 #ifdef MEMORY_POOL_STATS
00487 #define increment_used_count(p) {(p)->used_count++;}
00488 #define decrement_used_count(p) {(p)->used_count--;}
00489 #else
00490 #define increment_used_count(p) { }
00491 #define decrement_used_count(p) { }
00492 #endif
00493 
00494 #ifdef TRACK_MEMORY_USAGE
00495 #define decrement_free_list_length(p) {(p)->free_list_length--;}
00496 #define increment_free_list_length(p) {(p)->free_list_length++;}
00497 #else
00498 #define decrement_free_list_length(p) { }
00499 #define increment_free_list_length(p) { }
00500 #endif
00501 
00502 #ifdef USE_DEBUG_UTILS
00503 
00504 #define allocate_with_pool(p,dest_item_pointer) allocate_with_pool_fn( (p), (void *) (dest_item_pointer) )
00505 
00506 #define free_with_pool(p,item) free_with_pool_fn( (p), (item) )
00507 
00508 extern void allocate_with_pool_fn(memory_pool * p, void **dest);
00509 extern void free_with_pool_fn(memory_pool * p, void *item);
00510 
00511 #else
00512 
00513 #define allocate_with_pool(p,dest_item_pointer) { \
00514   if (! (p)->free_list) add_block_to_memory_pool(p); \
00515   (*(dest_item_pointer)) = (p)->free_list; \
00516   (p)->free_list =  *(void * *)(*(dest_item_pointer)); \
00517   fill_with_garbage (*(dest_item_pointer), (p)->item_size); \
00518   increment_used_count(p); \
00519   decrement_free_list_length(p); }
00520 
00521 #define free_with_pool(p,item) { \
00522   fill_with_garbage ((item), (p)->item_size); \
00523   *(void * *)(item) = (p)->free_list; \
00524   (p)->free_list = (void *)(item); \
00525   decrement_used_count(p); \
00526   increment_free_list_length(p); }
00527 
00528 #endif
00529 
00530 /* ------------------------- */
00531 /* Cons cell, list utilities */
00532 /* ------------------------- */
00533 
00534 typedef struct cons_struct {
00535     void *first;
00536     struct cons_struct *rest;
00537 } cons;
00538 
00539 typedef cons list;
00540 
00541 typedef struct dl_cons_struct {
00542     void *item;
00543     struct dl_cons_struct *next;
00544     struct dl_cons_struct *prev;
00545 } dl_cons;
00546 
00547 typedef dl_cons dl_list;
00548 
00549 #define allocate_cons(dest_cons_pointer) \
00550   allocate_with_pool (&current_agent(cons_cell_pool), (void **)(dest_cons_pointer))
00551 #define free_cons(c) free_with_pool (&current_agent(cons_cell_pool), (c))
00552 
00553 #define push(item,list_header) { \
00554   cons *push_cons_xy298; \
00555   allocate_cons ((void **)&push_cons_xy298); \
00556   push_cons_xy298->first = (item); \
00557   push_cons_xy298->rest = (list_header); \
00558   (list_header) = push_cons_xy298; }
00559 
00560 extern list *destructively_reverse_list(list * c);
00561 extern bool member_of_list(void *item, list * the_list);
00562 extern list *add_if_not_member(void *item, list * old_list);
00563 extern void free_list(list * the_list);
00564 
00565 typedef bool(*cons_test_fn) (cons * c);
00566 typedef bool(*dl_cons_test_fn) (dl_cons * dc);
00567 
00568 extern list *extract_list_elements(list ** header, cons_test_fn f);
00569 extern dl_list *extract_dl_list_elements(dl_list ** header, dl_cons_test_fn f);
00570 
00571 /* ----------------------------- */
00572 /* Resizable hash table routines */
00573 /* ----------------------------- */
00574 
00575 extern unsigned long masks_for_n_low_order_bits[33];
00576 typedef unsigned long ((*hash_function) (void *item, short num_bits));
00577 
00578 typedef struct item_in_hash_table_struct {
00579     struct item_in_hash_table_struct *next;
00580     char data;
00581 } item_in_hash_table;
00582 
00583 typedef item_in_hash_table *bucket_array;
00584 
00585 typedef struct hash_table_struct {
00586     unsigned long count;        /* number of items in the table */
00587     unsigned long size;         /* number of buckets */
00588     short log2size;             /* log (base 2) of size */
00589     short minimum_log2size;     /* table never shrinks below this size */
00590     bucket_array *buckets;
00591     hash_function h;            /* call this to hash or rehash an item */
00592 } hash_table;
00593 
00594 extern struct hash_table_struct *make_hash_table(short minimum_log2size, hash_function h);
00595 extern void remove_from_hash_table(struct hash_table_struct *ht, void *item);
00596 extern void add_to_hash_table(struct hash_table_struct *ht, void *item);
00597 
00598 typedef bool(*hash_table_callback_fn) (void *item);
00599 
00600 extern void do_for_all_items_in_hash_table(struct hash_table_struct *ht, hash_table_callback_fn f);
00601 extern void do_for_all_items_in_hash_bucket(struct hash_table_struct *ht,
00602                                             hash_table_callback_fn f, unsigned long hash_value);
00603 
00604 /* ======================================================================
00605                              lexer.c
00606 
00607   The lexer reads files and returns a stream of lexemes.  Get_lexeme() is
00608   the main routine; it looks for the next lexeme in the input, and stores
00609   it in the global variable "lexeme".  See the structure definition below.
00610 
00611   Restrictions:  the lexer cannot read individual input lines longer than
00612   MAX_LEXER_LINE_LENGTH characters.  Thus, a single lexeme can't be longer
00613   than that either.
00614 
00615   The lexer maintains a stack of files being read, in order to handle nested
00616   loads.  Start_lex_from_file() and stop_lex_from_file() push and pop the
00617   stack.  Immediately after start_lex_from_file(), the current lexeme (global
00618   variable) is undefined.  Immediately after stop_lex_from_file(), the 
00619   current lexeme is automatically restored to whatever it was just before
00620   the corresponding start_lex_from_file() call.
00621   
00622   Determine_possible_symbol_types_for_string() is a utility routine which
00623   figures out what kind(s) of symbol a given string could represent.
00624   
00625   Print_location_of_most_recent_lexeme() is used to print an indication
00626   of where a parser error occurred.  It tries to print out the current
00627   source line with a pointer to where the error was detected.
00628   
00629   Current_lexer_parentheses_level() returns the current level of parentheses
00630   nesting (0 means no open paren's have been encountered).
00631   Skip_ahead_to_balanced_parentheses() eats lexemes until the appropriate
00632   closing paren is found (0 means eat until back at the top level).
00633   
00634   Fake_rparen_at_next_end_of_line() tells the lexer to insert a fake
00635   R_PAREN_LEXEME token the next time it reaches the end of a line.
00636   
00637   Set_lexer_allow_ids() tells the lexer whether to allow identifiers to
00638   be read.  If FALSE, things that look like identifiers will be returned
00639   as SYM_CONSTANT_LEXEME's instead.
00640 ====================================================================== */
00641 
00642 #define reading_from_top_level() (! current_agent(current_file)->parent_file)
00643 
00644 #define MAX_LEXER_LINE_LENGTH 1000
00645 #define MAX_LEXEME_LENGTH (MAX_LEXER_LINE_LENGTH+5)     /* a little bigger to avoid
00646                                                            any off-by-one-errors */
00647 
00648 enum lexer_token_type {
00649     EOF_LEXEME,                 /* end-of-file */
00650     IDENTIFIER_LEXEME,          /* identifier */
00651     VARIABLE_LEXEME,            /* variable */
00652     SYM_CONSTANT_LEXEME,        /* symbolic constant */
00653     INT_CONSTANT_LEXEME,        /* integer constant */
00654     FLOAT_CONSTANT_LEXEME,      /* floating point constant */
00655     L_PAREN_LEXEME,             /* "(" */
00656     R_PAREN_LEXEME,             /* ")" */
00657     L_BRACE_LEXEME,             /* "{" */
00658     R_BRACE_LEXEME,             /* "}" */
00659     PLUS_LEXEME,                /* "+" */
00660     MINUS_LEXEME,               /* "-" */
00661     RIGHT_ARROW_LEXEME,         /* "-->" */
00662     GREATER_LEXEME,             /* ">" */
00663     LESS_LEXEME,                /* "<" */
00664     EQUAL_LEXEME,               /* "=" */
00665     LESS_EQUAL_LEXEME,          /* "<=" */
00666     GREATER_EQUAL_LEXEME,       /* ">=" */
00667     NOT_EQUAL_LEXEME,           /* "<>" */
00668     LESS_EQUAL_GREATER_LEXEME,  /* "<=>" */
00669     LESS_LESS_LEXEME,           /* "<<" */
00670     GREATER_GREATER_LEXEME,     /* ">>" */
00671     AMPERSAND_LEXEME,           /* "&" */
00672     AT_LEXEME,                  /* "@" */
00673     TILDE_LEXEME,               /* "~" */
00674     UP_ARROW_LEXEME,            /* "^" */
00675     EXCLAMATION_POINT_LEXEME,   /* "!" */
00676     COMMA_LEXEME,               /* "," */
00677     PERIOD_LEXEME,              /* "." */
00678     QUOTED_STRING_LEXEME,       /* string in double quotes */
00679     DOLLAR_STRING_LEXEME
00680 };                              /* string for shell escape */
00681 
00682 #define LENGTH_OF_LONGEST_SPECIAL_LEXEME 3      /* length of "-->" and "<=>"--
00683                                                    if a longer one is added, be
00684                                                    sure to update this! */
00685 
00686 struct lexeme_info {
00687     enum lexer_token_type type; /* what kind of lexeme it is */
00688     char string[MAX_LEXEME_LENGTH + 1]; /* text of the lexeme */
00689     int length;                 /* length of the above string */
00690     long int_val;               /* for INT_CONSTANT_LEXEME's */
00691     float float_val;            /* for FLOAT_CONSTANT_LEXEME's */
00692     char id_letter;             /* for IDENTIFIER_LEXEME's */
00693     unsigned long id_number;    /* for IDENTIFIER_LEXEME's */
00694 };
00695 
00696 extern void determine_possible_symbol_types_for_string(char *s,
00697                                                        int length_of_s,
00698                                                        bool * possible_id,
00699                                                        bool * possible_var,
00700                                                        bool * possible_sc,
00701                                                        bool * possible_ic, bool * possible_fc, bool * rereadable);
00702 
00703 extern void init_lexer(void);
00704 extern void start_lex_from_file(char *filename, FILE * already_opened_file);
00705 extern void stop_lex_from_file(void);
00706 
00707 extern void get_lexeme(void);
00708 extern void print_location_of_most_recent_lexeme(void);
00709 
00710 extern int current_lexer_parentheses_level(void);
00711 extern void skip_ahead_to_balanced_parentheses(int parentheses_level);
00712 extern void fake_rparen_at_next_end_of_line(void);
00713 extern void set_lexer_allow_ids(bool allow_identifiers);
00714 
00715 extern void determine_type_of_constituent_string(void);
00716 
00717 /* (RBD) the rest of this stuff shouldn't be in the module interface... */
00718 
00719 #define BUFSIZE (MAX_LEXER_LINE_LENGTH+2)       /* +2 for newline and null at end */
00720 
00721 /* --- we'll use one of these structures for each file being read --- */
00722 
00723 typedef struct lexer_source_file_struct {
00724     struct lexer_source_file_struct *parent_file;
00725     char *filename;
00726     FILE *file;
00727     bool fake_rparen_at_eol;
00728     bool allow_ids;
00729     int parentheses_level;      /* 0 means top level, no left paren's seen */
00730     int current_column;         /* column number of next char to read (0-based) */
00731     unsigned long current_line; /* line number of line in buffer (1-based) */
00732     int column_of_start_of_last_lexeme; /* (used for error messages) */
00733     unsigned long line_of_start_of_last_lexeme;
00734     char buffer[BUFSIZE];       /* holds text of current input line */
00735     struct lexeme_info saved_lexeme;    /* save/restore it during nested loads */
00736     char saved_current_char;    /* save/restore this too */
00737 } lexer_source_file;
00738 
00739 /* =======================================================================
00740                              symtab.c
00741 
00742    Soar 6 uses five kinds of symbols:  symbolic constants, integer
00743    constants, floating-point constants, identifiers, and variables.
00744    We use five resizable hash tables, one for each kind of symbol.
00745 
00746    "symbol" is typedef-ed as a union of the five kinds of symbol
00747    structures.  Some fields common to all symbols are accessed via
00748    sym->common.field_name; fields particular to a certain kind of
00749    symbol are accessed via sym->var.field_name_on_variables, etc.
00750    (See the definitions below.)  Note that "common" is #defined below.
00751 
00752    Some (but not all) of the fields common to all symbols are:
00753       symbol_type:  indicates which of the five kinds of symbols this is
00754       reference_count:  current reference count for this symbol
00755       hash_id:  used for hash functions in the rete (and elsewhere)
00756       
00757    Fields on symbolic constants:
00758       name:  points to null-terminated string giving its name
00759       production:  points to a production structure, or NIL if there is
00760                    no production with that name
00761 
00762    Fields on integer constants:
00763       value:  gives the value of the symbol.  This is of type (long).
00764 
00765    Fields on floating-point constants:
00766       value:  gives the value of the symbol.  This is of type (float).
00767 
00768    Fields on variables:
00769       name:  points to null-terminated string giving its name
00770       tc_num:  used for transitive closure computations
00771       current_binding_value:  when productions are fired, this indicates
00772                               the variable's binding
00773       gensym_number:  used by the variable generator to prevent certain
00774                       already-in-use variables from being generated
00775       rete_binding_locations:  used temporarily by the Rete, while adding
00776                       productions, to store a list of places where this
00777                       variable is bound and/or tested
00778 
00779    Fields on identifiers:
00780 
00781        name_number, name_letter:  indicate the name of the identifier
00782 
00783        isa_goal, isa_impasse:  indicate whether this is the identifier of a
00784                                goal or attribute impasse
00785 
00786        isa_operator:  keeps a count of how many (normal or acceptable
00787                       preference) wmes contain (^operator <this-id>).
00788                       The tracing code uses this to figure out whether
00789                       a given object is an operator.
00790 
00791        allow_bottom_up_chunks:  Used for bottom-up chunking, and only on goal
00792          identifiers.  This is TRUE iff no chunk has yet been built for a
00793          subgoal of this goal.
00794         
00795        could_be_a_link_from_below:  TRUE if there might be a link to this id
00796          from some other id lower in the goal stack.
00797 
00798        did_PE: 
00799 
00800        level:  current goal_stack_level of this id
00801 
00802        promotion_level:  level to which this id is going to be promoted as
00803          soon as ownership info is updated.
00804 
00805        link_count:  count of how many links there are to this id.
00806 
00807        unknown_level:  if the goal_stack_level of this id is known, this is
00808          NIL.  If the level isn't known, it points to a dl_cons in a dl_list
00809          used by the demotion routines.
00810 
00811        slots:  this is the header for a dll of the slots for this id.
00812 
00813        tc_num:  used for transitive closures, marking id's, etc.
00814  
00815        variablization:  used by the chunker when variablizing chunks--this
00816          points to the variable to which this id gets changed
00817 
00818        impasse_wmes:  for goal and impasse ids only:  this is the header
00819          of the dll of architecture-created wmes (e.g., (G37 ^object G36))
00820 
00821        higher_goal, lower_goal:  for goals, these point to adjacent goals
00822          in the context stack
00823        problem_space_slot, state_slot, operator_slot:  for goals, these
00824          point to the corresponding context slots
00825        preferences_from_goal:  for goals, this is the header of the dll
00826          of all preferences supported by this goal.  This is needed so
00827          we can remove o-supported preferences when the goal goes away.
00828 
00829        gds: pointer to a goal's dependency set
00830        saved_firing_type: the firing type that must be restored if
00831           Waterfall processing returns to this level. see consistency.c
00832        ms_o_assertions:  dll of o-assertions at this level
00833        ms_i_assertions:  dll of i-assertions at this level
00834        ms_retractions:   dll of all retractions at this level
00835 
00836        associated_output_links:  used by the output module
00837 
00838        input_wmes:  dll of wmes added by input functions
00839 
00840    Reference counting for symbols:  I can't remember all the places I add
00841      reference counts to symbols.  Here's a bunch I can remember though.
00842      If you're not sure whether to add/remove a reference for something,
00843      it's better to play it safe and do the add/remove.
00844 
00845      +1 for each occurrence in a rete test or alpha mem constant test
00846      +1 for each occurrence in a condition test anywhere
00847      +1 for each occurrence in a Not
00848      +1 for each occurrence in a saved_test
00849      +1 for each occurrence in a WME
00850      +1 for each occurrence in a preference
00851      +1 for each occurrence as {id or attr} of a slot
00852      +1 for goal/impasse identifiers
00853      +1 if it's the name of a production
00854      +1 if it's a predefined symbol (e.g., "goal" or "operator")
00855      +1 for each enqueued add-link or remove-link to/from it
00856      +1 for each occurrence in a global var. (e.g., chunk-free-problem-spaces)
00857 
00858   We deallocate a symbol when its reference count goes to 0.
00859 ======================================================================= */
00860 
00861 #define VARIABLE_SYMBOL_TYPE 0
00862 #define IDENTIFIER_SYMBOL_TYPE 1
00863 #define SYM_CONSTANT_SYMBOL_TYPE 2
00864 #define INT_CONSTANT_SYMBOL_TYPE 3
00865 #define FLOAT_CONSTANT_SYMBOL_TYPE 4
00866 
00867 /* WARNING:  In the following structure, next_in_hash_table MUST be the
00868    first field.  This field is used by the resizable hash table routines. */
00869 
00870 typedef struct symbol_common_data_struct {
00871     union symbol_union *next_in_hash_table;     /* next item in hash bucket */
00872     unsigned long reference_count;
00873     byte symbol_type;           /* one of the above xxx_SYMBOL_TYPE's */
00874     byte decider_flag;          /* used only by the decider */
00875     union a_union {
00876         struct wme_struct *decider_wme; /* used only by the decider */
00877         unsigned long retesave_symindex;        /* used for rete fastsave/fastload */
00878     } a;
00879     unsigned long hash_id;      /* used for hashing in the rete */
00880 } symbol_common_data;
00881 
00882 /* WARNING:  In the following structures (the five kinds of symbols),
00883    common_symbol_info MUST be the first field. */
00884 
00885 typedef struct sym_constant_struct {
00886     symbol_common_data common_symbol_info;
00887     char *name;
00888     struct production_struct *production;       /* NIL if no prod. has this name */
00889 } sym_constant;
00890 
00891 typedef struct int_constant_struct {
00892     symbol_common_data common_symbol_info;
00893     long value;
00894 } int_constant;
00895 
00896 typedef struct float_constant_struct {
00897     symbol_common_data common_symbol_info;
00898     float value;
00899 } float_constant;
00900 
00901 typedef struct variable_struct {
00902     symbol_common_data common_symbol_info;
00903     char *name;
00904     tc_number tc_num;
00905     union symbol_union *current_binding_value;
00906     unsigned long gensym_number;
00907     list *rete_binding_locations;
00908 } variable;
00909 
00910 /* Note: I arranged the fields below to try to minimize space */
00911 typedef struct identifier_struct {
00912     symbol_common_data common_symbol_info;
00913     unsigned long name_number;
00914     char name_letter;
00915 
00916     bool isa_goal;              /* TRUE iff this is a goal identifier */
00917     bool isa_impasse;           /* TRUE iff this is an attr. impasse identifier */
00918 
00919     bool did_PE;                /* RCHONG: 10.11 */
00920 
00921     unsigned short isa_operator;
00922 
00923     bool allow_bottom_up_chunks;
00924 
00925     /* --- ownership, promotion, demotion, & garbage collection stuff --- */
00926     bool could_be_a_link_from_below;
00927     goal_stack_level level;
00928     goal_stack_level promotion_level;
00929     unsigned long link_count;
00930     dl_cons *unknown_level;
00931 
00932     struct slot_struct *slots;  /* dll of slots for this identifier */
00933     tc_number tc_num;           /* used for transitive closures, marking, etc. */
00934     union symbol_union *variablization; /* used by the chunker */
00935 
00936     /* --- fields used only on goals and impasse identifiers --- */
00937     struct wme_struct *impasse_wmes;
00938 
00939     /* --- fields used only on goals --- */
00940     union symbol_union *higher_goal, *lower_goal;
00941     struct slot_struct *operator_slot;
00942     struct preference_struct *preferences_from_goal;
00943 
00944     /* REW: begin 09.15.96 */
00945     struct gds_struct *gds;     /* Pointer to a goal's dependency set */
00946     /* REW: begin 09.15.96 */
00947 
00948     /* REW: begin 08.20.97 */
00949     int saved_firing_type;      /* FIRING_TYPE that must be restored if Waterfall
00950                                    processing returns to this level.
00951                                    See consistency.c */
00952     struct ms_change_struct *ms_o_assertions;   /* dll of o assertions at this level */
00953     struct ms_change_struct *ms_i_assertions;   /* dll of i assertions at this level */
00954     struct ms_change_struct *ms_retractions;    /* dll of retractions at this level */
00955     /* REW: end   08.2097 */
00956 
00957     /* --- fields used for Soar I/O stuff --- */
00958     list *associated_output_links;
00959     struct wme_struct *input_wmes;
00960 } identifier;
00961 
00962 typedef union symbol_union {
00963     variable var;
00964     identifier id;
00965     sym_constant sc;
00966     int_constant ic;
00967     float_constant fc;
00968 } Symbol;
00969 
00970 /* WARNING: this #define's "common".  Don't use "common" anywhere in the
00971    code unless you intend this meaning of it.  This is so we can
00972    conveniently access fields used in all kinds of symbols, like this:
00973    "sym.common.reference_count" rather than "sym.var.common.reference_count"
00974    or "sym.id.common.reference_count", etc. */
00975 
00976 #define common var.common_symbol_info
00977 
00978 /* -----------------------------------------------------------------
00979                        Symbol Table Routines
00980 
00981    Initialization:
00982 
00983      Init_symbol_tables() should be called first, to initialize the
00984      module.
00985 
00986    Lookup and Creation:
00987 
00988      The find_xxx() routines look for an existing symbol and return it
00989      if found; if no such symbol exists, they return NIL.
00990 
00991      The make_xxx() routines look for an existing symbol; if the find one,
00992      they increment the reference count and return it.  If no such symbol
00993      exists, they create a new one, set the reference count to 1, and
00994      return it.
00995 
00996      Note that rather than a make_identifier() routine, we have a
00997      make_new_identifier() routine, which takes two arguments: the first
00998      letter for the new identifier, and its initial goal_stack_level.
00999      There is no way to force creation of an identifier with a particular
01000      name letter/number combination like J37.
01001 
01002    Reference Counting:
01003 
01004      Symbol_add_ref() and symbol_remove_ref() are macros for incrementing
01005      and decrementing the reference count on a symbol.  When the count
01006      goes to zero, symbol_remove_ref() calls deallocate_symbol().
01007 
01008    Other Utilities:
01009 
01010      Reset_id_counters() is called during an init-soar to reset the id
01011      gensym numbers to 1.  It first makes sure there are no existing
01012      identifiers in the system--otherwise we might generate a second
01013      identifier with the same name later on.
01014 
01015      Reset_id_and_variable_tc_numbers() resets the tc_num field of every
01016      existing id and variable to 0.
01017      
01018      Reset_variable_gensym_numbers() resets the gensym_number field of
01019      every existing variable to 0.
01020      
01021      Print_internal_symbols() just prints a list of all existing symbols.
01022      (This is useful for debugging memory leaks.)
01023      
01024      Generate_new_sym_constant() is used to gensym new symbols that are
01025      guaranteed to not already exist.  It takes two arguments: "prefix"
01026      (the desired prefix of the new symbol's name), and "counter" (a
01027      pointer to a counter (unsigned long) that is incremented to produce
01028      new gensym names).
01029 ----------------------------------------------------------------- */
01030 
01031 extern void init_symbol_tables(void);
01032 
01033 extern Symbol *find_variable(char *name);
01034 extern Symbol *find_identifier(char name_letter, unsigned long name_number);
01035 extern Symbol *find_sym_constant(const char *name);     /* AGR 600 */
01036 extern Symbol *find_int_constant(long value);
01037 extern Symbol *find_float_constant(float value);
01038 
01039 extern Symbol *make_variable(char *name);
01040 extern Symbol *make_sym_constant(const char *name);
01041 extern Symbol *make_int_constant(long value);
01042 extern Symbol *make_float_constant(float value);
01043 extern Symbol *make_new_identifier(char name_letter, goal_stack_level level);
01044 
01045 /* --- macros used for changing the reference count --- */
01046 #define symbol_add_ref(x) {(x)->common.reference_count++;}
01047 #define symbol_remove_ref(x) { \
01048   (x)->common.reference_count--; \
01049   if ((x)->common.reference_count == 0) \
01050   deallocate_symbol(x); \
01051   }
01052 
01053 extern void deallocate_symbol(Symbol * sym);
01054 
01055 extern void reset_id_counters(void);
01056 extern void reset_id_and_variable_tc_numbers(void);
01057 extern void reset_variable_gensym_numbers(void);
01058 extern bool print_sym(void *item);
01059 
01060 extern Symbol *generate_new_sym_constant(char *prefix, unsigned long *counter);
01061 
01062 /* -----------------------------------------------------------------
01063                        Predefined Symbols
01064 
01065    Certain symbols are used so frequently that we create them at
01066    system startup time and never deallocate them.  These symbols are
01067    global variables (per-agent) and are named xxx_symbol (see glob_vars.h).
01068    
01069    Create_predefined_symbols() should be called to do the creation.
01070    After that, the global variables can be accessed freely.  Note that
01071    the reference counts on these symbols should still be updated--
01072    symbol_add_ref() should be called, etc.--it's just that when the
01073    symbol isn't really being used, it stays around because the count
01074    is still 1.
01075 ----------------------------------------------------------------- */
01076 
01077 extern void create_predefined_symbols(void);
01078 
01079 /* ========================================================================= */
01080 /*                                                                           */
01081 /*                         Global Data Structures                            */
01082 /*                                                                           */
01083 /* ========================================================================= */
01084 
01085 /* ------------------------------------------------------------------------
01086                       Working Memory Elements (WMEs)
01087 
01088    Fields in a WME:
01089 
01090       id, attr, value:  points to symbols for the wme fields
01091 
01092       acceptable:  TRUE iff this is an acceptable pref. wme
01093 
01094       timetag:  timetag of the wme
01095 
01096       reference count:  (see below)
01097 
01098       rete_next, rete_prev:  pointers in the doubly-linked list of all
01099          wmes currently known to the rete (header is all_wmes_in_rete)
01100          (this equals WM except while WM is being changed)
01101 
01102       right_mems:  header of a doubly-linked list of right memory entries
01103          (in one or more alpha memories containing the wme).  This is used
01104          only by the Rete, as part of list-based remove.
01105 
01106       tokens:  header of a doubly-linked list of tokens in the Rete.
01107          This is used only by the Rete, as part of list-based remove.
01108 
01109       next, prev:  pointers in a doubly-linked list of wmes.
01110          Depending on the wme type, the header of this DLL is:
01111            - slot.wmes (for ordinary wmes)
01112            - slot.acceptable_preference_wmes (for acceptable pref. wmes)
01113            - id.impasse_wmes (for architecture-created goal/impasse wmes)
01114            - id.input_wmes (for Soar I/O wmes)
01115 
01116       preference:  points to the preference supporting the wme.  For I/O
01117          wmes and (most) architecture-created wmes, this is NIL.
01118 
01119       output_link:  this is used only for top-state output links.
01120          It points to an output_link structure used by the I/O routines.
01121 
01122       grounds_tc, potentials_tc, locals_tc:  used by the chunker to indicate
01123          whether this wme is in the grounds, potentials, and/or locals sets
01124 
01125       chunker_bt_pref: used by the chunker; set to cond->bt.trace when
01126          a wme is added to either the potentials or locals set
01127 
01128       These are the additions to the WME structure that will be used
01129          to track dependencies for goals.  Each working memory element
01130          now includes a pointer  to a gds_struct (defined below) and
01131          pointers to other WMEs on the same GDS.
01132 
01133       gds: the goal dependency set the wme is in
01134       gds_next, gds_prev:  used for dll of all wmes in gds
01135 
01136       If a particular working memory element is not dependent for any goal,
01137          then the values for these pointers will all be NIL. If a WME is
01138          dependent for more than one goal, then it will point to the GDS
01139          of the highest goal.
01140         
01141 
01142       
01143 
01144    Reference counts on wmes:
01145       +1 if the wme is currently in WM
01146       +1 for each instantiation condition that points to it (bt.wme)
01147    We deallocate a wme when its reference count goes to 0.
01148 ------------------------------------------------------------------------ */
01149 
01150 typedef struct wme_struct {
01151     /* WARNING:  The next three fields (id,attr,value) MUST be consecutive--
01152        the rete code relies on this! */
01153     Symbol *id;
01154     Symbol *attr;
01155     Symbol *value;
01156     bool acceptable;
01157     unsigned long timetag;
01158     unsigned long reference_count;
01159     struct wme_struct *rete_next, *rete_prev;   /* used for dll of wmes in rete */
01160     struct right_mem_struct *right_mems;        /* used for dll of rm's it's in */
01161     struct token_struct *tokens;        /* dll of tokens in rete */
01162     struct wme_struct *next, *prev;     /* (see above) */
01163     struct preference_struct *preference;       /* pref. supporting it, or NIL */
01164     struct output_link_struct *output_link;     /* for top-state output commands */
01165     tc_number grounds_tc;       /* for chunker use only */
01166     tc_number potentials_tc, locals_tc;
01167     struct preference_struct *chunker_bt_pref;
01168 
01169     /* REW: begin 09.15.96 */
01170     struct gds_struct *gds;
01171     struct wme_struct *gds_next, *gds_prev;     /* used for dll of wmes in gds */
01172     /* REW: end   09.15.96 */
01173 
01174 } wme;
01175 
01176 /* REW: begin 09.15.96 */
01177 
01178 /* ------------------------------------------------------------------------
01179                              Goal Dependency Set
01180 
01181    The Goal Dependency Set is a data strcuture used in Operand2 to maintain
01182    the integrity of a subgoal with respect to changes in supergoal WMEs.
01183    Whenever a WME in the goal's dependency set changes, the goal is immediately
01184    removed.  The routines for maintaining the GDS and determining if a goal
01185    should be retracted are in decide.c
01186 
01187    Fields in a goal dependency set:
01188 
01189       goal:  points to the goal for which this dependency set was created.
01190              The goal also has a pointer back to the GDS.
01191 
01192       wmes_in_gds:  A DLL of WMEs in the goal dependency set
01193 
01194    The GDS is created only when necessary; that is, when an o-suppported WME
01195    is created in some subgoal and that subgoal has no GDS already.  The
01196    instantiations that led to the creation of the o-supported WME are 
01197    examined; any supergoal WMEs in these instantiations are added to the 
01198    wmes_in_gds DLL.  The GDS for each goal is examined for every WM change;
01199    if a WME changes that is on a GDS, the goal that the GDS points to is
01200    immediately removed.  
01201 
01202    When a goal is removed, the GDS is not immediately removed.  Instead,
01203    whenever a WME is removed (or when it is added to another GDS), we check
01204    to also make certain that its GDS has other WMEs on the wmes_in_gds DLL.
01205    If not, then we remove the GDS then.  This delay avoids having to scan
01206    over all the WMEs in the GDS in addition to removing the goal (i.e., the
01207    maintenance cost is amortized over a number of WM phases).
01208 
01209    */
01210 
01211 typedef struct gds_struct {
01212     Symbol *goal;               /* pointer to the goal for the dependency set */
01213     wme *wmes_in_gds;           /* pointer to the dll of WMEs in GDS of goal */
01214 } goal_dependency_set;
01215 /* REW: end   09.15.96 */
01216 
01217 /* ------------------------------------------------------------------------
01218                                Preferences
01219 
01220    Fields in a preference:
01221 
01222       type:  indicates the type of the preference.  This is one of the
01223              types defined below:  ACCEPTABLE_PREFERENCE_TYPE, etc.
01224 
01225       o_supported:  TRUE iff the preference has o-support
01226 
01227       in_tm:  TRUE iff the preference is currently in temporary memory
01228 
01229       on_goal_list:  TRUE iff the preference is on the list of preferences
01230                      supported by its match goal (see all_of_goal_next below)
01231 
01232       reference_count:  (see below)
01233 
01234       id, attr, value, referent:  points to the symbols.  Referent is only
01235                                   used for binary preferences.
01236 
01237       slot:  points to the slot this preference is for.  (NIL if the
01238         preference is not in TM.)
01239 
01240       next, prev:  used for a doubly-linked list of preferences of the
01241                    same type in that particular slot
01242 
01243       all_of_slot_next, all_of_slot_prev:  used for a doubly-linked list
01244           of all preferences (of any type) in that particular slot
01245 
01246       all_of_goal_next, all_of_goal_prev:  used for a doubly-linked list
01247           of all preferences supported by this particular match goal.
01248           This is needed in order to remove all o-support from a particular
01249           goal when that goal is removed from the context stack.
01250 
01251       next_clone, prev_clone:  used for a doubly-linked list of all "clones"
01252         of this preference.  When a result is returned from a subgoal and a
01253         chunk is built, we get two copies of the "same" preference, one from
01254         the subgoal's production firing, and one from the chunk instantiation.
01255         If results are returned more than one level, or the same result is
01256         returned simultaneously by multiple production firings, we can get
01257         lots of copies of the "same" preference.  These clone preferences
01258         are kept on a list so that we can find the right one to backtrace
01259         through, given a wme supported by "all the clones."
01260 
01261       inst:  points to the instantiation that generated this preference
01262 
01263       inst_next, inst_prev:  used for a doubly-linked list of all
01264         existing preferences that were generated by that instantiation
01265 
01266       next_candidate:  used by the decider for lists of candidate values
01267         for a certain slot
01268 
01269       next_result:  used by the chunker for a list of result preferences
01270 
01271    Reference counts on preferences:
01272       +1 if the preference is currently in TM
01273       +1 for each instantiation condition that points to it (bt.trace)
01274       +1 if it supports an installed context WME
01275 
01276    We deallocate a preference if:
01277       (1) reference_count==0 and all its clones have reference_count==0
01278           (hence it couldn't possibly be needed anymore)
01279    or (2) its match goal is removed from the context stack
01280           (hence there's no way we'll ever want to BT through it)
01281 ------------------------------------------------------------------------ */
01282 
01283 /* WARNING: preference types must be numbered 0..(NUM_PREFERENCE_TYPES-1),
01284    because the slot structure contains an array using these indices. */
01285 #define NUM_PREFERENCE_TYPES 13 /* number of different preference types */
01286 
01287 #define ACCEPTABLE_PREFERENCE_TYPE 0
01288 #define REQUIRE_PREFERENCE_TYPE 1
01289 #define REJECT_PREFERENCE_TYPE 2
01290 #define PROHIBIT_PREFERENCE_TYPE 3
01291 #define RECONSIDER_PREFERENCE_TYPE 4
01292 #define UNARY_INDIFFERENT_PREFERENCE_TYPE 5
01293 #define UNARY_PARALLEL_PREFERENCE_TYPE 6
01294 #define BEST_PREFERENCE_TYPE 7
01295 #define WORST_PREFERENCE_TYPE 8
01296 #define BINARY_INDIFFERENT_PREFERENCE_TYPE 9
01297 #define BINARY_PARALLEL_PREFERENCE_TYPE 10
01298 #define BETTER_PREFERENCE_TYPE 11
01299 #define WORSE_PREFERENCE_TYPE 12
01300 #define preference_is_unary(p) ((p)<9)
01301 #define preference_is_binary(p) ((p)>8)
01302 
01303 extern char *preference_name[NUM_PREFERENCE_TYPES];
01304 
01305 typedef struct preference_struct {
01306     byte type;                  /* acceptable, better, etc. */
01307     bool o_supported;           /* is the preference o-supported? */
01308     bool in_tm;                 /* is this currently in TM? */
01309     bool on_goal_list;          /* is this pref on the list for its match goal */
01310     unsigned long reference_count;
01311     Symbol *id;
01312     Symbol *attr;
01313     Symbol *value;
01314     Symbol *referent;
01315     struct slot_struct *slot;
01316 
01317     /* dll of pref's of same type in same slot */
01318     struct preference_struct *next, *prev;
01319 
01320     /* dll of all pref's in same slot */
01321     struct preference_struct *all_of_slot_next, *all_of_slot_prev;
01322 
01323     /* dll of all pref's from the same match goal */
01324     struct preference_struct *all_of_goal_next, *all_of_goal_prev;
01325 
01326     /* dll (without header) of cloned preferences (created when chunking) */
01327     struct preference_struct *next_clone, *prev_clone;
01328 
01329     struct instantiation_struct *inst;
01330     struct preference_struct *inst_next, *inst_prev;
01331     struct preference_struct *next_candidate;
01332     struct preference_struct *next_result;
01333 
01334 #ifdef NO_TOP_JUST
01335 
01336     Symbol *match_goal;         /* Symbol, or NIL if none */
01337     goal_stack_level match_goal_level;  /* level, or ATTRIBUTE_IMPASSE_LEVEL */
01338 #endif
01339 
01340 #ifdef NUMERIC_INDIFFERENCE
01341     /* REW: 2003-01-08 Behavior Variability Kernel Experiements
01342        See decide.c for more information
01343        This is just a hack until we determine
01344        what we really want from these changes.
01345      */
01346 
01347     int total_preferences_for_candidate;
01348     double sum_of_probability;
01349 
01350     /* END: REW: 2003-01-08 */
01351 #endif
01352 
01353 } preference;
01354 
01355 /* Decl'd in prefmem.c and needed in decide.c */
01356 extern bool remove_preference_from_clones(preference * pref);
01357 
01358 /* ------------------------------------------------------------------------
01359 
01360                              Impasse Types
01361 
01362 ------------------------------------------------------------------------ */
01363 
01364 #define NONE_IMPASSE_TYPE 0     /* no impasse */
01365 #define CONSTRAINT_FAILURE_IMPASSE_TYPE 1
01366 #define CONFLICT_IMPASSE_TYPE 2
01367 #define TIE_IMPASSE_TYPE 3
01368 #define NO_CHANGE_IMPASSE_TYPE 4
01369 
01370 /* ------------------------------------------------------------------------
01371                                 Slots
01372 
01373    Fields in a slot:
01374 
01375       next, prev:  used for a doubly-linked list of all slots for a certain
01376         identifier.
01377 
01378       id, attr:   identifier and attribute of the slot
01379 
01380       wmes:  header of a doubly-linked list of all wmes in the slot
01381 
01382       acceptable_preference_wmes:  header of doubly-linked list of all
01383         acceptable preference wmes in the slot.  (This is only used for
01384         context slots.)
01385 
01386       all_preferences:  header of a doubly-linked list of all preferences
01387         currently in the slot
01388 
01389       preferences[NUM_PREFERENCE_TYPES]: array of headers of doubly-linked
01390         lists, one for each possible type of preference.  These store
01391         all the preferences, sorted into lists according to their types.
01392         Within each list, the preferences are sorted according to their
01393         match goal, with the pref. supported by the highest goal at the
01394         head of the list.
01395 
01396       impasse_id:  points to the identifier of the attribute impasse object
01397         for this slot.  (NIL if the slot isn't impassed.)
01398 
01399       isa_context_slot:  TRUE iff this is a context slot
01400 
01401       impasse_type:  indicates the type of the impasse for this slot.  This
01402         is one of NONE_IMPASSE_TYPE, CONSTRAINT_FAILURE_IMPASSE_TYPE, etc.
01403   
01404       marked_for_possible_removal:  TRUE iff this slot is on the list of
01405         slots that might be deallocated at the end of the current top-level
01406         phase.
01407 
01408       changed:  indicates whether the preferences for this slot have changed.
01409         For non-context slots, this is either NIL or a pointer to the
01410         corresponding dl_cons in changed_slots (see decide.c); for context
01411         slots, it's just a zero/nonzero flag.
01412 
01413       acceptable_preference_changed:  for context slots only; this is zero
01414         if no acceptable or require preference in this slot has changed;
01415         if one has changed, it points to a dl_cons.
01416 ------------------------------------------------------------------------ */
01417 
01418 typedef struct slot_struct {
01419     struct slot_struct *next, *prev;    /* dll of slots for this id */
01420     Symbol *id;                 /* id, attr of the slot */
01421     Symbol *attr;
01422     wme *wmes;                  /* dll of wmes in the slot */
01423     wme *acceptable_preference_wmes;    /* dll of acceptable pref. wmes */
01424     preference *all_preferences;        /* dll of all pref's in the slot */
01425     preference *preferences[NUM_PREFERENCE_TYPES];      /* dlls for each type */
01426     Symbol *impasse_id;         /* NIL if slot is not impassed */
01427     bool isa_context_slot;
01428     byte impasse_type;
01429     bool marked_for_possible_removal;
01430     dl_cons *changed;           /* for non-context slots: points to the corresponding
01431                                    dl_cons in changed_slots;  for context slots: just
01432                                    zero/nonzero flag indicating slot changed */
01433     dl_cons *acceptable_preference_changed;     /* for context slots: either zero,
01434                                                    or points to dl_cons if the slot
01435                                                    has changed + or ! pref's */
01436 } slot;
01437 
01438 /* -------------------------------------------------------------------
01439                               Tests
01440    
01441    Tests in conditions can be blank (null) tests, tests for equality
01442    with a variable or constant, or more complicated tests (such as
01443    not-equal tests, conjunctive tests, etc.).  We use some bit twiddling
01444    here to minimize space.  We use just a pointer to represent any kind
01445    of test.  For blank tests, this is the NIL pointer.  For equality tests,
01446    it points to the symbol referent of the test.  For other kinds of tests,
01447    bit 0 of the pointer is set to 1, and the pointer (minus 1) points to
01448    a complex_test structure.  (A field in the complex_test structure 
01449    further indicates the type of the test.)
01450 ------------------------------------------------------------------- */
01451 
01452 typedef char *test;
01453 
01454 #define test_is_blank_test(t) ((t)==NIL)
01455 #define test_is_complex_test(t) (((unsigned long)(t)) & 1)
01456 #define test_is_blank_or_equality_test(t) (! test_is_complex_test(t))
01457 
01458 #define make_blank_test() ((test)NIL)
01459 #define make_equality_test(sym) ((sym)->common.reference_count++, (test)(sym))
01460 #define make_equality_test_without_adding_reference(sym) ((test)(sym))
01461 #define make_blank_or_equality_test(sym_or_nil) \
01462   ((sym_or_nil) ? make_equality_test(sym_or_nil) : make_blank_test() )
01463 #define make_test_from_complex_test(ct) ((test) (((char *)(ct))+1))
01464 
01465 #define referent_of_equality_test(t) ((Symbol *) (t))
01466 #define complex_test_from_test(t) ((complex_test *) (((char *)(t))-1))
01467 
01468 typedef struct complex_test_struct {
01469     byte type;                  /* see definitions below */
01470     union test_info_union {
01471         Symbol *referent;       /* for relational tests */
01472         list *disjunction_list; /* for disjunction tests */
01473         list *conjunct_list;    /* for conjunctive tests */
01474     } data;
01475 } complex_test;
01476 
01477 /* types of the complex_test's */
01478 /* WARNING -- none of these can be 254 or 255 -- see rete.c */
01479 #define NOT_EQUAL_TEST 1        /* various relational tests */
01480 #define LESS_TEST 2
01481 #define GREATER_TEST 3
01482 #define LESS_OR_EQUAL_TEST 4
01483 #define GREATER_OR_EQUAL_TEST 5
01484 #define SAME_TYPE_TEST 6
01485 #define DISJUNCTION_TEST 7      /* item must be one of a list of constants */
01486 #define CONJUNCTIVE_TEST 8      /* item must pass each of a list of tests */
01487 #define GOAL_ID_TEST 9          /* item must be a goal identifier */
01488 #define IMPASSE_ID_TEST 10      /* item must be an impasse identifier */
01489 
01490 /* -------------------------------------------------------------------
01491                              Conditions
01492 
01493    Conditions are used for two things:  (1) to represent the LHS of newly
01494    entered productions (new SP's or chunks); and (2) to represent the 
01495    instantiated LHS in production instantiations.
01496    
01497    Fields in a condition:
01498 
01499       type:  indicates the type of condition:  either POSITIVE_CONDITION,
01500         NEGATIVE_CONDITION, or CONJUNCTIVE_NEGATION_CONDITION.
01501 
01502       already_in_tc:  (reserved for use by the cond_is_in_tc() stuff in
01503         production.c)
01504 
01505       next, prev:  used for a doubly-linked list of all conditions on the
01506         LHS, or all subconditions of an NCC.
01507 
01508       data.tests.id_test, data.tests.attr_test, data.tests.value_test:
01509         for positive and negative conditions, these are the three wme
01510         field tests for the condition.
01511 
01512       test_for_acceptable_preference:  for positive and negative conditions,
01513         this is TRUE iff the condition tests for acceptable preference wmes.
01514 
01515       data.ncc.top, data.ncc.bottom:  for NCC's, these point to the top and
01516         bottom of the subconditions likned list.
01517 
01518       bt:  for top-level positive conditions in production instantiations,
01519         this structure gives information for that will be used in backtracing.
01520 
01521       reorder:  (reserved for use by the reorderer)
01522 ------------------------------------------------------------------- */
01523 
01524 /* --- types of conditions --- */
01525 #define POSITIVE_CONDITION 0
01526 #define NEGATIVE_CONDITION 1
01527 #define CONJUNCTIVE_NEGATION_CONDITION 2
01528 
01529 /* --- info on conditions used for backtracing (and by the rete) --- */
01530 typedef struct bt_info_struct {
01531     wme *wme;                   /* the actual wme that was matched */
01532     goal_stack_level level;     /* level (at firing time) of the id of the wme */
01533 
01534     preference *trace;          /* preference for BT, or NIL */
01535 
01536     /* mvp 5-17-94 */
01537     list *prohibits;            /* list of prohibit prefs to backtrace through */
01538 
01539 } bt_info;
01540 
01541 /* --- info on conditions used only by the reorderer --- */
01542 typedef struct reorder_info_struct {
01543     list *vars_requiring_bindings;      /* used only during reordering */
01544     struct condition_struct *next_min_cost;     /* used only during reordering */
01545 } reorder_info;
01546 
01547 /* --- info on positive and negative conditions only --- */
01548 typedef struct three_field_tests_struct {
01549     test id_test;
01550     test attr_test;
01551     test value_test;
01552 } three_field_tests;
01553 
01554 /* --- info on negated conjunctive conditions only --- */
01555 typedef struct ncc_info_struct {
01556     struct condition_struct *top;
01557     struct condition_struct *bottom;
01558 } ncc_info;
01559 
01560 /* --- finally, the structure of a condition --- */
01561 typedef struct condition_struct {
01562     byte type;
01563     bool already_in_tc;         /* used only by cond_is_in_tc stuff */
01564     bool test_for_acceptable_preference;        /* for pos, neg cond's only */
01565     struct condition_struct *next, *prev;
01566     union condition_main_data_union {
01567         three_field_tests tests;        /* for pos, neg cond's only */
01568         ncc_info ncc;           /* for ncc's only */
01569     } data;
01570     bt_info bt;                 /* for top-level positive cond's: used for BT and by the rete */
01571     reorder_info reorder;       /* used only during reordering */
01572 } condition;
01573 
01574 /* -------------------------------------------------------------------
01575                       Right-Hand-Side Values
01576    
01577    Values on the RHS of productions can be given by symbols
01578    (constants or variables), by Rete locations, by indices of variables
01579    not bound on the LHS, or by function calls.  We use the low-order two
01580    bits of a pointer to differentiate between these types of values.
01581 
01582    If the low-order bits are:   the rhs_value is:
01583                        00       a pointer to a symbol
01584                        01       a pointer to a list (for a function call)
01585                        10       a Rete location
01586                        11       the index of an RHS unbound variable
01587 
01588    For function calls, the list is a consed list whose first element is
01589    the rhs_function structure, and whose remaining elements are the
01590    arguments of the function call.  (Each argument is an rhs_value.)
01591 
01592    WARNING: part of rete.c relies on the the fact that two rhs_values
01593    representing the same symbol, reteloc, or unboundvar will be equal (==),
01594    while two representing the same funcall will not be equal (==).
01595 ------------------------------------------------------------------- */
01596 
01597 typedef char *rhs_value;
01598 
01599 #define rhs_value_is_symbol(rv) ((((unsigned long)(rv)) & 3)==0)
01600 #define rhs_value_is_funcall(rv) ((((unsigned long)(rv)) & 3)==1)
01601 #define rhs_value_is_reteloc(rv) ((((unsigned long)(rv)) & 3)==2)
01602 #define rhs_value_is_unboundvar(rv) ((((unsigned long)(rv)) & 3)==3)
01603 
01604 /* Warning: symbol_to_rhs_value() doesn't symbol_add_ref.  The caller must
01605    do the reference count update */
01606 #define symbol_to_rhs_value(sym) ((rhs_value) (sym))
01607 #define funcall_list_to_rhs_value(fl) ((rhs_value) (((char *)(fl))+1))
01608 #define reteloc_to_rhs_value(field_num,levels_up) \
01609   ((rhs_value) ( (levels_up)<<4) + ((field_num)<<2) + 2 )
01610 #define unboundvar_to_rhs_value(n) ((rhs_value) (((n)<<2) + 3))
01611 
01612 #define rhs_value_to_symbol(rv) ((Symbol *)(rv))
01613 #define rhs_value_to_funcall_list(rv) ((list *) (((char *)(rv))-1))
01614 #define rhs_value_to_reteloc_field_num(rv) ((((unsigned long)(rv))>>2) & 3)
01615 #define rhs_value_to_reteloc_levels_up(rv) ((((unsigned long)(rv))>>4)& 0xFFFF)
01616 #define rhs_value_to_unboundvar(rv) (((unsigned long)(rv))>>2)
01617 
01618 /* -------------------------------------------------------------------
01619                              RHS Actions
01620 
01621    Fields in an action:
01622  
01623       next:  points to the next action in a singly-linked list of all
01624         actions in the RHS.
01625 
01626       type:  indicates the type of action:  usually this is MAKE_ACTION,
01627         but for function calls it is FUNCALL_ACTION.
01628 
01629       preference_type:  for make actions, this indicates the type of the
01630         preference being created:  ACCEPTABLE_PREFERENCE_TYPE, etc.
01631 
01632       support:  indicates the compile-time calculated o-support of the action.
01633         This is either UNKNOWN_SUPPORT, O_SUPPORT, or I_SUPPORT.
01634   
01635       already_in_tc:  (reserved for use by compile-time o-support calcs)
01636 
01637       id, attr:  for make actions, these give the symbols (or Rete locations)
01638         for the id and attribute fields of the preference.
01639 
01640       value:  for MAKE_ACTION's, this gives the value field of the preference
01641         (a symbol or function call).  For FUNCALL_ACTION's, this holds the
01642         function call itself.
01643   
01644       referent:  for MAKE_ACTION's of binary preferences, this gives the
01645         referent field of the preference.
01646 ------------------------------------------------------------------- */
01647 
01648 #define MAKE_ACTION 0
01649 #define FUNCALL_ACTION 1
01650 
01651 #define UNKNOWN_SUPPORT 0
01652 #define O_SUPPORT 1
01653 #define I_SUPPORT 2
01654 
01655 typedef struct action_struct {
01656     struct action_struct *next;
01657     byte type;
01658     byte preference_type;
01659     byte support;
01660     bool already_in_tc;         /* used only by compile-time o-support calcs */
01661     rhs_value id;
01662     rhs_value attr;
01663     rhs_value value;            /* for FUNCALL_ACTION's, this holds the funcall */
01664     rhs_value referent;
01665 } action;
01666 
01667 /* -------------------------------------------------------------------
01668                             Productions
01669 
01670    Fields in a production:
01671  
01672       name:  points to the name of the production (a symbol)
01673 
01674       documentation:  points to a string (a memory_block_for_string) giving
01675         user-provided documentation about the production, or NIL if the
01676         user didn't give any documentation for it.
01677     
01678       reference_count:  (see below)
01679 
01680       firing_count:  the number of times this production has ever fired
01681         since it was created.  (Note that this is not reset by an init-soar.)
01682 
01683       next, prev:  used for a doubly-linked list of productions of the same
01684         type (see below).  The list header is all_productions_of_type[].
01685 
01686       type: the type of the production:  USER_PRODUCTION_TYPE,
01687         DEFAULT_PRODUCTION_TYPE, CHUNK_PRODUCTION_TYPE, or
01688         JUSTIFICATION_PRODUCTION_TYPE.
01689 
01690       declared_support:  indicates whether the production was declared
01691         :o-support or :i-support.  This field is either UNDECLARED_SUPPORT,
01692         DECLARED_O_SUPPORT, or DECLARED_I_SUPPORT.
01693 
01694       trace_firings:  TRUE iff a (pwatch) has been set on this production.
01695 
01696       p_node:  If the production is currently in the Rete, this points to
01697         the corresponding p_node in the Rete.  If the production is not in
01698         the Rete, this field is NIL.
01699 
01700       action_list:  singly-linked list of the RHS actions of the production.
01701 
01702       rhs_unbound_variables:  A (consed) list of variables used on the RHS
01703         that aren't bound on the LHS, in the order of their indices (for
01704         rhs_values).  For chunks, this is NIL, since we discard chunk
01705         variable names.
01706 
01707       instantiations:  header for a doubly-linked list of the instantiations
01708         of this production that are currently in the match set (i.e.,
01709         Rete-supported).
01710 
01711       OPERAND_which_assert_list: (BUGBUG need info from REW or RCHONG)
01712 
01713                         interrupt: TRUE iff we should break when this production matches 
01714                                     (but before it fires).  Note: this functionality is
01715                                                                         only used when the compile time option:
01716                                                                         MATCHTIME_INTERRUPT is defined.
01717 
01718    Reference counts on productions:
01719       +1 if it's in production memory (i.e., hasn't been excised)
01720       +1 for each existing instantiation pointing to it
01721    We deallocate a production if its reference_count goes to 0.
01722 ------------------------------------------------------------------- */
01723 
01724 #define UNDECLARED_SUPPORT 0
01725 #define DECLARED_O_SUPPORT 1
01726 #define DECLARED_I_SUPPORT 2
01727 
01728 /* RCHONG: begin 10.11 */
01729 
01730 #define PE_PRODS 0
01731 #define IE_PRODS 1
01732 #define NO_SAVED_PRODS -1
01733 
01734 /* RCHONG: end 10.11 */
01735 
01736 typedef struct production_struct {
01737     Symbol *name;
01738     char *documentation;        /* pointer to memory block, or NIL */
01739     char *filename;             /* name of source file, or NIL.  kjh CUSP(b11) */
01740     unsigned long reference_count;
01741     unsigned long firing_count; /* how many times it's fired */
01742     struct production_struct *next, *prev;      /* used for dll */
01743     byte type;
01744     byte declared_support;
01745 
01746 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
01747     bool trace_firings;         /* used by pwatch */
01748 #endif
01749 
01750     struct rete_node_struct *p_node;    /* NIL if it's not in the rete */
01751     action *action_list;        /* RHS actions */
01752     list *rhs_unbound_variables;        /* RHS vars not bound on LHS */
01753     struct instantiation_struct *instantiations;        /* dll of inst's in MS */
01754     int OPERAND_which_assert_list;      /* RCHONG: 10.11 */
01755     byte interrupt;             /* SW: 7.31.03 */
01756 #ifdef BUG_139_WORKAROUND
01757     bool already_fired;         /* RPM test workaround for bug #139 */
01758 #endif
01759 } production;
01760 
01761 /* -------------------------------------------------------------------
01762                         Instantiations and Nots
01763 
01764    Instantiations record three main things:
01765      (1) the instantiated LHS of the production,
01766      (2) any "<>" tests that are between identifiers and that occur in
01767          top-level positive conditions on the LHS, and
01768      (3) the still-existing preferences that were generated by the RHS.
01769 
01770    Fields in an instantiation:
01771  
01772       prod:  points to the production.  (Note: this can also be NIL, for
01773         fake instantiations used for goal ^item augmentations.  See decide.c.)
01774 
01775       next, prev:  used for a doubly-linked list of instantiations of this
01776         production that are still in the match set.
01777 
01778       rete_token, rete_wme:  these fields are reserved for use by the Rete.
01779         (The Rete needs them to find the proper instantiation to retract
01780         when a token is delted from a p_node.)
01781 
01782       top_of_instantiated_conditions, bottom_of_instantiated_conditions:
01783         point to the top and bottom of the instantiated LHS conditions.
01784 
01785       nots:  header of a singly-linked list of Nots from the LHS.
01786 
01787       preferences_generated:  header for a doubly-linked list of existing
01788         preferences that were created by this instantiation.
01789 
01790       match_goal:  points to the match goal of the instantiation, or NIL
01791         if there is none.
01792 
01793       match_goal_level:  goal stack level of the match goal, or
01794         ATTRIBUTE_IMPASSE_LEVEL if there is no match goal.
01795 
01796       okay_to_variablize:  TRUE iff it's okay to variablize a
01797         chunk/justification formed by backtracing through this instantiation.
01798         This is used to make sure we don't variablize a chunk that got formed
01799         by backtracing through some other justification.
01800 
01801       in_ms:  TRUE iff this instantiation is still in the match set (i.e.,
01802         Rete-supported).
01803       backtrace_number:  used by the chunker to avoid backtracing through
01804         the same instantiation twice during the building of the same chunk.
01805 
01806       GDS_evaluated_already:  Most productions produce several actions.
01807         When we compute the goal-dependency-set (gds) gds for one wme of an
01808         instantiation, there's no point in redoing the work for a second wme
01809         from the same instantiation since the gds will be the same.  By
01810         testing this flag, we avoid duplicating this work.  The value is set
01811         to FALSE whenever an instantiation is created. 
01812 
01813    Reference counts on instantiations:
01814       +1 if it's in the match set
01815       +1 for each preference it created that's still around
01816    The reference count is kept implicitly using the preferences_generated
01817    and in_ms fields.  We deallocate an instantiation if its reference count
01818    goes to 0.
01819 ------------------------------------------------------------------- */
01820 
01821 typedef struct not_struct {
01822     struct not_struct *next;    /* next Not in the singly-linked list */
01823     Symbol *s1;                 /* the two identifiers constrained to be "<>" */
01824     Symbol *s2;
01825 } not;
01826 
01827 typedef struct instantiation_struct {
01828     production *prod;
01829     struct instantiation_struct *next, *prev;   /* dll of inst's from same prod */
01830     struct token_struct *rete_token;    /* used by Rete for retractions */
01831     wme *rete_wme;              /* ditto */
01832     condition *top_of_instantiated_conditions;
01833     condition *bottom_of_instantiated_conditions;
01834     not *nots;
01835     preference *preferences_generated;  /* header for dll of prefs */
01836     Symbol *match_goal;         /* symbol, or NIL if none */
01837     goal_stack_level match_goal_level;  /* level, or ATTRIBUTE_IMPASSE_LEVEL */
01838     byte okay_to_variablize;
01839     bool in_ms;                 /* TRUE iff this inst. is still in the match set */
01840     tc_number backtrace_number;
01841     bool GDS_evaluated_already;
01842 #if defined(WATCH_SSCI_INSTS) || defined(THIN_JUSTIFICATIONS)
01843     bool isa_ssci_inst;
01844 #endif
01845 } instantiation;
01846 
01847 /* REW: begin 09.15.96 */
01848 /* A dll of instantiations that will be used to determine the gds through
01849    a backtracing-style procedure, evaluate_gds in decide.c */
01850 
01851 typedef struct pi_struct {
01852     struct pi_struct *next, *prev;
01853     instantiation *inst;
01854 } parent_inst;
01855 /* REW: end   09.15.96 */
01856 
01857 /* ====================================================================
01858              Global System Parameters and Related Definitions
01859 
01860    A set of system parameters (sysparam's for short) affect many operations
01861    of Soar, including learning, tracing, deciding, etc.  In order to
01862    provide a simple, uniform update mechanism (a single callback routine that
01863    gets called when any parameter changes), we store these parameters in
01864    an array sysparams[].  Below, we #define various indices into this array
01865    corresponding to various system parameters.
01866 
01867    Most of the parameters are of type "long".  A few parameters are more
01868    naturally handled as lists; for these, the array value is just a dummy,
01869    and callback routines must inspect a global variable to get the real 
01870    value.  Chunk_free_problem_spaces is an example of this.
01871 
01872    The array of sysparams[] can be read directly, but should be modified
01873    ONLY via calls to set_sysparam(), which is defined in init-soar.c.
01874 ==================================================================== */
01875 
01876 /* -------------------------------
01877       Types of Productions
01878 ------------------------------- */
01879 
01880 #define USER_PRODUCTION_TYPE 0
01881 #define DEFAULT_PRODUCTION_TYPE 1
01882 #define CHUNK_PRODUCTION_TYPE 2
01883 #define JUSTIFICATION_PRODUCTION_TYPE 3
01884 
01885 #define NUM_PRODUCTION_TYPES 4
01886 
01887 /* ---------------------------------------
01888     Match Set print parameters
01889 --------------------------------------- */
01890 
01891 #define MS_ASSERT_RETRACT 0     /* print both retractions and assertions */
01892 #define MS_ASSERT         1     /* print just assertions */
01893 #define MS_RETRACT        2     /* print just retractions */
01894 
01895 typedef byte ms_trace_type;     /* must be one of the above constants */
01896 
01897 /* ---------------------------------------
01898     How much information to print about
01899     the wmes matching an instantiation
01900 --------------------------------------- */
01901 
01902 #define NONE_WME_TRACE    1     /* don't print anything */
01903 #define TIMETAG_WME_TRACE 2     /* print just timetag */
01904 #define FULL_WME_TRACE    3     /* print whole wme */
01905 #define NO_WME_TRACE_SET  4
01906 
01907 typedef byte wme_trace_type;    /* must be one of the above constants */
01908 
01909 /* -------------------------------
01910       Ways to Do User-Select
01911 ------------------------------- */
01912 
01913 #define USER_SELECT_FIRST  0    /* just choose the first candidate item */
01914 #define USER_SELECT_ASK    1    /* ask the user */
01915 #define USER_SELECT_RANDOM 2    /* pick one at random */
01916 #define USER_SELECT_LAST   3    /* choose the last item   AGR 615 */
01917 
01918 /* ---------------------------
01919    And now, the sysparam's
01920 --------------------------- */
01921 
01922 /* ====== Sysparams for what to trace === */
01923 
01924 #define TRACE_CONTEXT_DECISIONS_SYSPARAM          1
01925 #define TRACE_PHASES_SYSPARAM                     2
01926 
01927 /* --- Warning: these next four MUST be consecutive and in the order of the
01928    production types defined above --- */
01929 #define TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM      3
01930 #define TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM   4
01931 #define TRACE_FIRINGS_OF_CHUNKS_SYSPARAM          5
01932 #define TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM  6
01933 
01934 #define TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM     7
01935 #define TRACE_FIRINGS_PREFERENCES_SYSPARAM        8
01936 #define TRACE_WM_CHANGES_SYSPARAM                 9
01937 #define TRACE_CHUNK_NAMES_SYSPARAM               10
01938 #define TRACE_JUSTIFICATION_NAMES_SYSPARAM       11
01939 #define TRACE_CHUNKS_SYSPARAM                    12
01940 #define TRACE_JUSTIFICATIONS_SYSPARAM            13
01941 #define TRACE_BACKTRACING_SYSPARAM               14
01942 /* ===== watch loading flag =====  KJC 7/96 */
01943 #define TRACE_LOADING_SYSPARAM                   15
01944 
01945 /* ====== Max Elaborations === */
01946 #define MAX_ELABORATIONS_SYSPARAM                16
01947 
01948 /* ====== Max Chunks === */
01949 #define MAX_CHUNKS_SYSPARAM                      17
01950 
01951 #define RESPOND_TO_LOAD_ERRORS_SYSPARAM          18
01952 
01953 /* ====== Sysparams for control of learning === */
01954 #define LEARNING_ON_SYSPARAM                     19
01955 #define LEARNING_ONLY_SYSPARAM                   20
01956 #define LEARNING_EXCEPT_SYSPARAM                 21
01957 #define LEARNING_ALL_GOALS_SYSPARAM              22
01958 
01959 /* ====== User Select === */
01960 #define USER_SELECT_MODE_SYSPARAM                23
01961 
01962 /* ====== Print Warnings === */
01963 #define PRINT_WARNINGS_SYSPARAM                  24
01964 
01965 /* AGR 627 begin */
01966 /* ====== Whether to print out aliases as they're defined === */
01967 #define PRINT_ALIAS_SYSPARAM                     25
01968 /* AGR 627 end */
01969 
01970 /* ===== explain_flag =====  KJC 7/96 */
01971 #define EXPLAIN_SYSPARAM                         26
01972 
01973 /* kjh(B14) */
01974 #define USE_LONG_CHUNK_NAMES                     27
01975 
01976 /* REW:  10.22.97 */
01977 #define TRACE_OPERAND2_REMOVALS_SYSPARAM         28
01978 
01979 /* RMJ */
01980 #define REAL_TIME_SYSPARAM                       29
01981 
01982 /* RMJ */
01983 #define ATTENTION_LAPSE_ON_SYSPARAM              30
01984 
01985 /* SAN */
01986 #define TRACE_INDIFFERENT_SYSPARAM               31
01987 
01988 /* --- Warning: if you add sysparams, be sure to update the next line! --- */
01989 #define HIGHEST_SYSPARAM_NUMBER                  31
01990 
01991 /* -----------------------------------------
01992    Sysparams[] stores the parameters; set_sysparam()
01993    should be used to modify them.
01994 ----------------------------------------- */
01995 
01996 extern void init_sysparams(void);
01997 extern void set_sysparam(int param_number, long new_value);
01998 
01999 #ifndef MAXPATHLEN              /* excludeFromBuildInfo */
02000 #define MAXPATHLEN 1024         /* AGR 536  - from sys/param.h */
02001 #endif
02002 
02003 #define kChunkNamePrefixMaxLength  64   /* kjh (B14) */
02004 
02005 /******************************************************************
02006  ******************************************************************
02007                        Subroutine Declarations
02008  ******************************************************************
02009  ******************************************************************/
02010 
02011 /* ========================================================================
02012                         main.c and init_soar.c
02013 ======================================================================== */
02014 
02015 extern void reset_statistics(void);
02016 extern void setup_signal_handling(void);
02017 extern void load_init_file(void);
02018 
02019 /* --- signal handler that gets invoked on SIGINT --- */
02020 extern void control_c_handler(int the_signal);
02021 
02022 /* ---------------------------------------------------------------------
02023                             Exiting Soar
02024 
02025    Exit_soar() and abort_with_fatal_error() both terminate Soar, closing
02026    the log file before exiting.  Abort_with_fatal_error() also prints
02027    an error message before exiting.  Just_before_exit_soar() calls the
02028    Soar cleanup functions but does not actually exit.  This is useful
02029    for interfaces that do their own exiting.
02030 --------------------------------------------------------------------- */
02031 
02032 extern void exit_soar(void);
02033 extern void abort_with_fatal_error(char *);
02034 extern void just_before_exit_soar(void);
02035 
02036 /* ---------------------------------------------------------------------
02037                        Timer Utility Routines
02038 
02039    These are utility routines for using timers.  We use (struct timeval)'s
02040    (defined in a system include file) for keeping track of the cumulative
02041    time spent in one part of the system or another.  Reset_timer()
02042    clears a timer to 0.  Start_timer() and stop_timer() are used for
02043    timing an interval of code--the usage is:
02044    
02045      start_timer (&timeval_to_record_the_start_time_in); 
02046      ... other code here ...
02047      stop_timer (&timeval_to_record_the_start_time_in,
02048                  &timeval_holding_accumulated_time_for_this_code);
02049 
02050    Finally, timer_value() returns the accumulated value of a timer
02051    (in seconds).
02052 --------------------------------------------------------------------- */
02053 
02054 #ifndef NO_TIMING_STUFF
02055 
02056 extern void reset_timer(TIMER_VALUE * tv_to_reset);
02057 extern void start_timer(TIMER_VALUE * tv_for_recording_start_time);
02058 extern void stop_timer(TIMER_VALUE * tv_with_recorded_start_time, TIMER_VALUE * tv_with_accumulated_time);
02059 extern double timer_value(TIMER_VALUE * tv);
02060 extern int test_timers();
02061 
02062 #else                           /* NO_TIMING_STUFF */
02063 
02064 #define start_timer(X)
02065 #define stop_timer(X)
02066 #endif
02067 
02068 #define ONE_MILLION (1000000)
02069 
02070 #ifdef REAL_TIME_BEHAVIOR
02071 /* RMJ */
02072 extern void init_real_time();
02073 extern struct timeval *current_real_time;
02074 #endif
02075 
02076 #ifdef ATTENTION_LAPSE
02077 /* RMJ */
02078 extern void wake_from_attention_lapse();
02079 extern void init_attention_lapse();
02080 #endif
02081 
02082 /* ---------------------------------------------------------------------
02083                      Adding and Removing Pwatchs
02084 
02085    Productions_being_traced is a (consed) list of all productions
02086    on which a pwatch has been set.  Pwatchs are added/removed via
02087    calls to add_pwatch() and remove_pwatch().
02088 --------------------------------------------------------------------- */
02089 
02090 extern void add_pwatch(struct production_struct *prod);
02091 extern void remove_pwatch(struct production_struct *prod);
02092 
02093 /* ---------------------------------------------------------------------
02094                          Reinitializing Soar
02095 
02096    Reinitialize_soar() does all the work for an init-soar.
02097 --------------------------------------------------------------------- */
02098 
02099 extern void reinitialize_soar(void);
02100 
02101 /* ---------------------------------------------------------------------
02102                             Running Soar
02103 
02104    Each of the following routines runs Soar for a certain duration,
02105    or until stop_soar gets set to TRUE.
02106      - Run_forever() runs Soar forever.
02107      - Run_for_n_phases() runs Soar for a given number (n) of top-level
02108        phases.  (If n==-1, it runs forever.)
02109      - Run_for_n_elaboration_cycles() runs Soar for a given number (n)
02110        of elaboration cycles.  (Here, decision phase is counted as
02111        an elaboration cycle.)  (If n==-1, it runs forever.)
02112      - Run_for_n_decision_cycles() runs Soar for a given number (n) of
02113        decision cycles.  (If n==-1, it runs forever.)
02114      - Run_for_n_modifications_of_output runs soar by decision cycle
02115        n times, where n starts at 0 and is incremented anytime the
02116        output link is modified by the agent.  n is not incremented when
02117        the output-link is created nor when the output-link is modified
02118        during the Input Cycle, ie when getting feedback from a simulator.
02119      - Run_for_n_selections_of_slot (long n, Symbol *attr_of_slot): this
02120        runs Soar until the nth time a selection is made for a given
02121        type of slot.  Attr_of_slot should be either state_symbol or 
02122        operator_symbol.
02123      - Run_for_n_selections_of_slot_at_level (long n, Symbol *attr_of_slot,
02124        goal_stack_level level):  this runs Soar for n selections of the
02125        given slot at the given level, or until the goal stack is popped
02126        so that level no longer exists.
02127 --------------------------------------------------------------------- */
02128 
02129 enum go_type_enum { GO_PHASE, GO_ELABORATION, GO_DECISION,
02130     GO_STATE, GO_OPERATOR, GO_SLOT, GO_OUTPUT
02131 };
02132 
02133 extern void run_forever(void);
02134 extern void run_for_n_phases(long n);
02135 extern void run_for_n_elaboration_cycles(long n);
02136 extern void run_for_n_decision_cycles(long n);
02137 extern void run_for_n_modifications_of_output(long n);
02138 extern void run_for_n_selections_of_slot(long n, Symbol * attr_of_slot);
02139 extern void run_for_n_selections_of_slot_at_level(long n, Symbol * attr_of_slot, goal_stack_level level);
02140 
02141 /* REW: begin 05.05.97 */
02142 /* Added new DETERMINE_LEVEL_PHASE here and in the timers */
02143 
02144 enum top_level_phase { INPUT_PHASE, DETERMINE_LEVEL_PHASE, PREFERENCE_PHASE, WM_PHASE,
02145     OUTPUT_PHASE, DECISION_PHASE
02146 };
02147 /* REW: end   05.05.97 */
02148 
02149 /* =======================================================================
02150                                 wmem.c 
02151 
02152                 Working Memory Management and Utility Routines
02153 
02154    Reset_wme_timetags() resets the wme timetag generator back to 1.
02155    This should be called during an init-soar.
02156 
02157    Make_wme() creates and returns a new wme.  The caller should add the
02158    wme onto the appropriate dll (e.g., my_slot->wmes) and should call
02159    add_wme_to_wm() on it.
02160 
02161    Add_wme_to_wm() and remove_wme_from_wm() make changes to WM.  Again,
02162    the caller is responsible for manipulating the appropriate dll.  WM
02163    changes don't actually get stuffed down the rete until the end of the
02164    phase, when do_buffered_wm_and_ownership_changes() gets be called.
02165 
02166    Remove_wme_list_from_wm() is a utility routine that scans through a
02167    list of wmes, linked by their "next" fields, and calls remove_wme_from_wm()
02168    on each one.
02169 
02170    Wme_add_ref() and wme_remove_ref() are macros for incrementing and
02171    decrementing the reference count on a wme.  Deallocate_wme() deallocates
02172    a wme; this should only be invoked via the wme_remove_ref() macro.
02173 
02174    Find_name_of_object() is a utility function for finding the value of
02175    the ^name attribute on a given object (symbol).  It returns the name,
02176    or NIL if the object has no name.
02177 ======================================================================= */
02178 
02179 extern void reset_wme_timetags(void);
02180 extern wme *make_wme(Symbol * id, Symbol * attr, Symbol * value, bool acceptable);
02181 extern void add_wme_to_wm(wme * w);
02182 extern void remove_wme_from_wm(wme * w);
02183 extern void remove_wme_list_from_wm(wme * w);
02184 extern void do_buffered_wm_changes(void);
02185 
02186 #define wme_add_ref(w) { (w)->reference_count++; }
02187 #define wme_remove_ref(w) { \
02188   (w)->reference_count--; \
02189   if ((w)->reference_count == 0) deallocate_wme(w); }
02190 
02191 extern void deallocate_wme(wme * w);
02192 extern Symbol *find_name_of_object(Symbol * id);
02193 
02194 /* =======================================================================
02195                                 decide.c
02196 
02197    Decide.c contains the decider as well as routine for managing working
02198    memory, preference memory, slots, and the garbage collection of
02199    disconnected WMEs.
02200 
02201    Whenever a link is added from one identifier to another (i.e.,
02202    (I37 ^x R26)), we call post_link_addition().  This records the link
02203    addition and buffers it for later processing.  Similarly, whenever a
02204    link is removed, we call post_link_removal(), which buffers the
02205    removal for later processing.  At the end of the phase, we call
02206    do_buffered_link_changes() to update the goal stack level of all
02207    identifiers, and garbage collect anything that's now disconnected.
02208 
02209    Whenever some acceptable or require preference for a context slot
02210    changes, we call mark_context_slot_as_acceptable_preference_changed().
02211    
02212    see decide.c for more information in the comments.
02213 ======================================================================= */
02214 
02215 extern void post_link_addition(Symbol * from, Symbol * to);
02216 extern void post_link_removal(Symbol * from, Symbol * to);
02217 
02218 extern void mark_context_slot_as_acceptable_preference_changed(slot * s);
02219 
02220 /* ---------------------------------------------------------------------
02221                   Slot Management Routines (in tempmem.c)
02222 
02223    Find_slot() looks for an existing slot for a given id/attr pair, and
02224    returns it if found.  If no such slot exists, it returns NIL.
02225    Make_slot() looks for an existing slot for a given id/attr pair,
02226    returns it if found, and otherwise creates a new slot and returns it.
02227 
02228    Mark_slot_as_changed() is called by the preference manager whenever
02229    the preferences for a slot change.  This updates the list of
02230    changed_slots and highest_goal_whose_context_changed for use by the
02231    decider.
02232 
02233    Old slots are garbage collected as follows:  whenever we notice that
02234    the last preference has been removed from a slot, we call
02235    mark_slot_for_possible_removal().  We don't deallocate the slot
02236    right away, because there might still be wmes in it, or we might
02237    be about to add a new preference to it (through some later action
02238    of the same production firing, for example).  At the end of the phase, 
02239    we call remove_garbage_slots(), which scans through each marked slot 
02240    and garbage collects it if it has no wmes or preferences.
02241 --------------------------------------------------------------------- */
02242 
02243 extern slot *find_slot(Symbol * id, Symbol * attr);
02244 extern slot *make_slot(Symbol * id, Symbol * attr);
02245 extern void mark_slot_as_changed(slot * s);
02246 extern void mark_slot_for_possible_removal(slot * s);
02247 extern void remove_garbage_slots(void);
02248 
02249 /* ---------------------------------------------------------------------
02250                      Preference Management Routines
02251 
02252    Make_preference() creates a new preference structure of the given type
02253    with the given id/attribute/value/referent.  (Referent is only used
02254    for binary preferences.)  The preference is not yet added to preference
02255    memory, however.
02256 
02257    Preference_add_ref() and preference_remove_ref() are macros for
02258    incrementing and decrementing the reference count on a preference.
02259    
02260    Possibly_deallocate_preference_and_clones() checks whether a given
02261    preference and all its clones have reference_count 0, and deallocates
02262    them all if they do; it returns TRUE if they were actually deallocated,
02263    FALSE otherwise.   Deallocate_preference() deallocates a given
02264    preference.  These routines should normally be invoked only via the
02265    preference_remove_ref() macro.
02266 
02267    Add_preference_to_tm() adds a given preference to preference memory (and
02268    hence temporary memory).  Remove_preference_from_tm() removes a given
02269    preference from PM and TM.
02270 
02271    Process_o_rejects_and_deallocate_them() handles the processing of
02272    o-supported reject preferences.  This routine is called from the firer
02273    and passed a list of all the o-rejects generated in the current
02274    preference phase (the list is linked via the "next" fields on the
02275    preference structures).  This routine removes all preferences for
02276    matching values from TM, and deallocates the o-reject preferences when
02277    done.
02278 --------------------------------------------------------------------- */
02279 
02280 extern preference *make_preference(byte type, Symbol * id, Symbol * attr, Symbol * value, Symbol * referent);
02281 
02282 #define preference_add_ref(p) { (p)->reference_count++; }
02283 #define preference_remove_ref(p) { \
02284   (p)->reference_count--; \
02285   if ((p)->reference_count == 0) \
02286     possibly_deallocate_preference_and_clones(p); }
02287 
02288 extern bool possibly_deallocate_preference_and_clones(preference * pref);
02289 extern void deallocate_preference(preference * pref);
02290 
02291 extern void add_preference_to_tm(preference * pref);
02292 extern void remove_preference_from_tm(preference * pref);
02293 extern void process_o_rejects_and_deallocate_them(preference * o_rejects);
02294 
02295 /* ---------------------------------------------------------------------
02296                       Top-Level Decider Routines
02297 
02298    Init_decider() should be called at startup time to initialize this
02299    module.
02300 
02301    Do_buffered_wm_and_ownership_changes() does the end-of-phase processing
02302    of WM changes, ownership calculations, garbage collection, etc.
02303 
02304    Do_working_memory_phase() and do_decision_phase() are called from
02305    the top level to run those phases.
02306 
02307    Create_top_goal() creates the top goal in the goal stack.
02308    Clear_goal_stack() wipes out the whole goal stack--this is called
02309    during an init-soar.
02310 
02311    Print_lowest_slot_in_context_stack() is used for the watch 0 trace
02312    to print the context slot that was just decided.
02313 --------------------------------------------------------------------- */
02314 
02315 extern void init_decider(void);
02316 extern void do_buffered_wm_and_ownership_changes(void);
02317 extern void do_working_memory_phase(void);
02318 extern void do_decision_phase(void);
02319 extern void create_top_goal(void);
02320 extern void clear_goal_stack(void);
02321 extern void print_lowest_slot_in_context_stack(void);
02322 
02323 /* =================================================================
02324                              interface.c                             
02325 
02326   This portion of the code is normally replaced by the Tcl interface
02327   and interface support routines, but some maintenance continues, in
02328   the event someone needs to build a version without Tcl.  However some
02329   user interface commands are likely to break or give unusual output.
02330 
02331   User Interface Command Routines:
02332 
02333      Each user interface command has a corresponding function
02334      (user_interface_routine) to handle it.  These commands/functions
02335      should be installed at system startup time via add_command().  The
02336      command name string passed to add_command() must be permanently
02337      available (e.g., a constant in global data memory).
02338 
02339      When a user interface routine is called, the current lexeme is the
02340      command name.  The function should call the lexer to read its arguments,
02341      etc.  If successful, the function should return TRUE and should exit
02342      with the current lexeme being the closing right parenthesis (otherwise
02343      the dispatching function will print an error message about extra
02344      arguments being given).  If unsuccessful, the function should
02345      return FALSE.
02346 
02347   Dispatching commands:
02348 
02349      Dispatch_command() dispatches the appropriate user interface routine
02350      for the current command (i.e., the command named by the current lexeme).
02351      It calls set_lexer_allow_ids(TRUE) before dispatching the command,
02352      so if the command doesn't allow id's, it should call 
02353      set_lexer_allow_ids(FALSE) immediately.  Dispatch_command() returns 
02354      TRUE if the command was successful, FALSE if any error occurred.
02355    
02356      Repeatedly_read_and_dispatch_commands() keeps calling dispatch_command()
02357      until end-of-file is reached on the current input file.
02358      
02359      Load_file() sets up the lexer to read from a given open file, executes
02360      all the commands in that file, and then restore the lexer to reading
02361      the previous file.
02362 
02363   Help Information:
02364 
02365      Add_help() should be called at system startup time to specify to the
02366      "help" command what help info is available.  It takes a topic name and
02367      an array of lines of text for the helpscreen.  All these strings
02368      should be permanently available (e.g., constants in global data memory).
02369 ================================================================= */
02370 
02371 typedef bool(*user_interface_routine) (void);
02372 extern void add_command(char *command_name, user_interface_routine f);
02373 
02374 extern bool dispatch_command(void);
02375 
02376 extern void repeatedly_read_and_dispatch_commands(void);
02377 
02378 extern void load_file(char *file_name, FILE * already_open_file);
02379 
02380 extern void add_help(char *topic, char **lines_of_text);
02381 
02382 extern void init_built_in_commands(void);
02383 
02384 extern void init_multi_agent_built_in_commands(void);
02385 
02386 extern bool old_parse_go_command(void);
02387 extern void old_execute_go_selection(void);
02388 
02389 /*  this routine is defined in interface.c, but the Symbol struct
02390     hasn't been defined yet, so we can't declare it yet.  So kjc
02391     moved this prototype to ? ? ? 
02392 extern Symbol *read_identifier_or_context_variable (void);
02393 */
02394 
02395 extern void respond_to_load_errors(void);
02396 
02397 /* defined in tilde.c but also used in interface.c */
02398 extern char *tilde_expand(char *filename);
02399 
02400 /* AGR 568 begin */
02401 typedef struct expansion_node {
02402     struct lexeme_info lexeme;
02403     struct expansion_node *next;
02404 } expansion_node;
02405 
02406 typedef struct alias_struct {
02407     char *alias;
02408     struct expansion_node *expansion;
02409     struct alias_struct *next;
02410 } alias_struct;
02411 
02412 typedef struct dir_stack_struct {
02413     char *directory;
02414     struct dir_stack_struct *next;
02415 } dir_stack_struct;
02416 /* AGR 568 end */
02417 
02418 /* AGR 568  This bug fix concerned an alias command.  But I've expanded
02419    it a little to also include the pushd and popd commands, which are
02420    all being implemented for the release of 6.2.  11-May-94 */
02421 
02422 /* ======================================================================
02423                               parser.c
02424 
02425                      The Production (SP) Parser 
02426 
02427    Init_parser() should be called at startup time.  Parse_production()
02428    reads an SP (starting from the production name), builds a production,
02429    adds it to the rete, and returns a pointer to the new production
02430    (or NIL if any error occurred).  Parse_lhs() reads just an LHS,
02431    and returns a condition list (or NIL if an error occurred).  
02432    Parse_rhs() reads an RHS, setting "dest_rhs" to point to the resulting
02433    action list; it returns TRUE if successful, FALSE if any error occurred.
02434 ====================================================================== */
02435 
02436 extern void init_parser(void);
02437 extern condition *parse_lhs(void);
02438 extern bool parse_rhs(action ** dest_rhs);
02439 extern struct production_struct *parse_production(void);
02440 
02441 /* ======================================================================
02442                               print.c                                
02443 
02444     Printing with an Optional Log File and with Redirection to a File
02445 
02446    We want to print stuff not only to the screen but also to a log
02447    file (if one is currently being used).  The print_string(), print(),
02448    print_with_symbols(), and print_spaces() routines do this.
02449 
02450    Start_log_file() and stop_log_file() open and close the current log
02451    file.  Print_string_to_log_file_only() is called by the lexer to
02452    echo keyboard input to the log file (it's already on the screen, so
02453    we don't want to print it there too).
02454 
02455    Print_string() and print_spaces() do the obvious things.
02456    Print() is exactly like printf() in C, except it prints to both
02457    the screen and log file (if there is one).  Print_with_symbols()
02458    is sort of like print, but only takes two kinds of escape sequences
02459    in the format string: 
02460        %y  -- print a symbol
02461        %%  -- print a "%" sign
02462 
02463    Sometimes we need to know the current output column so we can put
02464    a line break in the right place.  Get_printer_output_column() returns
02465    the current column number (1 means the start of the line). 
02466    Tell_printer_that_output_column_has_been_reset () is called from the
02467    lexer every time it reads a line from the keyboard--since after the
02468    user types a line (and hits return) the output column is reset.
02469 
02470    We also support temporarily redirecting all printing output to
02471    another file.  This is done by calling start_redirection_to_file()
02472    and stop_redirection_to_file().  In between these calls, all screen
02473    and log file output is turned off, and printing is done only to the
02474    redirection file.
02475 ====================================================================== */
02476 
02477 extern void start_log_file(char *filename, bool append);
02478 extern void stop_log_file(void);
02479 extern void print_string_to_log_file_only(char *string);
02480 
02481 extern int get_printer_output_column(void);
02482 extern void tell_printer_that_output_column_has_been_reset(void);
02483 
02484 extern void start_redirection_to_file(FILE * already_opened_file);
02485 extern void stop_redirection_to_file(void);
02486 
02487 extern void print_string(char *s);
02488 #ifdef USE_STDARGS
02489 extern void print(char *format, ...);
02490 extern void print_with_symbols(char *format, ...);
02491 #else
02492 extern void print();
02493 extern void print_with_symbols();
02494 #endif
02495 extern void print_spaces(int n);
02496 
02497 /* ------------------------------------------------------------------------
02498                 String to Escaped String Conversion
02499            {Symbol, Test, RHS Value} to String Conversion
02500 
02501    These routines produce strings.  Each takes an optional parameter "dest"
02502    which, if non-nil, points to the destination buffer for the result string.
02503    If dest is nil, these routines use a global buffer, and return a pointer
02504    to it.  (Otherwise "dest" itself is returned.)  Note that a single global
02505    buffer is shared by all three routines, so callers should assume the
02506    buffer will be destroyed by the next call to these routines with dest=NIL.
02507 
02508    String_to_escaped_string() takes a string and a first/last char,
02509    and produces an "escaped string" representation of the string; i.e.,
02510    a string that uses '\' escapes to include special characters.
02511    For example, input 'ab"c' with first/last character '"' yields
02512    '"ab\"c"'.  This is used for printing quoted strings and for printing
02513    symbols using |vbar| notation.
02514  
02515    Symbol_to_string() converts a symbol to a string.  The "rereadable"
02516    parameter indicates whether a rereadable representation is desired.
02517    Normally symbols are printed rereadably, but for (write) and Text I/O,
02518    we don't want this.
02519 
02520    Test_to_string() takes a test and produces a string representation.
02521 
02522    Rhs_value_to_string() takes an rhs_value and produces a string
02523    representation.  The rhs_value MUST NOT be a reteloc.
02524 ----------------------------------------------------------------------- */
02525 
02526 extern char *string_to_escaped_string(char *s, char first_and_last_char, char *dest);
02527 extern char *symbol_to_string(Symbol * sym, bool rereadable, char *dest, size_t dest_size);
02528 extern char *test_to_string(test t, char *dest, size_t dest_size);
02529 extern char *rhs_value_to_string(rhs_value rv, char *dest, size_t dest_size);
02530 
02531 /* -----------------------------------------------------------------------
02532              Print Condition List, Action List, Production
02533 
02534    Print_condition_list() prints a list of conditions.  The "indent"
02535    parameter tells how many spaces to indent each line other than the
02536    first--the first line is not indented (the caller must handle this).
02537    The last line is printed without a trailing linefeed.  The "internal"
02538    parameter, if TRUE, indicates that the condition list should be printed
02539    in internal format--one condition per line, without grouping all the
02540    conditions for the same id into one line.
02541 
02542    Print_action_list() is similar except it prints actions instead of
02543    conditions.  The actions MUST NOT contain any reteloc's.
02544 
02545    Print_production() prints a given production, optionally using internal
02546    format.
02547 ----------------------------------------------------------------------- */
02548 
02549 extern void print_condition_list(condition * conds, int indent, bool internal);
02550 extern void print_action_list(action * actions, int indent, bool internal);
02551 extern void print_production(production * p, bool internal);
02552 
02553 /* -----------------------------------------------------------------------
02554                        Other Printing Utilities
02555 
02556    Print_condition() prints a single condition.  Print_action() prints
02557    a single action (which MUST NOT contain any reteloc's).
02558    Note that these routines work by calling print_condition_list() and
02559    print_action_list(), respectively, so they print a linefeed if the
02560    output would go past COLUMNS_PER_LINE.
02561 
02562    Preference_type_indicator() returns a character corresponding to
02563    a given preference type (byte)--for example, given BEST_PREFERENCE_TYPE,
02564    it returns '>'.
02565 
02566    Print_preference() prints a given preference.  Print_wme() prints a
02567    wme (including the timetag).  Print_instantiation_with_wmes() prints
02568    an instantiation's production name and the wmes it matched, using a
02569    given wme_trace_type (e.g., TIMETAG_WME_TRACE).
02570 ----------------------------------------------------------------------- */
02571 
02572 extern void print_condition(condition * cond);
02573 extern void print_action(action * a);
02574 extern char preference_type_indicator(byte type);
02575 extern void print_preference(preference * pref);
02576 extern void print_wme(wme * w);
02577 
02578 extern void print_instantiation_with_wmes(instantiation * inst, wme_trace_type wtt);
02579 
02580 extern void print_list_of_conditions(condition * cond); /* BUGBUG comments */
02581 
02582 /* ========================================================================
02583                                production.c
02584 
02585    Various utility routines for manipulating productions and parts thereof.
02586    Also includes the reorderer and compile-time o-support calculations.
02587 
02588    Init_production_utilities() should be called before anything else here.
02589 ======================================================================== */
02590 
02591 /* This structure is used to break ties in favor of non-multi-attributes */
02592 typedef struct multi_attributes_struct {
02593     Symbol *symbol;
02594     long value;
02595     struct multi_attributes_struct *next;
02596 } multi_attribute;
02597 
02598 extern void init_production_utilities(void);
02599 
02600 /* ------------------------------------------ */
02601 /* Utilities for symbols and lists of symbols */
02602 /* ------------------------------------------ */
02603 
02604 /* --- Looks at a symbol, returns appropriate first letter for a dummy
02605    variable or identifier to follow it.  Returns '*' if none found. --- */
02606 extern char first_letter_from_symbol(Symbol * sym);
02607 
02608 /* --- Takes a list of symbols and returns a copy of the same list,
02609    incrementing the reference count on each symbol in the list. --- */
02610 extern list *copy_symbol_list_adding_references(list * sym_list);
02611 
02612 /* --- Frees a list of symbols, decrementing their reference counts. --- */
02613 extern void deallocate_symbol_list_removing_references(list * sym_list);
02614 
02615 /* ------------------- */
02616 /* Utilities for tests */
02617 /* ------------------- */
02618 
02619 extern void add_all_variables_in_action(action * a, tc_number tc, list ** var_list);
02620 extern void add_bound_variables_in_test(test t, tc_number tc, list ** var_list);
02621 extern void add_bound_variables_in_condition(condition * c, tc_number tc, list ** var_list);
02622 extern void unmark_variables_and_free_list(list * var_list);
02623 
02624 /* --- Takes a test and returns a new copy of it. --- */
02625 extern test copy_test(test t);
02626 
02627 /* --- Same as copy_test(), only it doesn't include goal or impasse tests
02628    in the new copy.  The caller should initialize the two flags to FALSE
02629    before calling this routine; it sets them to TRUE if it finds a goal
02630    or impasse test. --- */
02631 extern test copy_test_removing_goal_impasse_tests(test t, bool * removed_goal, bool * removed_impasse);
02632 
02633 /* --- Deallocates a test. --- */
02634 extern void deallocate_test(test t);
02635 
02636 /* --- Destructively modifies the first test (t) by adding the second
02637    one (add_me) to it (usually as a new conjunct).  The first test
02638    need not be a conjunctive test. --- */
02639 extern void add_new_test_to_test(test * t, test add_me);
02640 
02641 /* --- Same as above, only has no effect if the second test is already
02642    included in the first one. --- */
02643 extern void add_new_test_to_test_if_not_already_there(test * t, test add_me);
02644 
02645 /* --- Returns TRUE iff the two tests are identical. --- */
02646 extern bool tests_are_equal(test t1, test t2);
02647 
02648 /* --- Returns a hash value for the given test. --- */
02649 extern unsigned long hash_test(test t);
02650 
02651 /* --- Returns TRUE iff the test contains an equality test for the given
02652    symbol.  If sym==NIL, returns TRUE iff the test contains any equality
02653    test. --- */
02654 extern bool test_includes_equality_test_for_symbol(test t, Symbol * sym);
02655 
02656 /* --- Looks for goal or impasse tests (as directed by the two flag
02657    parameters) in the given test, and returns TRUE if one is found. --- */
02658 extern bool test_includes_goal_or_impasse_id_test(test t, bool look_for_goal, bool look_for_impasse);
02659 
02660 /* --- Looks through a test, and returns a new copy of the first equality
02661    test it finds.  Signals an error if there is no equality test in the
02662    given test. --- */
02663 extern test copy_of_equality_test_found_in_test(test t);
02664 
02665 /* --- Looks through a test, returns appropriate first letter for a dummy
02666    variable to follow it.  Returns '*' if none found. --- */
02667 extern char first_letter_from_test(test t);
02668 
02669 /* ------------------------ */
02670 /* Utilities for conditions */
02671 /* ------------------------ */
02672 
02673 /* --- Deallocates a condition list (including any NCC's and tests in it). */
02674 extern void deallocate_condition_list(condition * cond_list);
02675 
02676 /* --- Returns a new copy of the given condition. --- */
02677 extern condition *copy_condition(condition * cond);
02678 
02679 /* --- Copies the given condition list, returning pointers to the
02680    top-most and bottom-most conditions in the new copy. --- */
02681 extern void copy_condition_list(condition * top_cond, condition ** dest_top, condition ** dest_bottom);
02682 
02683 /* --- Returns TRUE iff the two conditions are identical. --- */
02684 extern bool conditions_are_equal(condition * c1, condition * c2);
02685 
02686 /* --- Returns a hash value for the given condition. --- */
02687 extern unsigned long hash_condition(condition * cond);
02688 
02689 /* ------------------------------------ */
02690 /* Utilities for actions and RHS values */
02691 /* ------------------------------------ */
02692 
02693 /* --- Deallocates the given rhs_value. --- */
02694 extern void deallocate_rhs_value(rhs_value rv);
02695 
02696 /* --- Returns a new copy of the given rhs_value. --- */
02697 extern rhs_value copy_rhs_value(rhs_value rv);
02698 
02699 /* --- Deallocates the given action (singly-linked) list. --- */
02700 extern void deallocate_action_list(action * actions);
02701 
02702 /* --- Looks through an rhs_value, returns appropriate first letter for a
02703    dummy variable to follow it.  Returns '*' if none found. --- */
02704 extern char first_letter_from_rhs_value(rhs_value rv);
02705 
02706 /* ------------------ */
02707 /* Utilities for nots */
02708 /* ------------------ */
02709 
02710 /* --- Deallocates the given (singly-linked) list of Nots. --- */
02711 extern void deallocate_list_of_nots(not * nots);
02712 
02713 /* --------------------------------------------------------------------
02714                       Transitive Closure Utilities
02715                Marking, Unmarking, and Collecting Symbols
02716 
02717    Get_new_tc_number() is called from lots of places.  Any time we need
02718    to mark a set of identifiers and/or variables, we get a new tc_number
02719    by calling this routine, then proceed to mark various ids or vars
02720    by setting the sym->id.tc_num or sym->var.tc_num fields.
02721 
02722    Sometimes in addition to marking symbols using their tc_num fields,
02723    we also want to build up a list of the symbols we've marked.  So,
02724    the routines here take an "id_list" or "var_list" argument.  This
02725    argument should be NIL if no such list is desired.  If non-NIL, it
02726    should point to the header of the linked list being built.
02727 
02728        Transitive Closure Calculations for Conditions and Actions
02729 
02730    Usage: 
02731      1. Set my_tc = get_new_tc_number() to start a new TC
02732      2. (optional) If you want linked lists of symbols in the TC, initialize
02733         id_list=NIL and var_list=NIL.
02734         If you're not using id_list and/or var_list, give NIL for "&id_list"
02735         and/or "&var_list" in the function calls below.
02736      3. (optional) setup any id's or var's that you want to include in the
02737         initial TC, by calling 
02738            add_symbol_to_tc (sym, my_tc, &id_list, &var_list)
02739         (If not using id_list or var_list, you can just mark
02740          sym->{id,var}.tc_num = my_tc instead.)
02741      4. To do the work you want, use any of the following any number of times:
02742             add_cond_to_tc (cond, my_tc, &id_list, &var_list);
02743             add_action_to_tc (cond, my_tc, &id_list, &var_list);
02744             result = cond_is_in_tc (cond, my_tc);
02745             result = action_is_in_tc (action, my_tc);
02746      5. When finished, free the cons cells in id_list and var_list (but
02747         don't call symbol_remove_ref() on the symbols in them).
02748 
02749   Warning:  actions must not contain reteloc's or rhs unbound variables here.
02750 -------------------------------------------------------------------- */
02751 
02752 tc_number get_new_tc_number(void);
02753 
02754 extern void add_symbol_to_tc(Symbol * sym, tc_number tc, list ** id_list, list ** var_list);
02755 extern void add_cond_to_tc(condition * c, tc_number tc, list ** id_list, list ** var_list);
02756 extern void add_action_to_tc(action * a, tc_number tc, list ** id_list, list ** var_list);
02757 extern bool cond_is_in_tc(condition * cond, tc_number tc);
02758 extern bool action_is_in_tc(action * a, tc_number tc);
02759 
02760 /* --------------------------------------------------------------------
02761                          Variable Generator
02762 
02763    These routines are used for generating new variables.  The variables
02764    aren't necessarily "completely" new--they might occur in some existing
02765    production.  But we usually need to make sure the new variables don't
02766    overlap with those already used in a *certain* production--for instance,
02767    when variablizing a chunk, we don't want to introduce a new variable that
02768    conincides with the name of a variable already in an NCC in the chunk.
02769    
02770    To use these routines, first call reset_variable_generator(), giving
02771    it lists of conditions and actions whose variables should not be
02772    used.  Then call generate_new_variable() any number of times; each
02773    time, you give it a string to use as the prefix for the new variable's
02774    name.  The prefix string should not include the opening "<".
02775 -------------------------------------------------------------------- */
02776 
02777 extern void reset_variable_generator(condition * conds_with_vars_to_avoid, action * actions_with_vars_to_avoid);
02778 extern Symbol *generate_new_variable(char *prefix);
02779 
02780 /* -------------------------------------------------------------------
02781                          Production Management
02782  
02783     For each type of production, we maintain a doubly-linked list of
02784     all productions of that type.  The headers of these dll's are
02785     stored in the array all_productions_of_type[].  Another array,
02786     num_productions_of_type[], keeps counts of how many productions
02787     there are of each type.
02788 
02789     Production_add_ref() and production_remove_ref() are macros for
02790     incrementing and decrementing the reference count on a production.
02791     Production_remove_ref() also deallocates the production if the
02792     count goes to 0.
02793     
02794     Make_production() does reordering, compile-time o-support calc's,
02795     and builds and returns a production structure for a new production.
02796     It does not enter the production into the Rete net, however.
02797     The "type" argument should be one of USER_PRODUCTION_TYPE, etc.
02798     The flag "reorder_nccs" tells whether to recursively reorder
02799     the subconditions of NCC's--this is not necessary for newly
02800     built chunks, as their NCC's are copies of other NCC's in SP's that
02801     have already been reordered.  If any error occurs, make_production()
02802     returns NIL.
02803 
02804     Deallocate_production() and excise_production() do just what they
02805     say.  Normally deallocate_production() should be invoked only via
02806     the production_remove_ref() macro.
02807 ------------------------------------------------------------------- */
02808 
02809 #define production_add_ref(p) { (p)->reference_count++; }
02810 #define production_remove_ref(p) { \
02811   (p)->reference_count--; \
02812   if ((p)->reference_count == 0) \
02813     deallocate_production(p); }
02814 
02815 extern production *make_production(byte type,
02816                                    Symbol * name,
02817                                    condition ** lhs_top, condition ** lhs_bottom, action ** rhs_top, bool reorder_nccs);
02818 extern void deallocate_production(production * prod);
02819 extern void excise_production(production * prod, bool print_sharp_sign);
02820 
02821 extern bool canonical_cond_greater(condition * c1, condition * c2);
02822 
02823 /* =======================================================================
02824                                 reorder.c
02825    BUGBUG comments here
02826 ======================================================================= */
02827 
02828 extern bool reorder_action_list(action ** action_list, tc_number lhs_tc);
02829 extern bool reorder_lhs(condition ** lhs_top, condition ** lhs_bottom, bool reorder_nccs);
02830 extern void init_reorderer(void);
02831 
02832 /* =======================================================================
02833                                 recmem.c
02834 
02835    Init_firer() and init_chunker() should be called at startup time, to
02836    do initialization.
02837 
02838    Do_preference_phase() runs the entire preference phase.  This is called
02839    from the top-level control in main.c.
02840 
02841    Possibly_deallocate_instantiation() checks whether an instantiation
02842    can be deallocated yet, and does so if possible.  This is used whenever
02843    the (implicit) reference count on the instantiation decreases.
02844 ======================================================================= */
02845 
02846 extern void init_firer(void);
02847 extern void do_preference_phase(void);
02848 
02849 /* RBD BUGBUG more comments here */
02850 extern preference *find_clone_for_level(preference * p, goal_stack_level level);
02851 extern void fill_in_new_instantiation_stuff(instantiation * inst, bool need_to_do_support_calculations);
02852 
02853 /* mvp 5-17-94 */
02854 extern void build_prohibits_list(instantiation * inst);
02855 
02856 #define possibly_deallocate_instantiation(inst) { \
02857   if ((! (inst)->preferences_generated) && \
02858       (! (inst)->in_ms)) \
02859     deallocate_instantiation (inst); }
02860 
02861 extern void deallocate_instantiation(instantiation * inst);
02862 
02863 /* =======================================================================
02864                                backtrace.c
02865 ======================================================================= */
02866 
02867 /* RBD BUGBUG more comments here */
02868 extern void trace_locals(goal_stack_level grounds_level);
02869 extern void trace_grounded_potentials(void);
02870 extern bool trace_ungrounded_potentials(goal_stack_level grounds_level);
02871 extern void backtrace_through_instantiation(instantiation * inst,
02872                                             goal_stack_level grounds_level, condition * trace_cond, int indent);
02873 
02874 /* =======================================================================
02875                                 chunk.c
02876 ======================================================================= */
02877 
02878 /* RBD BUGBUG more comments here */
02879 #define CHUNK_COND_HASH_TABLE_SIZE 1024
02880 #define LOG_2_CHUNK_COND_HASH_TABLE_SIZE 10
02881 
02882 typedef struct chunk_cond_struct {
02883     condition *cond;            /* points to the original condition */
02884 
02885     condition *instantiated_cond;       /* points to cond in chunk instantiation */
02886     condition *variablized_cond;        /* points to cond in the actual chunk */
02887     condition *saved_prev_pointer_of_variablized_cond;  /* don't ask */
02888 
02889     /* dll of all cond's in a set (i.e., a chunk_cond_set, or the grounds) */
02890     struct chunk_cond_struct *next, *prev;
02891 
02892     /* dll of cond's in this particular hash bucket for this set */
02893     struct chunk_cond_struct *next_in_bucket, *prev_in_bucket;
02894 
02895     unsigned long hash_value;   /* equals hash_condition(cond) */
02896     unsigned long compressed_hash_value;        /* above, compressed to a few bits */
02897 } chunk_cond;
02898 
02899 typedef struct chunk_cond_set_struct {
02900     chunk_cond *all;            /* header for dll of all chunk_cond's in the set */
02901     chunk_cond *table[CHUNK_COND_HASH_TABLE_SIZE];      /* hash table buckets */
02902 } chunk_cond_set;
02903 
02904 extern void init_chunker(void);
02905 extern void chunk_instantiation(instantiation * inst, bool allow_variablization);
02906 extern chunk_cond *make_chunk_cond_for_condition(condition * cond);
02907 extern bool add_to_chunk_cond_set(chunk_cond_set * set, chunk_cond * new_cc);
02908 
02909 /* =======================================================================
02910                                 osupport.c
02911 
02912    Calculate_support_for_instantiation_preferences() does run-time o-support
02913    calculations -- it fills in pref->o_supported in each pref. on the
02914    instantiation.  Calculate_compile_time_o_support() does the compile-time
02915    version:  it takes the LHS and RHS, and fills in the a->support field in 
02916    each RHS action with either UNKNOWN_SUPPORT, O_SUPPORT, or I_SUPPORT.
02917 ======================================================================= */
02918 
02919 extern void calculate_support_for_instantiation_preferences(instantiation * inst);
02920 extern void calculate_compile_time_o_support(condition * lhs, action * rhs);
02921 
02922 extern void dougs_calculate_support_for_instantiation_preferences(instantiation * inst);
02923 
02924 /* =======================================================================
02925                                  rete.c
02926 
02927    All_wmes_in_rete is the header for a dll of all the wmes currently
02928    in the rete.  (This is normally equal to all of WM, except at times
02929    when WM changes have been buffered but not yet done.)  The wmes
02930    are linked via their "rete_next" and "rete_prev" fields.
02931    Num_wmes_in_rete counts how many wmes there are in the rete.
02932 
02933    Init_rete() initializes the rete.  It should be called at startup time.
02934 
02935    Any_assertions_or_retractions_ready() returns TRUE iff there are any
02936    pending changes to the match set.  This is used to test for quiescence.
02937    Get_next_assertion() retrieves a pending assertion (returning TRUE) or
02938    returns FALSE is no more are available.  Get_next_retraction() is
02939    similar.
02940 
02941    Add_production_to_rete() adds a given production, with a given LHS,
02942    to the rete.  If "refracted_inst" is non-NIL, it should point to an
02943    initial instantiation of the production.  This routine returns one
02944    of NO_REFRACTED_INST, REFRACTED_INST_MATCHED, etc. (see below).
02945    Excise_production_from_rete() removes the given production from the
02946    rete, and enqueues all its existing instantiations as pending
02947    retractions.
02948 
02949    Add_wme_to_rete() and remove_wme_from_rete() inform the rete of changes
02950    to WM.
02951 
02952    P_node_to_conditions_and_nots() takes a p_node and (optionally) a
02953    token/wme pair, and reconstructs the (optionally instantiated) LHS
02954    for the production.  The firer uses this to build the instantiated
02955    conditions; the printer uses it to reconstruct the LHS for printing.
02956    Get_symbol_from_rete_loc() takes a token/wme pair and a location
02957    specification (levels_up/field_num), examines the match (token/wme),
02958    and returns the symbol at that location.  The firer uses this for
02959    resolving references in RHS actions to variables bound on the LHS.
02960 
02961    Count_rete_tokens_for_production() returns a count of the number of 
02962    tokens currently in use for the given production.
02963 
02964    Print_partial_match_information(), print_match_set(), and
02965    the API function soar_ecPrintReteStatistics(),
02966    do printouts for various interface routines.
02967 
02968    Save_rete_net() and load_rete_net() are used for the fastsave/load
02969    commands.  They save/load everything to/from the given (already open)
02970    files.  They return TRUE if successful, FALSE if any error occurred.
02971 ======================================================================= */
02972 
02973 extern void init_rete(void);
02974 
02975 extern bool any_assertions_or_retractions_ready(void);
02976 extern bool get_next_assertion(production ** prod, struct token_struct **tok, wme ** w);
02977 extern bool get_next_retraction(struct instantiation_struct **inst);
02978 /* REW: begin 08.20.97 */
02979 /* Special routine for retractions in removed goals.  See note in rete.c */
02980 extern bool get_next_nil_goal_retraction(struct instantiation_struct **inst);
02981 /* REW: end   08.20.97 */
02982 
02983 #define NO_REFRACTED_INST 0     /* no refracted inst. was given */
02984 #define REFRACTED_INST_MATCHED 1        /* there was a match for the inst. */
02985 #define REFRACTED_INST_DID_NOT_MATCH 2  /* there was no match for it */
02986 #define DUPLICATE_PRODUCTION 3  /* the prod. was a duplicate */
02987 extern byte add_production_to_rete(production * p, condition * lhs_top,
02988                                    instantiation * refracted_inst, bool warn_on_duplicates);
02989 extern void excise_production_from_rete(production * p);
02990 
02991 extern void add_wme_to_rete(wme * w);
02992 extern void remove_wme_from_rete(wme * w);
02993 
02994 extern void p_node_to_conditions_and_nots(struct rete_node_struct *p_node,
02995                                           struct token_struct *tok,
02996                                           wme * w,
02997                                           condition ** dest_top_cond,
02998                                           condition ** dest_bottom_cond, not ** dest_nots, action ** dest_rhs);
02999 extern Symbol *get_symbol_from_rete_loc(unsigned short levels_up, byte field_num, struct token_struct *tok, wme * w);
03000 
03001 extern unsigned long count_rete_tokens_for_production(production * prod);
03002 extern void print_partial_match_information(struct rete_node_struct *p_node, wme_trace_type wtt);
03003 extern void print_match_set(wme_trace_type wtt, ms_trace_type mst);
03004 
03005 extern int get_node_count_statistic(const char *node_type_name, const char *column_name, unsigned long *result);
03006 
03007 extern bool save_rete_net(FILE * dest_file);
03008 extern bool load_rete_net(FILE * source_file);
03009 
03010 /* ====================================================================
03011                              rhsfun.c
03012 
03013    The system maintains a list of available RHS functions.  Functions
03014    can appear on the RHS of productions either as values (in make actions
03015    or as arguments to other function calls) or as stand-alone actions
03016    (e.g., "write" and "halt").  When a function is executed, its C code
03017    is called with one parameter--a (consed) list of the arguments (symbols).
03018    The C function should return either a symbol (if all goes well) or NIL
03019    (if an error occurred, or if the function is a stand-alone action).
03020 
03021    All available RHS functions should be setup at system startup time via
03022    calls to add_rhs_function().  It takes as arguments the name of the
03023    function (a symbol), a pointer to the corresponding C function, the
03024    number of arguments the function expects (-1 if the function can take
03025    any number of arguments), and flags indicating whether the function can
03026    be a RHS value or a stand-alone action.
03027 
03028    Lookup_rhs_function() takes a symbol and returns the corresponding
03029    rhs_function structure (or NIL if there is no such function).
03030 
03031    Init_built_in_rhs_functions() should be called at system startup time
03032    to setup all the built-in functions.
03033 ==================================================================== */
03034 
03035 typedef Symbol *((*rhs_function_routine) (list * args));
03036 
03037 typedef struct rhs_function_struct {
03038     struct rhs_function_struct *next;
03039     Symbol *name;
03040     rhs_function_routine f;
03041     int num_args_expected;      /* -1 means it can take any number of args */
03042     bool can_be_rhs_value;
03043     bool can_be_stand_alone_action;
03044 } rhs_function;
03045 
03046 extern void add_rhs_function(Symbol * name,
03047                              rhs_function_routine f,
03048                              int num_args_expected, bool can_be_rhs_value, bool can_be_stand_alone_action);
03049 extern rhs_function *lookup_rhs_function(Symbol * name);
03050 extern void init_built_in_rhs_functions(void);
03051 
03052 /* ======================================================================
03053                                 trace.c
03054 
03055    Object and stack trace formats are managed by this module.
03056 
03057    Init_tracing() initializes the tables; at this point, there are no trace
03058    formats for anything.  This routine should be called at startup time.
03059 
03060    Trace formats are changed by calls to add_trace_format() and
03061    remove_trace_format().  Add_trace_format() returns TRUE if the
03062    format was successfully added, or FALSE if the format string didn't
03063    parse right.  Remove_trace_format() returns TRUE if a trace format
03064    was actually removed, or FALSE if there was no such trace format for
03065    the given type/name restrictions.  These routines take a "stack_trace"
03066    argument, which should be TRUE if the stack trace format is intended,
03067    or FALSE if the object trace format is intended.  Their
03068    "type_restriction" argument should be one of FOR_ANYTHING_TF, ...,
03069    FOR_OPERATORS_TF.  The "name_restriction" argument should be either
03070    a pointer to a symbol, if the trace format is  restricted to apply
03071    to objects with that name, or NIL if the format can apply to any object.
03072    
03073    Print_all_trace_formats() prints out either all existing stack trace
03074    or object trace formats.
03075 
03076    Print_object_trace() takes an object (any symbol).  It prints the
03077    trace for that object.  Print_stack_trace() takes a (context)
03078    object (the state or op), the current state, the "slot_type"
03079    (one of FOR_OPERATORS_TF, etc.), and a flag indicating whether to
03080    allow %dc and %ec escapes (this flag should normally be TRUE for
03081    watch 0 traces but FALSE during a "print -stack" command).  It prints
03082    the stack trace for that context object.
03083 ====================================================================== */
03084 
03085 /* trace format type restrictions */
03086 #define FOR_ANYTHING_TF 0       /* format applies to any object */
03087 #define FOR_STATES_TF 1         /* format applies only to states */
03088 #define FOR_OPERATORS_TF 2      /* format applies only to operators */
03089 
03090 extern void init_tracing(void);
03091 extern bool add_trace_format(bool stack_trace, int type_restriction,
03092                              Symbol * name_restriction, const char *format_string);
03093 extern bool remove_trace_format(bool stack_trace, int type_restriction, Symbol * name_restriction);
03094 extern void print_all_trace_formats(bool stack_trace);
03095 
03096 extern void print_object_trace(Symbol * object);
03097 extern void print_stack_trace(Symbol * object, Symbol * state, int slot_type, bool allow_cycle_counts);
03098 
03099 extern char *help_on_trace_format_escapes[];
03100 
03101 /* =======================================================================
03102                                  io.c
03103 
03104                   General Soar I/O System Routines
03105 
03106    User-defined Soar I/O routines should be added at system startup time
03107    via calls to add_input_function() and add_output_function().  These 
03108    calls add things to the system's list of (1) functions to be called 
03109    every input cycle, and (2) symbol-to-function mappings for output
03110    commands.  File io.c contains the system I/O mechanism itself (i.e.,
03111    the stuff that calls the input and output functions), plus the text
03112    I/O routines.
03113 
03114    Init_soar_io() does what it say.  Do_input_cycle() and do_output_cycle()
03115    perform the entire input and output cycles -- these routines are called 
03116    once per elaboration cycle.  (once per Decision cycle in Soar 8).
03117    The output module is notified about WM changes via a call to
03118    inform_output_module_of_wm_changes().
03119 ======================================================================= */
03120 
03121 extern void init_soar_io(void);
03122 extern void do_input_cycle(void);
03123 extern void do_output_cycle(void);
03124 
03125 extern void inform_output_module_of_wm_changes(list * wmes_being_added, list * wmes_being_removed);
03126 
03127 /* =======================================================================
03128                                callback.c
03129 
03130    Callback.c contains a callback facility enabling users to add their
03131    own code to handle certain events occurring in the Soar architecture.
03132    For more details, see the descriptions of the individual callbacks, 
03133    in callback.h.
03134 ======================================================================= */
03135 
03136 #include "callback.h"
03137 
03138 extern unsigned long soar_global_callback_error;
03139 
03140 /* =======================================================================
03141                             Input Functions
03142  
03143    Input functions take one parameter--a mode (integer) indicating why the 
03144    function is being called.  The mode is either TOP_STATE_JUST_CREATED, 
03145    NORMAL_INPUT_CYCLE, or TOP_STATE_JUST_REMOVED.  In the input cycle
03146    immediately following the installation of the top state, each input
03147    function is called once with TOP_STATE_JUST_CREATED and then once with
03148    NORMAL_INPUT_CYCLE.  In the input cycle immediately following the removal
03149    of the top state, the functions are called with TOP_STATE_JUST_REMOVED.
03150    If the top state is *replaced*, the functions are called with 
03151    TOP_STATE_JUST_REMOVED, then TOP_STATE_JUST_CREATED, and then
03152    NORMAL_INPUT_CYCLE.
03153 
03154    Input routines create, modify, and delete input structures via calls
03155    to add_input_wme() and remove_input_wme().  The arguments to add_input_wme()
03156    indicate the id/attr/value components of the wme to be added.  Each of
03157    these components must be either (1) the current value of the global
03158    variable "top_state", or (2) the returned value from a call to 
03159    get_new_io_identifier(), get_io_sym_constant(), get_io_int_constant(),
03160    or get_io_float_constant().  [The idea behind creating the components this
03161    way is to avoid having I/O functions deal with the reference counts on
03162    symbols.]  For every call an I/O function makes to get_xxx(), it should
03163    later call release_io_symbol().  Release_io_symbol() should *not* be
03164    called with the value of "top_state"--*only* the components obtained via
03165    get_xxx().
03166    
03167    The add_input_wme() routine returns a pointer to the wme added.  The input
03168    routine shouldn't use this pointer in any way except to save it around for
03169    a later call to remove_input_wme().  Example:
03170 
03171          float current_sensor_value;
03172          wme *w;
03173          Symbol *s1,*s2;
03174          ... insert code to read value into current_sensor_value here ...
03175          s1 = get_io_sym_constant ("sensor-value");
03176          s2 = get_io_float_constant (current_sensor_value);
03177          ... add to working memory (S1 ^sensor-value 37.5) ...
03178          w = add_input_wme (top_state, s1, s2);
03179          release_io_symbol (s1);
03180          release_io_symbol (s2);
03181    
03182    On some later call, the input function might call remove_input_wme (w)
03183    to remove (S1 ^sensor-value 37.5) from working memory.
03184 
03185    To remove an entire input structure, it is sufficient for the input
03186    function to call remove_input_wme() on just the top link wme.  The input
03187    function need not call remove_input_wme() on each and every wme in the
03188    structure.  (Soar automagically garbage collects all the wmes in the
03189    now-disconnected structure.)  Note that when an input function is called
03190    with TOP_STATE_JUST_REMOVED, all existing input structures have already
03191    been garbage collected (since the top state no longer exists), so the 
03192    input function should never call remove_input_wme() when mode is
03193    TOP_STATE_JUST_REMOVED.  Remove_input_wme() normally returns TRUE,
03194    indicating success.  It returns FALSE if an error occurs (e.g., if the
03195    wme argument isn't in WM).
03196 ======================================================================= */
03197 
03198 #define TOP_STATE_JUST_CREATED 1
03199 #define NORMAL_INPUT_CYCLE 2
03200 #define TOP_STATE_JUST_REMOVED 3
03201 
03202 extern Symbol *get_new_io_identifier(char first_letter);
03203 extern Symbol *get_io_sym_constant(char *name);
03204 extern Symbol *get_io_int_constant(long value);
03205 extern Symbol *get_io_float_constant(float value);
03206 extern void release_io_symbol(Symbol * sym);
03207 
03208 extern wme *add_input_wme(Symbol * id, Symbol * attr, Symbol * value);
03209 extern bool remove_input_wme(wme * w);
03210 
03211 /* =======================================================================
03212                             Output Functions
03213  
03214    Output functions take two parameters--a mode (integer) indicating why the 
03215    function is being called, and a pointer to a chain of io_wme structures.
03216    The mode is either ADDED_OUTPUT_COMMAND (used when an output link is first
03217    created), MODIFIED_OUTPUT_COMMAND (used when the transitive closure of an
03218    existing link changes), or REMOVED_OUTPUT_COMMAND (used when the output
03219    link is removed from working memory).
03220 
03221    The chain of io_wme structures is connected via the "next" fields in the
03222    structures; for the last io_wme, next==NIL.  When mode is either
03223    ADDED_OUTPUT_COMMAND or MODIFIED_OUTPUT_COMMAND, this chain contains
03224    all the wmes in the current transitive closure of the output link
03225    (including the output link wme itself).  When mode is
03226    REMOVED_OUTPUT_COMMAND, the chain consists of just one io_wme--the top-level
03227    ouput link being removed.
03228   
03229    Output functions should inspect the io_wme chain and take whatever
03230    actions are appropriate.  Note that Soar deallocates the io_wme chain
03231    after calling the output function, so the output function is responsible
03232    for saving any necessary information around for later.
03233    
03234    How can an output function examine the io_wme's?  The io_wme structures
03235    indicate the id/attr/value of the wmes in the output structure.  See
03236    the comments above for symtab.c for an explanation of the structure
03237    of these symbols.
03238 
03239    Get_output_value() is a simple utility routine for finding things in
03240    an io_wme chain.  It takes "outputs" (the io_wme chain), and "id" and
03241    "attr" (symbols to match against the wmes), and returns the value from
03242    the first wme in the chain with a matching id and attribute.  Either
03243    "id" or "attr" (or both) can be specified as "don't care" by giving
03244    NULL (0) pointers for them instead of pointers to symbols.  If no matching
03245    wme is found, the function returns a NULL pointer.
03246 ======================================================================= */
03247 
03248 typedef struct io_wme_struct {
03249     /*
03250      *  12.08.00 Put next field last, so id,attr,value fall in same position
03251      * as in a wme structure
03252      */
03253     Symbol *id;                 /* id, attribute, and value of the wme */
03254     Symbol *attr;
03255     Symbol *value;
03256     struct io_wme_struct *next; /* points to next io_wme in the chain */
03257 } io_wme;
03258 
03259 enum captured_action_type {
03260     ADD_WME,
03261     REMOVE_WME
03262 };
03263 
03264 typedef struct captured_action_struct {
03265 
03266     struct captured_action_struct *next;
03267     int dc;
03268     enum captured_action_type action;
03269 
03270     void *args;
03271 
03272 } captured_action;
03273 
03274 #define ADDED_OUTPUT_COMMAND 1
03275 #define MODIFIED_OUTPUT_COMMAND 2
03276 #define REMOVED_OUTPUT_COMMAND 3
03277 
03278 typedef struct output_call_info_struct {
03279     int mode;
03280     io_wme *outputs;
03281 } output_call_info;
03282 
03283 extern Symbol *get_output_value(io_wme * outputs, Symbol * id, Symbol * attr);
03284 
03285 /* ===========================================================================
03286    Miscellaneous functions that I needed to declare because I used them in
03287    more than one file, even though they're not really part of a "module
03288    interface" or something like that.
03289 =========================================================================== */
03290 
03291 extern Symbol *get_next_io_symbol_from_text_input_line(char **text_read_position);      /* in io.c */
03292 
03293 /* -------------------------------------------------------------------- */
03294 /*                                                                      */
03295 /* Macros for handling multi-agent switching in Soar.                   */
03296 
03297 /* RBD BUGBUG more comments here, or should this stuff be here at all? */
03298 
03299 #define UPDATE_LINKS_NORMALLY 0
03300 #define UPDATE_DISCONNECTED_IDS_LIST 1
03301 #define JUST_UPDATE_COUNT 2
03302 
03303 /* AGR 564 begins */
03304 /* ======================================================================
03305                               explain.c
03306 ====================================================================== */
03307 
03308 /*
03309    For each production which is backtraced through, keep the name of the
03310    production, which condition was being traced (from the RHS of this
03311    production firing) and then the lists of grounds, potentials, locals
03312    and negateds generated during the backtrace.
03313    At the moment I'm not guaranteeing that each condition appears in the
03314    correct list -- this is because elements move between lists after their
03315    initial positioning.
03316 */
03317 
03318 #define PROD_NAME_SIZE 256
03319 typedef struct backtrace_struct {
03320     int result;                 /* 1 when this is a result of the chunk */
03321     condition *trace_cond;      /* The (local) condition being traced */
03322     char prod_name[PROD_NAME_SIZE];     /* The production's name */
03323     condition *grounds;         /* The list of conds for the LHS of chunk */
03324     condition *potentials;      /* The list of conds which aren't linked */
03325     condition *locals;          /* Conds in the subgoal -- need to BT */
03326     condition *negated;         /* Negated conditions (sub/super) */
03327     struct backtrace_struct *next_backtrace;    /* Pointer to next in this list */
03328 } backtrace_str;
03329 
03330 /*
03331    For each chunk (or justification) take a copy of its conds and actions,
03332    and the list of productions which were backtraced through in creating it.
03333    Also keep a list of all of the grounds (WMEs in the supergoal) which were
03334    tested as the chunk was formed.
03335 */
03336 
03337 typedef struct explain_chunk_struct {
03338     char name[PROD_NAME_SIZE];  /* Name of this chunk/justification */
03339     condition *conds;           /* Variablized list of conditions */
03340     action *actions;            /* Variablized list of actions */
03341     struct backtrace_struct *backtrace; /* List of back traced productions */
03342     struct explain_chunk_struct *next_chunk;    /* Next chunk in the list */
03343     condition *all_grounds;     /* All conditions which go to LHS -- 
03344                                    must be in same order as the chunk's 
03345                                    conditions. */
03346 } explain_chunk_str;
03347 /* AGR 564 ends */
03348 
03349 /* RBD added decl's of these routines because they were called from files
03350    other than explain.c.  I don't know what they do. */
03351 extern void explain_add_temp_to_backtrace_list(backtrace_str * temp,
03352                                                cons * grounds, cons * pots, cons * locals, cons * negateds);
03353 extern void explain_add_temp_to_chunk_list(explain_chunk_str * temp);
03354 extern void reset_backtrace_list(void);
03355 extern void reset_explain(void);
03356 extern void init_explain(void);
03357 extern void explain_full_trace(void);
03358 extern void explain_chunk(char *chunk_name, int cond_number);
03359 extern void explain_list_chunks(void);
03360 extern explain_chunk_str *find_chunk(explain_chunk_str * chunk, char *name);
03361 extern void explain_trace_chunk(explain_chunk_str * chunk);
03362 extern condition *find_ground(explain_chunk_str * chunk, int number);
03363 extern void explain_trace(char *chunk_name, backtrace_str * prod_list, condition * ground);
03364 
03365 /* REW: begin 08.20.97 */
03366 
03367 /* Export ms_change structure to entire code in order to include pointers to 
03368    assertion and retractions lists directly on goals. */
03369 
03370 /* BUGBUG ms changes only really need tok (the tok from the p-node),
03371    not a tok+wme pair.  Need to change the firer for this though. */
03372 
03373 /* --- info about a change to the match set --- */
03374 typedef struct ms_change_struct {
03375     struct ms_change_struct *next;      /* dll for all p nodes */
03376     struct ms_change_struct *prev;
03377     struct ms_change_struct *next_of_node;      /* dll for just this p node */
03378     struct ms_change_struct *prev_of_node;
03379     struct rete_node_struct *p_node;    /* for retractions, this can be NIL
03380                                            if the p_node has been excised */
03381     struct token_struct *tok;   /* for assertions only */
03382 
03383     wme *w;                     /* for assertions only */
03384     struct instantiation_struct *inst;  /* for retractions only */
03385 /* REW: begin 08.20.97 */
03386     Symbol *goal;
03387     goal_stack_level level;     /* Level of the match of the assertion or retraction */
03388     struct ms_change_struct *next_in_level;     /* dll for goal level */
03389     struct ms_change_struct *prev_in_level;
03390 /* REW: end   08.20.97 */
03391 } ms_change;
03392 /* REW: end 08.20.97 */
03393 
03394 /* !!!!!!!!!!!!!!!!  here's the agent structure !!!!!!!!!!!!!!!!!!!!!!!!*/
03395 /*----------------------------------------------------------------------*/
03396 /*                                                                      */
03397 /*  Agent structure used to hold what were previously global variables  */
03398 /*  in the single-agent Soar.                                           */
03399 /*                                                                      */
03400 /*----------------------------------------------------------------------*/
03401 
03402 /* WARNING!! If you add a new global into the Soar C code, be
03403    sure to use the current_agent macro to ensure compatibility
03404    with the multi-agent code!  E.g. if your new global is "foo"
03405    then do NOT refer to it in the code as "foo" but instead as
03406    "current_agent(foo)". */
03407 
03408 /* If you define a new global, initialize it in the create_soar_agent
03409    routine.  AGR 527c 3-May-94 */
03410 
03411 typedef struct agent_struct {
03412 
03413     /* ----------------------- Rete stuff -------------------------- */
03414 
03415     /* Hash tables for alpha memories, and for entries in left & right memories */
03416     void *left_ht;
03417     void *right_ht;
03418     hash_table *(alpha_hash_tables[16]);
03419 
03420     /* Number of WMEs, and list of WMEs, the Rete has been told about */
03421     unsigned long num_wmes_in_rete;
03422     wme *all_wmes_in_rete;
03423 
03424     /* Memory pools */
03425     memory_pool rete_node_pool;
03426     memory_pool rete_test_pool;
03427     memory_pool right_mem_pool;
03428     memory_pool token_pool;
03429     memory_pool alpha_mem_pool;
03430     memory_pool ms_change_pool;
03431     memory_pool node_varnames_pool;
03432 
03433     /* Dummy nodes and tokens */
03434     struct rete_node_struct *dummy_top_node;
03435     struct token_struct *dummy_top_token;
03436 
03437     /* Various Rete statistics counters */
03438     unsigned long rete_node_counts[256];
03439     unsigned long rete_node_counts_if_no_sharing[256];
03440     unsigned long token_additions;
03441     unsigned long token_additions_without_sharing;
03442     unsigned long num_right_activations;
03443     unsigned long num_left_activations;
03444     unsigned long num_null_right_activations;
03445     unsigned long num_null_left_activations;
03446 
03447     /* Miscellaneous other stuff */
03448     unsigned long alpha_mem_id_counter; /* node id's for hashing */
03449     unsigned long beta_node_id_counter;
03450     struct ms_change_struct *ms_assertions;     /* changes to match set */
03451     struct ms_change_struct *ms_retractions;
03452 
03453     /* ----------------------- Lexer stuff -------------------------- */
03454 
03455     lexer_source_file *current_file;    /* file we're currently reading */
03456     char current_char;          /* holds current input character */
03457     struct lexeme_info lexeme;  /* holds current lexeme */
03458     bool print_prompt_flag;
03459 
03460     /* ---------------- Predefined Symbols -------------------------
03461        Certain symbols are used so frequently that we create them at
03462        system startup time and never deallocate them.  
03463        ------------------------------------------------------------- */
03464 
03465     Symbol *attribute_symbol;
03466     Symbol *choices_symbol;
03467     Symbol *conflict_symbol;
03468     Symbol *constraint_failure_symbol;
03469     Symbol *goal_symbol;
03470     Symbol *impasse_symbol;
03471     Symbol *io_symbol;
03472     Symbol *item_symbol;
03473     Symbol *multiple_symbol;
03474     Symbol *name_symbol;
03475     Symbol *nil_symbol;
03476     Symbol *no_change_symbol;
03477     Symbol *none_symbol;
03478     Symbol *o_context_variable;
03479     Symbol *object_symbol;
03480     Symbol *operator_symbol;
03481     Symbol *problem_space_symbol;
03482     Symbol *quiescence_symbol;
03483     Symbol *s_context_variable;
03484     Symbol *so_context_variable;
03485     Symbol *ss_context_variable;
03486     Symbol *sso_context_variable;
03487     Symbol *sss_context_variable;
03488     Symbol *state_symbol;
03489     Symbol *superstate_symbol;
03490     Symbol *t_symbol;
03491     Symbol *tie_symbol;
03492     Symbol *to_context_variable;
03493     Symbol *ts_context_variable;
03494     Symbol *type_symbol;
03495     Symbol *wait_symbol;        /* REW:  10.24.97 */
03496 
03497     /* ----------------------- Symbol table stuff -------------------------- */
03498 
03499     unsigned long current_symbol_hash_id;
03500     unsigned long id_counter[26];
03501 
03502     struct hash_table_struct *float_constant_hash_table;
03503     struct hash_table_struct *identifier_hash_table;
03504     struct hash_table_struct *int_constant_hash_table;
03505     struct hash_table_struct *sym_constant_hash_table;
03506     struct hash_table_struct *variable_hash_table;
03507 
03508     memory_pool float_constant_pool;
03509     memory_pool identifier_pool;
03510     memory_pool int_constant_pool;
03511     memory_pool sym_constant_pool;
03512     memory_pool variable_pool;
03513 
03514     /* ----------------------- Top-level stuff -------------------------- */
03515 
03516     /* --- headers of dll's of all productions of each type --- */
03517     production *all_productions_of_type[NUM_PRODUCTION_TYPES];
03518     /* --- counts of how many productions there are of each type --- */
03519     unsigned long num_productions_of_type[NUM_PRODUCTION_TYPES];
03520 
03521     /* --- lists of symbols (PS names) declared chunk-free and chunky --- */
03522     list *chunk_free_problem_spaces;
03523     list *chunky_problem_spaces;        /* AGR MVL1 */
03524 
03525     /* --- default depth for "print" command --- */
03526     int default_wme_depth;      /* AGR 646 */
03527 
03528     /* --- stuff for "input-period" command --- */
03529     /* --- in Soar8, input runs once at beginning of D cycle, no matter what */
03530     int input_period;           /* AGR REW1 */
03531     bool input_cycle_flag;      /* AGR REW1 */
03532 
03533     /* --- current top level phase --- */
03534     enum top_level_phase current_phase;
03535 
03536     /* --- to interrupt at the end of the current phase, set stop_soar to TRUE
03537        and reason_for_stopping to some appropriate string --- */
03538     byte stop_soar;
03539     const char *reason_for_stopping;
03540 
03541     /* --- the RHS action (halt) sets this TRUE --- */
03542     bool system_halted;
03543 
03544     /* --- stuff for max-chunks (which is a sysparam) --- */
03545     unsigned long chunks_this_d_cycle;  /* # chunks built this DC */
03546     bool max_chunks_reached;
03547 
03548     /* --- list of productions whose firings are being traced --- */
03549     list *productions_being_traced;
03550 
03551     /* --- various user-settable system parameters --- */
03552     long sysparams[HIGHEST_SYSPARAM_NUMBER + 1];
03553 
03554     /* --- parameters for running Soar --- */
03555     /*  --- the code loops go_number times over the go_type phases --- */
03556     long go_number;             /* How many times to "go" */
03557     Symbol *go_slot_attr;       /* The context slot checked */
03558     goal_stack_level go_slot_level;     /* The goal stack level checked */
03559     enum go_type_enum go_type;  /* The phase type used */
03560 
03561     /* --- Top-level Statistics --- */
03562 
03563     /* running total of WM sizes at end of phases */
03564     double cumulative_wm_size;
03565     /* number of items included in "cumulative_wm_size" sum */
03566     unsigned long num_wm_sizes_accumulated;
03567 
03568     unsigned long max_wm_size;  /* maximum size of WM so far */
03569     unsigned long wme_addition_count;   /* # of wmes added to WM */
03570     unsigned long wme_removal_count;    /* # of wmes removed from WM */
03571     unsigned long d_cycle_count;        /* # of DC's run so far */
03572     unsigned long e_cycle_count;        /* # of EC's run so far */
03573     /*  in Soar 8, e_cycles_this_d_cycle is reset to zero for every
03574        propose and apply phase */
03575     unsigned long e_cycles_this_d_cycle;        /* # of EC's run this DC */
03576     unsigned long num_existing_wmes;    /* current WM size */
03577     unsigned long production_firing_count;      /* # of prod. firings */
03578 
03579     /* REW: begin 09.15.96 */
03580 /* in Soar 8, PE's are done only during the APPLY phase */
03581     unsigned long pe_cycle_count;       /* # of PE's run so far */
03582     unsigned long pe_cycles_this_d_cycle;       /* # of PE's run this DC */
03583 
03584     parent_inst *parent_list_head;
03585 /* REW: end   09.15.96 */
03586 
03587     /* ----------------------- Timing statistics -------------------------- */
03588 
03589 /* 
03590 For Soar 7, the timing code has been completely revamped.  When the compile
03591 flag NO_TIMING_STUFF is not set, statistics will be now be collected on the
03592 total cpu time, total kernel time, time spent in the individual phases of a
03593 decision cycle, time spent executing the input and output functions, and time
03594 spent executing callbacks (or monitors).  When the DETAILED_TIMING_STATS flag
03595 is set, additional statistics will be collected for ownership, match, and
03596 chunking computations according to the phase in which they occur. (Notice
03597 that DETAILED_TIMING_STATS can only be collected when NO_TIMING_STUFF is not
03598 true.)
03599 
03600 The total_cpu_time is turned on when one of the run_<x> functions is
03601 initiated.  This timer is not turned off while the do_one_top_level_phase()
03602 function is executing.  The total_kernel_time timer is turned on just after
03603 the total_cpu_time timer and turned off just before the other is turned off.
03604 This guarantees that the total kernel time -- including the time it takes to
03605 turn on and off the kernel timer -- is a part of the total cpu time.  The
03606 total_kernel_time is also turned off whenever a callback is initiated or when
03607 the input and output functions are executing.
03608 
03609 The decision_cycle_phase_timers measure the kernel time for each phase of the
03610 decision cycle (ie, INPUT_PHASE, PREFERENCE_PHASE, WM_PHASE, OUTPUT_PHASE,
03611 and DECISION_PHASE).  Each is turned on at the beginning of its corresponding
03612 phase in do_one_top_level_phase and turned off at the end of that phase.
03613 These timers are also turned off for callbacks and during the execution of
03614 the input and output functions.
03615 
03616 The monitors_cpu_time timers are also indexed by the current phase.  Whenever
03617 a callback is initiated, both the total_kernel_time and
03618 decision_cycle_phase_timer for the current phase are turned off and the
03619 monitors_cpu_time turned on.  After the callback has terminated, the kernel
03620 timers are turned back on.  Notice that the same relationship holds here as
03621 it did between the total_cpu_time and total_kernel_time timers.  The
03622 total_kernel_time is always turned off last and turned on first, in
03623 comparison to the decision_cycle_phase_timer.  This means that turning the
03624 decision_cycle_phase_timers on and off is included as part of the kernel time
03625 and helps ensure that the total_kernel_time is always greater than the sum of
03626 the decision_cycle_timers.
03627 
03628 The input_function_cpu_time and output_function_cpu_time timers measure the
03629 time it takes to execute the input and output functions respectively.  Both
03630 the total_kernel_time and decision_cycle_phase_timers are turned off when
03631 these timers are turned on (with the same ordering as discussed previously).
03632 The input function is a little tricky.  Because add-wme can be called by the
03633 input routine, which then calls do_buffered_wm_and_ownership_changes, we
03634 can't just turn off the kernel timers for input and expect to get numbers for
03635 both match_time (see next para) and kernel time.  The solution implemented in
03636 the 28.07.96 changes is to not turn off the kernel timers until the actual
03637 INPUT_PHASE_CALLBACK is initiated.  This takes care of all but direct
03638 additions and removals of WMEs.  Since these are done through the add-wme and
03639 remove-wme commands, the input_timer is turned off there was well, and the
03640 kernel timers turned back on (for the buffered wm changes).  However, this is
03641 a hack and may introduce problems when add-wme and remove-wme are used at the
03642 command line or someplace in the decision cycle other than input (probably
03643 rare but possible).
03644 
03645 The DETAILED_TIMING_STATS flag enables collection of statistics on match,
03646 ownership and chunking calculations performed in each part of the decision
03647 cycle.  An 'other' value is reported which is simply the difference between
03648 the sum of the deailed timers and the kernel timer for some pahse.  The other
03649 value should always be greater than or equal to zero.
03650 
03651 The "stats" command (in soarCommandUtils) has been updated to report these
03652 new timing values.  The output is provided in a spreadsheet-style format to
03653 display the information in a succinct form.  There are also some derived
03654 totals in that report.  The derived totals in the right column are simply the
03655 sum of the all the other columns in a particular row; for example, the
03656 derived total for the first row, kernel time, is just the sum of all the
03657 decision_cycle_phase_timers.  The derived totals in the bottom row are the
03658 sum of all the basic timers in that row (i.e., no DETAILED statistics are
03659 included in the sum).  For example, the derived total under input is equal to
03660 the sum of decision_cycle_phase_timer and the monitors_time for the
03661 INPUT_PHASE, and the input_function_cpu_time and represents the total time
03662 spent in the input phase for the current run.  The number in the lower
03663 right-hand corner is the sum of the derived totals above it in that right
03664 column (and should always be equal to the numbers to the left of it in that
03665 row).
03666 
03667 Also reported with the stats command are the values of total_cpu_time and
03668 total_kernel_time.  If the ordering discussed above is strictly enforced,
03669 total_kernel_time should always be slightly greater than the derived total
03670 kernel time and total_cpu_time greater than the derived total CPU time. REW */
03671 
03672 /* REW: begin 28.07.96 */
03673 #ifndef NO_TIMING_STUFF
03674 
03675     TIMER_VALUE start_total_tv;
03676     TIMER_VALUE total_cpu_time;
03677     TIMER_VALUE start_kernel_tv, start_phase_tv;
03678     TIMER_VALUE total_kernel_time;
03679 
03680     TIMER_VALUE decision_cycle_phase_timers[6];
03681     TIMER_VALUE monitors_cpu_time[6];
03682     TIMER_VALUE input_function_cpu_time;
03683     TIMER_VALUE output_function_cpu_time;
03684 /* REW: end 28.07.96 */
03685 
03686 /* REW: begin 28.07.96 */
03687     /* accumulated cpu time spent in various parts of the system */
03688 #ifdef DETAILED_TIMING_STATS
03689     TIMER_VALUE ownership_cpu_time[6];
03690     TIMER_VALUE chunking_cpu_time[6];
03691     TIMER_VALUE match_cpu_time[6];
03692 /* REW: begin 11.25.96 */
03693     TIMER_VALUE start_gds_tv, total_gds_time;
03694     TIMER_VALUE gds_cpu_time[6];
03695 /* REW: end   11.25.96 */
03696 /* REW: end 28.07.96 */
03697 #endif
03698 
03699 #ifdef DC_HISTOGRAM
03700     TIMER_VALUE *dc_histogram_tv;
03701     int dc_histogram_sz;
03702     int dc_histogram_offset;
03703     TIMER_VALUE start_dc_tv;
03704     int dc_histogram_freq;
03705     bool dc_histogram_now;
03706 #endif                          /* DC_HISTOGRAM */
03707 
03708 #ifdef KT_HISTOGRAM
03709     TIMER_VALUE *kt_histogram_tv;
03710     int kt_histogram_sz;
03711     int kt_histogram_offset;
03712 #endif
03713 
03714 #endif                          /* !NO_TIMING_STUFF */
03715 
03716 #ifdef REAL_TIME_BEHAVIOR
03717     /* RMJ */
03718     /* Keep track of real time steps for constant real-time per decision */
03719     TIMER_VALUE *real_time_tracker;
03720     bool real_time_idling;
03721 #endif
03722 
03723 #ifdef ATTENTION_LAPSE
03724     /* RMJ */
03725     /* Keep track of duration of attentional lapses */
03726     TIMER_VALUE *attention_lapse_tracker;
03727     bool attention_lapsing;
03728 #endif
03729 
03730     /* ----------------------- Chunker stuff -------------------------- */
03731 
03732     tc_number backtrace_number;
03733     memory_pool chunk_cond_pool;
03734     unsigned long chunk_count;
03735     unsigned long justification_count;
03736     bool chunk_free_flag;
03737     bool chunky_flag;           /* AGR MVL1 */
03738     list *grounds;
03739     tc_number grounds_tc;
03740     list *instantiations_with_nots;
03741     list *locals;
03742     tc_number locals_tc;
03743     list *positive_potentials;
03744     tc_number potentials_tc;
03745     chunk_cond_set negated_set;
03746     preference *results;
03747     goal_stack_level results_match_goal_level;
03748     tc_number results_tc_number;
03749     tc_number variablization_tc;
03750     bool variablize_this_chunk;
03751     preference *extra_result_prefs_from_instantiation;
03752     bool quiescence_t_flag;
03753     char chunk_name_prefix[kChunkNamePrefixMaxLength];  /* kjh (B14) */
03754 
03755     /* ----------------------- Misc. top-level stuff -------------------------- */
03756 
03757     memory_pool action_pool;
03758     memory_pool complex_test_pool;
03759     memory_pool condition_pool;
03760     memory_pool not_pool;
03761     memory_pool production_pool;
03762 
03763     /* ----------------------- Reorderer stuff -------------------------- */
03764 
03765     memory_pool saved_test_pool;
03766 
03767     /* ----------------------- Memory utilities -------------------------- */
03768 
03769     /* Counters for memory usage of various types */
03770     unsigned long memory_for_usage[NUM_MEM_USAGE_CODES];
03771 
03772     /* List of all memory pools being used */
03773     memory_pool *memory_pools_in_use;
03774 
03775     memory_pool cons_cell_pool; /* pool for cons cells */
03776     memory_pool dl_cons_pool;   /* doubly-linked list cells */
03777 
03778     /* ----------------------- Explain.c stuff -------------------------- */
03779 
03780     backtrace_str *explain_backtrace_list;      /* AGR 564 */
03781     explain_chunk_str *explain_chunk_list;      /* AGR 564 */
03782     char explain_chunk_name[256];       /* AGR 564 */
03783     /* made explain_flag EXPLAIN_SYSPARAM instead, KJC 7/96 */
03784     /* bool                explain_flag; */
03785 
03786     /* ----------------------- Firer stuff -------------------------- */
03787 
03788     memory_pool instantiation_pool;
03789     instantiation *newly_created_instantiations;
03790 
03791     /* production_being_fired -- during firing, points to the prod. being fired */
03792     production *production_being_fired;
03793 
03794     unsigned long max_rhs_unbound_variables;
03795     Symbol **rhs_variable_bindings;
03796 
03797     /* ==================================================================
03798        Decider stuff 
03799        =================================================================== */
03800 
03801     memory_pool preference_pool;
03802 
03803     unsigned long current_wme_timetag;
03804     memory_pool wme_pool;
03805     list *wmes_to_add;
03806     list *wmes_to_remove;
03807 
03808     /* ---------------------------------------------------------------------
03809        Top_goal and bottom_goal point to the top and bottom goal identifiers,
03810        respectively.  (If there is no goal stack at all, they're both NIL.)
03811        Top_state points to the top state (symbol) if there is a top state, and
03812        is NIL of there isn't any top state selected.
03813        --------------------------------------------------------------------- */
03814 
03815     Symbol *bottom_goal;
03816     Symbol *top_goal;
03817     Symbol *top_state;
03818 
03819     Symbol *highest_goal_whose_context_changed;
03820     dl_list *changed_slots;
03821     dl_list *context_slots_with_changed_acceptable_preferences;
03822     memory_pool slot_pool;
03823     list *slots_for_possible_removal;
03824 
03825     dl_list *disconnected_ids;
03826     goal_stack_level highest_level_anything_could_fall_from;
03827     dl_list *ids_with_unknown_level;
03828     goal_stack_level lowest_level_anything_could_fall_to;
03829     tc_number mark_tc_number;
03830     goal_stack_level level_at_which_marking_started;
03831     goal_stack_level walk_level;
03832     tc_number walk_tc_number;
03833     list *promoted_ids;
03834     int link_update_mode;
03835 
03836     /* ------------------ Printing utilities stuff --------------------- */
03837 
03838 #define PRINTED_OUTPUT_STRING_SIZE MAX_LEXEME_LENGTH*2+10
03839     FILE *log_file;
03840     char *log_file_name;
03841     bool logging_to_file;
03842     char printed_output_string[PRINTED_OUTPUT_STRING_SIZE];
03843     int printer_output_column;
03844     bool redirecting_to_file;
03845     FILE *redirection_file;
03846     int saved_printer_output_column;
03847 
03848     /* kjh(CUSP-B10) begin */
03849     /* ------------------ Recording/replaying stuff --------------------- */
03850     /*  bool                replaying; */
03851     /* kjh(CUSP-B10) end */
03852 
03853 #ifdef USE_CAPTURE_REPLAY
03854     FILE *capture_fileID;
03855     FILE *replay_fileID;
03856     unsigned long *replay_timetags;
03857     captured_action **replay_actions;
03858     unsigned long dc_to_replay;
03859     bool timetag_mismatch;
03860 #endif
03861 
03862     /* ----------------------- Trace Formats -------------------------- */
03863 
03864     struct trace_format_struct *(object_tf_for_anything[3]);
03865     struct hash_table_struct *(object_tr_ht[3]);
03866     bool printing_stack_traces;
03867     struct trace_format_struct *(stack_tf_for_anything[3]);
03868     struct hash_table_struct *(stack_tr_ht[3]);
03869     tc_number tf_printing_tc;
03870 
03871     list *wme_filter_list;      /* kjh(CUSP-B2) */
03872 
03873     /* ----------------------- RHS Function Stuff -------------------------- */
03874 
03875     /* --- "interrupt" fun. uses this to build "reason_for_stopping" msg. --- */
03876 #define INTERRUPT_SOURCE_SIZE 2*MAX_LEXEME_LENGTH+100
03877     char interrupt_source[INTERRUPT_SOURCE_SIZE];
03878 
03879     /* --- "make-constant-symbol" counter --- */
03880     unsigned long mcs_counter;
03881 
03882     /* ----------------------- O support stuff -------------------------- */
03883 
03884     tc_number o_support_tc;
03885     preference *rhs_prefs_from_instantiation;
03886 
03887     /* ----------------------- I/O stuff -------------------------- */
03888 
03889     io_wme *collected_io_wmes;
03890     struct output_link_struct *existing_output_links;
03891 
03892     struct output_link_struct *output_link_for_tc;
03893     memory_pool output_link_pool;
03894     tc_number output_link_tc_num;
03895 
03896     bool output_link_changed;
03897 
03898     Symbol *io_header;
03899     wme *io_header_link;
03900 
03901     Symbol *io_header_input;
03902     Symbol *io_header_output;
03903 
03904     memory_pool io_wme_pool;
03905     Symbol *prev_top_state;
03906 
03907     /* ------------ Varible Generator stuff (in production.c) ---------------- */
03908 
03909     unsigned long current_variable_gensym_number;
03910     unsigned long gensymed_variable_count[26];
03911 
03912     /* ------------------- Experimental features ---------------------- */
03913     int o_support_calculation_type;
03914     int attribute_preferences_mode;
03915 
03916     /* ------------------- Info about the agent itself ---------------------- */
03917 
03918     char *name;                 /* name of this Soar agent */
03919     int id;                     /* unique integer id */
03920     unsigned long callback_error;       /* an error status set during callback */
03921 
03922 /* --------- I (RBD) don't know what the following stuff is ------------ */
03923 
03924     /* String redirection */
03925     /*  
03926        bool                   using_input_string;
03927        char                 * input_string;
03928        bool                   using_output_string;
03929        char                 * output_string;
03930      */
03931 
03932     /*mvp 5-17-94 */
03933     list *variables_set;
03934 
03935     multi_attribute *multi_attributes;
03936     /* char                path[MAXPATHLEN];    AGR 568 */
03937 
03938     soar_callback_array soar_callbacks;
03939 
03940     alias_struct *alias_list;   /* AGR 568 */
03941     const char *alternate_input_string;
03942     const char *alternate_input_suffix;
03943     bool alternate_input_exit;  /* Soar-Bugs #54, TMH */
03944     expansion_node *lex_alias;  /* AGR 568 */
03945     bool load_errors_quit;      /* AGR 527c */
03946     dir_stack_struct *top_dir_stack;    /* AGR 568 */
03947 
03948     /* RCHONG: begin 10.11 */
03949     bool did_PE;
03950     bool soar_verbose_flag;
03951     int FIRING_TYPE;
03952     Symbol *PE_level;
03953 
03954     struct ms_change_struct *ms_o_assertions;   /* changes to match set */
03955     struct ms_change_struct *ms_i_assertions;   /* changes to match set */
03956     /* RCHONG: end 10.11 */
03957 
03958     /* REW: begin 08.20.97 */
03959 #ifndef SOAR_8_ONLY
03960     bool operand2_mode;
03961 #endif
03962     goal_stack_level active_level;
03963     goal_stack_level previous_active_level;
03964     Symbol *active_goal;
03965     Symbol *previous_active_goal;
03966     struct ms_change_struct *nil_goal_retractions;      /* dll of all retractions for removed (ie nil) goals */
03967     /* REW: end   08.20.97 */
03968 
03969     /* delineate btwn Pref/WM(propose) and Pref/WM(apply) KJC 10.05.98 */
03970     bool applyPhase;
03971 
03972     /* REW: begin 10.24.97 */
03973     bool waitsnc;
03974     bool waitsnc_detect;
03975     /* REW: end   10.24.97 */
03976 
03977     enum ni_mode numeric_indifferent_mode;      /* SW 08.19.2003 */
03978 
03979 #ifdef COUNT_KERNEL_TIMER_STOPS
03980     long kernelTimerStops;
03981     long nonKernelTimerStops;
03982 #endif
03983 #ifdef USE_AGENT_DBG_FILE
03984     FILE *dbgFile;
03985 #endif
03986 #ifdef WARN_IF_TIMERS_REPORT_ZERO
03987     bool warn_on_zero_timers;
03988 #endif
03989 
03990 } agent;
03991 /*************** end of agent struct *****/
03992 
03993 typedef struct output_link_struct {
03994     struct output_link_struct *next, *prev;     /* dll of all existing links */
03995     byte status;                /* current xxx_OL_STATUS */
03996     wme *link_wme;              /* points to the output link wme */
03997     list *ids_in_tc;            /* ids in TC(link) */
03998     soar_callback *cb;          /* corresponding output function */
03999 } output_link;
04000 
04001 extern agent *soar_agent;
04002 extern list *all_soar_agents;
04003 extern int agent_count;
04004 
04005 extern agent *create_soar_agent(char *name);
04006 extern void destroy_soar_agent(agent * soar_agent);
04007 
04008 extern char *c_interrupt_msg;
04009 
04010 /* Main pgm stuff */
04011 
04012 extern void init_soar(void);
04013 extern int terminate_soar(void);
04014 
04015 #ifdef __cplusplus
04016 #undef extern
04017 #endif
04018 
04019 #endif                          /* _SOAR_H_INCLUDED */

Generated on Thu Dec 11 13:00:23 2003 for Soar Kernel by doxygen 1.3.5