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

symtab.c

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  file:  symtab.c
00004  *
00005  * =======================================================================
00006  *  
00007  *                 Symbol Table Routines for Soar 6
00008  *
00009  * Soar 6 uses five kinds of symbols:  symbolic constants, integer
00010  * constants, floating-point constants, identifiers, and variables.
00011  * We use five resizable hash tables, one for each kind of symbol.
00012  *
00013  *   "symbol" is typedef-ed as a union of the five kinds of symbol
00014  *  structures.  Some fields common to all symbols are accessed via
00015  *  sym->common.field_name; fields particular to a certain kind of
00016  *  symbol are accessed via sym->var.field_name_on_variables, etc.
00017  *  See soarkernel.h for the Symbol structure definitions.
00018  *
00019  * =======================================================================
00020  *
00021  * Copyright 1995-2003 Carnegie Mellon University,
00022  *                                                                               University of Michigan,
00023  *                                                                               University of Southern California/Information
00024  *                                                                               Sciences Institute. All rights reserved.
00025  *                                                                              
00026  * Redistribution and use in source and binary forms, with or without
00027  * modification, are permitted provided that the following conditions are met:
00028  *
00029  * 1.   Redistributions of source code must retain the above copyright notice,
00030  *              this list of conditions and the following disclaimer. 
00031  * 2.   Redistributions in binary form must reproduce the above copyright notice,
00032  *              this list of conditions and the following disclaimer in the documentation
00033  *              and/or other materials provided with the distribution. 
00034  *
00035  * THIS SOFTWARE IS PROVIDED BY THE SOAR CONSORTIUM ``AS IS'' AND ANY EXPRESS OR
00036  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00037  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00038  * EVENT SHALL THE SOAR CONSORTIUM  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00039  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00040  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00041  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00042  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00043  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00044  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00045  * The views and conclusions contained in the software and documentation are
00046  * those of the authors and should not be interpreted as representing official
00047  * policies, either expressed or implied, of Carnegie Mellon University, the
00048  * University of Michigan, the University of Southern California/Information
00049  * Sciences Institute, or the Soar consortium.
00050  * =======================================================================
00051  */
00052 
00053 /* Uncomment the following line to get symbol debugging printouts */
00054 /* #define DEBUG_SYMBOLS */
00055 
00056 #include "soarkernel.h"
00057 #include <ctype.h>
00058 
00059 /* -------------------------------------------------------------------
00060                            Hash Functions
00061 
00062    Compress() takes a 32-bit hash value and compresses it down to a few
00063    bits, xor-ing pieces of the 32-bit value to avoid throwing away bits
00064    that might be important for the hash function to be effective.
00065    
00066    Hash_string() produces a hash value for a string of characters.
00067 
00068    Hash_xxx_raw_info() are the hash functions for the five kinds of
00069    symbols.  These functions operate on the basic info about the symbol
00070    (i.e., the name, value, etc.).  Hash_xxx(), on the other hand,
00071    operate on the symbol table entries for the five kinds of symbols--
00072    these routines are the callback hashing functions used by the
00073    resizable hash table routines.
00074 ------------------------------------------------------------------- */
00075 
00076 unsigned long compress(unsigned long h, short num_bits)
00077 {
00078     unsigned long result;
00079 
00080     if (num_bits < 16)
00081         h = (h & 0xFFFF) ^ (h >> 16);
00082     if (num_bits < 8)
00083         h = (h & 0xFF) ^ (h >> 8);
00084     result = 0;
00085     while (h) {
00086         result ^= (h & masks_for_n_low_order_bits[num_bits]);
00087         h = h >> num_bits;
00088     }
00089     return result;
00090 }
00091 
00092 unsigned long hash_string(const char *s)
00093 {                               /* AGR 600 */
00094     unsigned long h;
00095 
00096     h = 0;
00097     while (*s != 0) {
00098         h = ((h << 8) | (h >> 24)) ^ (*s);
00099         s++;
00100     }
00101     return h;
00102 }
00103 
00104 /* -----------------------------------------
00105    Hashing symbols using their basic info 
00106 ----------------------------------------- */
00107 
00108 unsigned long hash_variable_raw_info(char *name, short num_bits)
00109 {
00110     return compress(hash_string(name), num_bits);
00111 }
00112 
00113 unsigned long hash_identifier_raw_info(char name_letter, unsigned long name_number, short num_bits)
00114 {
00115     return compress(name_number | (name_letter << 24), num_bits);
00116 }
00117 
00118 unsigned long hash_sym_constant_raw_info(const char *name, short num_bits)
00119 {
00120     return compress(hash_string(name), num_bits);
00121 }
00122 
00123 unsigned long hash_int_constant_raw_info(long value, short num_bits)
00124 {
00125     return compress((unsigned long) value, num_bits);
00126 }
00127 
00128 unsigned long hash_float_constant_raw_info(float value, short num_bits)
00129 {
00130     return compress((unsigned long) value, num_bits);
00131 }
00132 
00133 /* ---------------------------------------------------
00134    Hashing symbols using their symbol table entries
00135 --------------------------------------------------- */
00136 
00137 unsigned long hash_variable(void *item, short num_bits)
00138 {
00139     variable *var;
00140     var = item;
00141     return compress(hash_string(var->name), num_bits);
00142 }
00143 
00144 unsigned long hash_identifier(void *item, short num_bits)
00145 {
00146     identifier *id;
00147     id = item;
00148     return compress(id->name_number ^ (id->name_letter << 24), num_bits);
00149 }
00150 
00151 unsigned long hash_sym_constant(void *item, short num_bits)
00152 {
00153     sym_constant *sc;
00154     sc = item;
00155     return compress(hash_string(sc->name), num_bits);
00156 }
00157 
00158 unsigned long hash_int_constant(void *item, short num_bits)
00159 {
00160     int_constant *ic;
00161     ic = item;
00162     return compress((unsigned long) (ic->value), num_bits);
00163 }
00164 
00165 unsigned long hash_float_constant(void *item, short num_bits)
00166 {
00167     float_constant *fc;
00168     fc = item;
00169     return compress((unsigned long) (fc->value), num_bits);
00170 }
00171 
00172 /* -------------------------------------------------------------------
00173 
00174         Basic Symbol Table Data Structures and Initialization
00175 
00176 ------------------------------------------------------------------- */
00177 
00178 #define get_next_symbol_hash_id() (current_agent(current_symbol_hash_id) += 137)
00179 
00180 void init_symbol_tables(void)
00181 {
00182     int i;
00183 
00184     current_agent(variable_hash_table) = make_hash_table(0, hash_variable);
00185     current_agent(identifier_hash_table) = make_hash_table(0, hash_identifier);
00186     current_agent(sym_constant_hash_table) = make_hash_table(0, hash_sym_constant);
00187     current_agent(int_constant_hash_table) = make_hash_table(0, hash_int_constant);
00188     current_agent(float_constant_hash_table) = make_hash_table(0, hash_float_constant);
00189 
00190     init_memory_pool(&current_agent(variable_pool), sizeof(variable), "variable");
00191     init_memory_pool(&current_agent(identifier_pool), sizeof(identifier), "identifier");
00192     init_memory_pool(&current_agent(sym_constant_pool), sizeof(sym_constant), "sym constant");
00193     init_memory_pool(&current_agent(int_constant_pool), sizeof(int_constant), "int constant");
00194     init_memory_pool(&current_agent(float_constant_pool), sizeof(float_constant), "float constant");
00195 
00196     for (i = 0; i < 26; i++)
00197         current_agent(id_counter)[i] = 1;
00198 }
00199 
00200 /* -------------------------------------------------------------------
00201           Symbol Table Lookup and Symbol Creation Routines
00202 
00203    The find_xxx() routines look for an existing symbol and return it
00204    if found; if no such symbol exists, they return NIL.
00205 
00206    The make_xxx() routines look for an existing symbol; if the find one,
00207    they increment the reference count and return it.  If no such symbol
00208    exists, they create a new one, set the reference count to 1, and
00209    return it.
00210 
00211    Note that rather than a make_identifier() routine, we have a
00212    make_new_identifier() routine, which takes two arguments: the first
00213    letter for the new identifier, and its initial goal_stack_level.
00214    There is no way to force creation of an identifier with a particular
00215    name letter/number combination like J37.
00216 ------------------------------------------------------------------- */
00217 
00218 Symbol *find_variable(char *name)
00219 {
00220     unsigned long hash_value;
00221     Symbol *sym;
00222 
00223     hash_value = hash_variable_raw_info(name, current_agent(variable_hash_table)->log2size);
00224     sym = (Symbol *) (*(current_agent(variable_hash_table)->buckets + hash_value));
00225     for (; sym != NIL; sym = sym->common.next_in_hash_table) {
00226         if (!strcmp(sym->var.name, name))
00227             return sym;
00228     }
00229     return NIL;
00230 }
00231 
00232 Symbol *find_identifier(char name_letter, unsigned long name_number)
00233 {
00234     unsigned long hash_value;
00235     Symbol *sym;
00236 
00237     hash_value = hash_identifier_raw_info(name_letter, name_number, current_agent(identifier_hash_table)->log2size);
00238     sym = (Symbol *) (*(current_agent(identifier_hash_table)->buckets + hash_value));
00239     for (; sym != NIL; sym = sym->common.next_in_hash_table) {
00240         if ((name_letter == sym->id.name_letter) && (name_number == sym->id.name_number))
00241             return sym;
00242     }
00243     return NIL;
00244 }
00245 
00246 Symbol *find_sym_constant(const char *name)
00247 {
00248     unsigned long hash_value;
00249     Symbol *sym;
00250 
00251     hash_value = hash_sym_constant_raw_info(name, current_agent(sym_constant_hash_table)->log2size);
00252     sym = (Symbol *) (*(current_agent(sym_constant_hash_table)->buckets + hash_value));
00253     for (; sym != NIL; sym = sym->common.next_in_hash_table) {
00254         if (!strcmp(sym->sc.name, name))
00255             return sym;
00256     }
00257     return NIL;
00258 }
00259 
00260 Symbol *find_int_constant(long value)
00261 {
00262     unsigned long hash_value;
00263     Symbol *sym;
00264 
00265     hash_value = hash_int_constant_raw_info(value, current_agent(int_constant_hash_table)->log2size);
00266     sym = (Symbol *) (*(current_agent(int_constant_hash_table)->buckets + hash_value));
00267     for (; sym != NIL; sym = sym->common.next_in_hash_table) {
00268         if (value == sym->ic.value)
00269             return sym;
00270     }
00271     return NIL;
00272 }
00273 
00274 Symbol *find_float_constant(float value)
00275 {
00276     unsigned long hash_value;
00277     Symbol *sym;
00278 
00279     hash_value = hash_float_constant_raw_info(value, current_agent(float_constant_hash_table)->log2size);
00280     sym = (Symbol *) (*(current_agent(float_constant_hash_table)->buckets + hash_value));
00281     for (; sym != NIL; sym = sym->common.next_in_hash_table) {
00282         if (value == sym->fc.value)
00283             return sym;
00284     }
00285     return NIL;
00286 }
00287 
00288 Symbol *make_variable(char *name)
00289 {
00290     Symbol *sym;
00291 
00292     sym = find_variable(name);
00293     if (sym) {
00294         sym->common.reference_count++;
00295     } else {
00296         allocate_with_pool(&current_agent(variable_pool), &sym);
00297         sym->common.symbol_type = VARIABLE_SYMBOL_TYPE;
00298         sym->common.reference_count = 1;
00299         sym->common.hash_id = get_next_symbol_hash_id();
00300         sym->var.name = make_memory_block_for_string(name);
00301         sym->var.gensym_number = 0;
00302         sym->var.tc_num = 0;
00303         sym->var.rete_binding_locations = NIL;
00304         add_to_hash_table(current_agent(variable_hash_table), sym);
00305     }
00306     return sym;
00307 }
00308 
00309 Symbol *make_new_identifier(char name_letter, goal_stack_level level)
00310 {
00311     Symbol *sym;
00312 
00313     if (isalpha(name_letter)) {
00314         if (islower(name_letter))
00315             name_letter = (char) toupper(name_letter);
00316     } else {
00317         name_letter = 'I';
00318     }
00319     allocate_with_pool(&current_agent(identifier_pool), &sym);
00320     sym->common.symbol_type = IDENTIFIER_SYMBOL_TYPE;
00321     sym->common.reference_count = 1;
00322     sym->common.hash_id = get_next_symbol_hash_id();
00323     sym->id.name_letter = name_letter;
00324     sym->id.name_number = current_agent(id_counter)[name_letter - 'A']++;
00325     sym->id.level = level;
00326     sym->id.promotion_level = level;
00327     sym->id.slots = NIL;
00328     sym->id.isa_goal = FALSE;
00329     sym->id.isa_impasse = FALSE;
00330     sym->id.isa_operator = 0;
00331     sym->id.link_count = 0;
00332     sym->id.unknown_level = NIL;
00333     sym->id.could_be_a_link_from_below = FALSE;
00334     sym->id.impasse_wmes = NIL;
00335     sym->id.higher_goal = NIL;
00336 /* REW: begin 09.15.96 */
00337     sym->id.gds = NIL;
00338 /* REW: end   09.15.96 */
00339 /* REW: begin 08.20.97 */
00340     sym->id.saved_firing_type = NO_SAVED_PRODS;
00341     sym->id.ms_o_assertions = NIL;
00342     sym->id.ms_i_assertions = NIL;
00343     sym->id.ms_retractions = NIL;
00344 /* REW: end   08.20.97 */
00345     sym->id.lower_goal = NIL;
00346     sym->id.operator_slot = NIL;
00347     sym->id.preferences_from_goal = NIL;
00348     sym->id.tc_num = 0;
00349     sym->id.associated_output_links = NIL;
00350     sym->id.input_wmes = NIL;
00351     add_to_hash_table(current_agent(identifier_hash_table), sym);
00352     return sym;
00353 }
00354 
00355 Symbol *make_sym_constant(const char *name)
00356 {
00357     Symbol *sym;
00358 
00359     sym = find_sym_constant(name);
00360     if (sym) {
00361         sym->common.reference_count++;
00362     } else {
00363         allocate_with_pool(&current_agent(sym_constant_pool), &sym);
00364         sym->common.symbol_type = SYM_CONSTANT_SYMBOL_TYPE;
00365         sym->common.reference_count = 1;
00366         sym->common.hash_id = get_next_symbol_hash_id();
00367         sym->sc.name = make_memory_block_for_string(name);
00368         sym->sc.production = NIL;
00369         add_to_hash_table(current_agent(sym_constant_hash_table), sym);
00370     }
00371     return sym;
00372 }
00373 
00374 Symbol *make_int_constant(long value)
00375 {
00376     Symbol *sym;
00377 
00378     sym = find_int_constant(value);
00379     if (sym) {
00380         sym->common.reference_count++;
00381     } else {
00382         allocate_with_pool(&current_agent(int_constant_pool), &sym);
00383         sym->common.symbol_type = INT_CONSTANT_SYMBOL_TYPE;
00384         sym->common.reference_count = 1;
00385         sym->common.hash_id = get_next_symbol_hash_id();
00386         sym->ic.value = value;
00387         add_to_hash_table(current_agent(int_constant_hash_table), sym);
00388     }
00389     return sym;
00390 }
00391 
00392 Symbol *make_float_constant(float value)
00393 {
00394     Symbol *sym;
00395 
00396     sym = find_float_constant(value);
00397     if (sym) {
00398         sym->common.reference_count++;
00399     } else {
00400         allocate_with_pool(&current_agent(float_constant_pool), &sym);
00401         sym->common.symbol_type = FLOAT_CONSTANT_SYMBOL_TYPE;
00402         sym->common.reference_count = 1;
00403         sym->common.hash_id = get_next_symbol_hash_id();
00404         sym->fc.value = value;
00405         add_to_hash_table(current_agent(float_constant_hash_table), sym);
00406     }
00407     return sym;
00408 }
00409 
00410 /* -------------------------------------------------------------------
00411 
00412                          Deallocate Symbol
00413 
00414 ------------------------------------------------------------------- */
00415 
00416 void deallocate_symbol(Symbol * sym)
00417 {
00418 
00419 #ifdef DEBUG_SYMBOLS
00420     print_with_symbols("\nDeallocating Symbol %y", sym);
00421 #endif
00422 
00423     switch (sym->common.symbol_type) {
00424     case VARIABLE_SYMBOL_TYPE:
00425         remove_from_hash_table(current_agent(variable_hash_table), sym);
00426         free_memory_block_for_string(sym->var.name);
00427         free_with_pool(&current_agent(variable_pool), sym);
00428         break;
00429     case IDENTIFIER_SYMBOL_TYPE:
00430         remove_from_hash_table(current_agent(identifier_hash_table), sym);
00431         free_with_pool(&current_agent(identifier_pool), sym);
00432         break;
00433     case SYM_CONSTANT_SYMBOL_TYPE:
00434         remove_from_hash_table(current_agent(sym_constant_hash_table), sym);
00435         free_memory_block_for_string(sym->sc.name);
00436         free_with_pool(&current_agent(sym_constant_pool), sym);
00437         break;
00438     case INT_CONSTANT_SYMBOL_TYPE:
00439         remove_from_hash_table(current_agent(int_constant_hash_table), sym);
00440         free_with_pool(&current_agent(int_constant_pool), sym);
00441         break;
00442     case FLOAT_CONSTANT_SYMBOL_TYPE:
00443         remove_from_hash_table(current_agent(float_constant_hash_table), sym);
00444         free_with_pool(&current_agent(float_constant_pool), sym);
00445         break;
00446     default:
00447         {
00448             char msg[MESSAGE_SIZE];
00449             strncpy(msg, "Internal error: called deallocate_symbol on non-symbol.\n", MESSAGE_SIZE);
00450             msg[MESSAGE_SIZE - 1] = 0;
00451             abort_with_fatal_error(msg);
00452         }
00453     }
00454 }
00455 
00456 /* -------------------------------------------------------------------
00457                        Other Symbol Utilities
00458 
00459    Reset_id_counters() is called during an init-soar to reset the id
00460    gensym numbers to 1.  It first makes sure there are no existing
00461    identifiers in the system--otherwise we might generate a second
00462    identifier with the same name later on.
00463 
00464    Reset_id_and_variable_tc_numbers() resets the tc_num field of every
00465    existing id and variable to 0.
00466 
00467    Reset_variable_gensym_numbers() resets the gensym_number field of
00468    every existing variable to 0.
00469 
00470    Print_internal_symbols() just prints a list of all existing symbols.
00471    (This is useful for debugging memory leaks.)
00472 
00473    Generate_new_sym_constant() is used to gensym new symbols that are
00474    guaranteed to not already exist.  It takes two arguments: "prefix"
00475    (the desired prefix of the new symbol's name), and "counter" (a
00476    pointer to a counter (unsigned long) that is incremented to produce
00477    new gensym names).
00478 ------------------------------------------------------------------- */
00479 
00480 void reset_id_counters(void)
00481 {
00482     int i;
00483 
00484     if (current_agent(identifier_hash_table)->count != 0) {
00485         print("Internal warning:  wanted to reset identifier generator numbers, but\n");
00486         print("there are still some identifiers allocated.  (Probably a memory leak.)\n");
00487         print("(Leaving identifier numbers alone.)\n");
00488         return;
00489     }
00490     for (i = 0; i < 26; i++)
00491         current_agent(id_counter)[i] = 1;
00492 }
00493 
00494 bool reset_tc_num(void *item)
00495 {
00496     Symbol *sym;
00497 
00498     sym = item;
00499     if (sym->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00500         sym->id.tc_num = 0;
00501     else if (sym->common.symbol_type == VARIABLE_SYMBOL_TYPE)
00502         sym->var.tc_num = 0;
00503     return FALSE;
00504 }
00505 
00506 void reset_id_and_variable_tc_numbers(void)
00507 {
00508     do_for_all_items_in_hash_table(current_agent(identifier_hash_table), reset_tc_num);
00509     do_for_all_items_in_hash_table(current_agent(variable_hash_table), reset_tc_num);
00510 }
00511 
00512 bool reset_gensym_number(void *item)
00513 {
00514     Symbol *sym;
00515 
00516     sym = item;
00517     sym->var.gensym_number = 0;
00518     return FALSE;
00519 }
00520 
00521 void reset_variable_gensym_numbers(void)
00522 {
00523     do_for_all_items_in_hash_table(current_agent(variable_hash_table), reset_gensym_number);
00524 }
00525 
00526 bool print_sym(void *item)
00527 {
00528     print_string(symbol_to_string(item, TRUE, NIL, 0));
00529     print_string("\n");
00530     return FALSE;
00531 }
00532 
00533 #define GENERATE_NEW_SYM_CONSTANT_NAME_SIZE 2048
00534 Symbol *generate_new_sym_constant(char *prefix, unsigned long *counter)
00535 {
00536     char name[GENERATE_NEW_SYM_CONSTANT_NAME_SIZE];     /* that ought to be long enough! */
00537     Symbol *new;
00538 
00539     for (;;) {
00540         snprintf(name, GENERATE_NEW_SYM_CONSTANT_NAME_SIZE, "%s%lu", prefix, (*counter)++);
00541         name[GENERATE_NEW_SYM_CONSTANT_NAME_SIZE - 1] = 0;      /* snprintf doesn't set last char to null if output is truncated */
00542         if (!find_sym_constant(name))
00543             break;
00544     }
00545     new = make_sym_constant(name);
00546     return new;
00547 }
00548 
00549 /* --------------------------------------------------------------------
00550    
00551                          Predefined Symbols
00552 
00553 -------------------------------------------------------------------- */
00554 
00555 void create_predefined_symbols(void)
00556 {
00557     current_agent(problem_space_symbol) = make_sym_constant("problem-space");
00558     current_agent(state_symbol) = make_sym_constant("state");
00559     current_agent(operator_symbol) = make_sym_constant("operator");
00560     current_agent(superstate_symbol) = make_sym_constant("superstate");
00561     current_agent(io_symbol) = make_sym_constant("io");
00562     current_agent(object_symbol) = make_sym_constant("object");
00563     current_agent(attribute_symbol) = make_sym_constant("attribute");
00564     current_agent(impasse_symbol) = make_sym_constant("impasse");
00565     current_agent(choices_symbol) = make_sym_constant("choices");
00566     current_agent(none_symbol) = make_sym_constant("none");
00567     current_agent(constraint_failure_symbol) = make_sym_constant("constraint-failure");
00568     current_agent(no_change_symbol) = make_sym_constant("no-change");
00569     current_agent(multiple_symbol) = make_sym_constant("multiple");
00570     current_agent(conflict_symbol) = make_sym_constant("conflict");
00571     current_agent(tie_symbol) = make_sym_constant("tie");
00572     current_agent(item_symbol) = make_sym_constant("item");
00573     current_agent(quiescence_symbol) = make_sym_constant("quiescence");
00574     current_agent(t_symbol) = make_sym_constant("t");
00575     current_agent(nil_symbol) = make_sym_constant("nil");
00576     current_agent(type_symbol) = make_sym_constant("type");
00577     current_agent(goal_symbol) = make_sym_constant("goal");
00578     current_agent(name_symbol) = make_sym_constant("name");
00579 
00580     current_agent(ts_context_variable) = make_variable("<ts>");
00581     current_agent(to_context_variable) = make_variable("<to>");
00582     current_agent(sss_context_variable) = make_variable("<sss>");
00583     current_agent(sso_context_variable) = make_variable("<sso>");
00584     current_agent(ss_context_variable) = make_variable("<ss>");
00585     current_agent(so_context_variable) = make_variable("<so>");
00586     current_agent(s_context_variable) = make_variable("<s>");
00587     current_agent(o_context_variable) = make_variable("<o>");
00588 
00589     /* REW: begin 10.24.97 */
00590     current_agent(wait_symbol) = make_variable("wait");
00591     /* REW: end   10.24.97 */
00592 }

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