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

soar_core_utils.c

Go to the documentation of this file.
00001 #include "soarkernel.h"
00002 #include "soar_core_utils.h"
00003 #include "rhsfun.h"
00004 #include "rhsfun_examples.h"
00005 
00006 extern int soar_agent_ids[];
00007 extern int agent_counter;
00008 extern int next_available_agent_id();
00009 extern void init_soar_agent();
00010 
00011 /*
00012  *----------------------------------------------------------------------
00013  *
00014  * read_id_or_context_var_from_string --
00015  *
00016  *      This procedure parses a string to determine if it is a
00017  *      lexeme for an identifier or context variable.
00018  * 
00019  *      Many interface routines take identifiers as arguments.  
00020  *      These ids can be given as normal ids, or as special variables 
00021  *      such as <s> for the current state, etc.  This routine reads 
00022  *      (without consuming it) an identifier or context variable, 
00023  *      and returns a pointer (Symbol *) to the id.  (In the case of 
00024  *      context variables, the instantiated variable is returned.  If 
00025  *      any error occurs (e.g., no such id, no instantiation of the 
00026  *      variable), an error message is printed and NIL is returned.
00027  *
00028  * Results:
00029  *      Pointer to a symbol for the variable or NIL.
00030  *
00031  * Side effects:
00032  *      None.
00033  *
00034  *----------------------------------------------------------------------
00035  */
00036 
00037 int read_id_or_context_var_from_string(const char *the_lexeme, Symbol * *result_id)
00038 {
00039     Symbol *id;
00040     Symbol *g, *attr, *value;
00041 
00042     get_lexeme_from_string(the_lexeme);
00043 
00044     if (current_agent(lexeme).type == IDENTIFIER_LEXEME) {
00045         id = find_identifier(current_agent(lexeme).id_letter, current_agent(lexeme).id_number);
00046         if (!id) {
00047             return SOAR_ERROR;
00048         } else {
00049             *result_id = id;
00050             return SOAR_OK;
00051         }
00052     }
00053 
00054     if (current_agent(lexeme).type == VARIABLE_LEXEME) {
00055         get_context_var_info(&g, &attr, &value);
00056 
00057         if ((!attr) || (!value)) {
00058             return SOAR_ERROR;
00059         }
00060 
00061         if (value->common.symbol_type != IDENTIFIER_SYMBOL_TYPE) {
00062             return SOAR_ERROR;
00063         }
00064 
00065         *result_id = value;
00066         return SOAR_OK;
00067     }
00068 
00069     return SOAR_ERROR;
00070 }
00071 
00072 /*
00073  *  This function should be replaced by the one above and added to the
00074  *  Soar kernel. 
00075  */
00076 
00077 Symbol *read_identifier_or_context_variable(void)
00078 {
00079     Symbol *id;
00080     Symbol *g, *attr, *value;
00081 
00082     if (current_agent(lexeme).type == IDENTIFIER_LEXEME) {
00083         id = find_identifier(current_agent(lexeme).id_letter, current_agent(lexeme).id_number);
00084         if (!id) {
00085             print("There is no identifier %c%lu.\n", current_agent(lexeme).id_letter, current_agent(lexeme).id_number);
00086             print_location_of_most_recent_lexeme();
00087             return NIL;
00088         }
00089         return id;
00090     }
00091     if (current_agent(lexeme).type == VARIABLE_LEXEME) {
00092         get_context_var_info(&g, &attr, &value);
00093         if (!attr) {
00094             print("Expected identifier (or context variable)\n");
00095             print_location_of_most_recent_lexeme();
00096             return NIL;
00097         }
00098         if (!value) {
00099             print("There is no current %s.\n", current_agent(lexeme).string);
00100             print_location_of_most_recent_lexeme();
00101             return NIL;
00102         }
00103         if (value->common.symbol_type != IDENTIFIER_SYMBOL_TYPE) {
00104             print("The current %s ", current_agent(lexeme).string);
00105             print_with_symbols("(%y) is not an identifier.\n", value);
00106             print_location_of_most_recent_lexeme();
00107             return NIL;
00108         }
00109         return value;
00110     }
00111     print("Expected identifier (or context variable)\n");
00112     print_location_of_most_recent_lexeme();
00113     return NIL;
00114 }
00115 
00116 /*
00117  *----------------------------------------------------------------------
00118  *
00119  * name_to_production --
00120  *
00121  *      This procedure determines if a string matches an existing
00122  *      production name.  If so, the production is returned.
00123  *
00124  * Results:
00125  *      Returns the production if a match is found, NIL otherwise.
00126  *
00127  * Side effects:
00128  *      None.
00129  *
00130  *----------------------------------------------------------------------
00131  */
00132 
00133 production *name_to_production(const char *string_to_test)
00134 {
00135     Symbol *sym;
00136 
00137     sym = find_sym_constant(string_to_test);
00138 
00139     if (sym && sym->sc.production)
00140         return sym->sc.production;
00141     else
00142         return NIL;
00143 }
00144 
00145 void do_print_for_identifier(Symbol * id, int depth, bool internal)
00146 {
00147     tc_number tc;
00148 
00149     tc = get_new_tc_number();
00150     print_augs_of_id(id, depth, internal, 0, tc);
00151 }
00152 
00153 /*
00154  *----------------------------------------------------------------------
00155  *
00156  * get_lexeme_from_string --
00157  *
00158  *      A hack to get the Soar lexer to take a string
00159  *      as a lexeme and setup the agent lexeme structure.  It
00160  *      is assumed that the lexeme is composed of Soar
00161  *      "constituent" characters -- i.e., does not contain any
00162  *      Soar special characters.  
00163  *
00164  *      See lexer.c for more information.
00165  *
00166  * Results:
00167  *      None.
00168  *
00169  * Side effects:
00170  *      String copied to lexeme structure,  string length
00171  *      computed, and lexeme type determined.
00172  *      Overwrites previous lexeme contents. 
00173  *
00174  *----------------------------------------------------------------------
00175  */
00176 
00177 void get_lexeme_from_string(const char *the_lexeme)
00178 {
00179     int i;
00180     const char *c;
00181     bool sym_constant_start_found = FALSE;
00182     bool sym_constant_end_found = FALSE;
00183 
00184     for (c = the_lexeme, i = 0; *c; c++, i++) {
00185         if (*c == '|') {
00186             if (!sym_constant_start_found) {
00187                 i--;
00188                 sym_constant_start_found = TRUE;
00189             } else {
00190                 i--;
00191                 sym_constant_end_found = TRUE;
00192             }
00193         } else {
00194             current_agent(lexeme).string[i] = *c;
00195         }
00196     }
00197 
00198     current_agent(lexeme).string[i] = '\0';     /* Null terminate lexeme string */
00199 
00200     current_agent(lexeme).length = i;
00201 
00202     if (sym_constant_end_found) {
00203         current_agent(lexeme).type = SYM_CONSTANT_LEXEME;
00204     } else {
00205         determine_type_of_constituent_string();
00206     }
00207 }
00208 
00209 void get_context_var_info(Symbol ** dest_goal, Symbol ** dest_attr_of_slot, Symbol ** dest_current_value)
00210 {
00211 
00212     get_context_var_info_from_string(current_agent(lexeme).string, dest_goal, dest_attr_of_slot, dest_current_value);
00213 }
00214 
00215 void get_context_var_info_from_string(char *str,
00216                                       Symbol ** dest_goal, Symbol ** dest_attr_of_slot, Symbol ** dest_current_value)
00217 {
00218 
00219     Symbol *v, *g;
00220     int levels_up;
00221     wme *w;
00222 
00223     v = find_variable(str);
00224     if (v == current_agent(s_context_variable)) {
00225         levels_up = 0;
00226         *dest_attr_of_slot = current_agent(state_symbol);
00227     } else if (v == current_agent(o_context_variable)) {
00228         levels_up = 0;
00229         *dest_attr_of_slot = current_agent(operator_symbol);
00230     } else if (v == current_agent(ss_context_variable)) {
00231         levels_up = 1;
00232         *dest_attr_of_slot = current_agent(state_symbol);
00233     } else if (v == current_agent(so_context_variable)) {
00234         levels_up = 1;
00235         *dest_attr_of_slot = current_agent(operator_symbol);
00236     } else if (v == current_agent(sss_context_variable)) {
00237         levels_up = 2;
00238         *dest_attr_of_slot = current_agent(state_symbol);
00239     } else if (v == current_agent(sso_context_variable)) {
00240         levels_up = 2;
00241         *dest_attr_of_slot = current_agent(operator_symbol);
00242     } else if (v == current_agent(ts_context_variable)) {
00243         levels_up =
00244             current_agent(top_goal) ? current_agent(bottom_goal)->id.level - current_agent(top_goal)->id.level : 0;
00245         *dest_attr_of_slot = current_agent(state_symbol);
00246     } else if (v == current_agent(to_context_variable)) {
00247         levels_up =
00248             current_agent(top_goal) ? current_agent(bottom_goal)->id.level - current_agent(top_goal)->id.level : 0;
00249         *dest_attr_of_slot = current_agent(operator_symbol);
00250     } else {
00251         *dest_goal = NIL;
00252         *dest_attr_of_slot = NIL;
00253         *dest_current_value = NIL;
00254         return;
00255     }
00256 
00257     g = current_agent(bottom_goal);
00258     while (g && levels_up) {
00259         g = g->id.higher_goal;
00260         levels_up--;
00261     }
00262     *dest_goal = g;
00263 
00264     if (!g) {
00265         *dest_current_value = NIL;
00266         return;
00267     }
00268 
00269     if (*dest_attr_of_slot == current_agent(state_symbol)) {
00270         *dest_current_value = g;
00271     } else {
00272         w = g->id.operator_slot->wmes;
00273         *dest_current_value = w ? w->value : NIL;
00274     }
00275 }
00276 
00277 wme **get_augs_of_id(Symbol * id, tc_number tc, int *num_attr)
00278 {
00279     slot *s;
00280     wme *w;
00281 
00282     wme **list;                 /* array of WME pointers, AGR 652 */
00283     int attr;                   /* attribute index, AGR 652 */
00284     int n;
00285 
00286 /* AGR 652  The plan is to go through the list of WMEs and find out how
00287    many there are.  Then we malloc an array of that many pointers.
00288    Then we go through the list again and copy all the pointers to that array.
00289    Then we qsort the array and print it out.  94.12.13 */
00290 
00291     if (id->common.symbol_type != IDENTIFIER_SYMBOL_TYPE)
00292         return NULL;
00293     if (id->id.tc_num == tc)
00294         return NULL;
00295     id->id.tc_num = tc;
00296 
00297     /* --- first, count all direct augmentations of this id --- */
00298     n = 0;
00299     for (w = id->id.impasse_wmes; w != NIL; w = w->next)
00300         n++;
00301     for (w = id->id.input_wmes; w != NIL; w = w->next)
00302         n++;
00303     for (s = id->id.slots; s != NIL; s = s->next) {
00304         for (w = s->wmes; w != NIL; w = w->next)
00305             n++;
00306         for (w = s->acceptable_preference_wmes; w != NIL; w = w->next)
00307             n++;
00308     }
00309 
00310     /* --- next, construct the array of wme pointers and sort them --- */
00311     list = allocate_memory(n * sizeof(wme *), MISCELLANEOUS_MEM_USAGE);
00312     attr = 0;
00313     for (w = id->id.impasse_wmes; w != NIL; w = w->next)
00314         list[attr++] = w;
00315     for (w = id->id.input_wmes; w != NIL; w = w->next)
00316         list[attr++] = w;
00317     for (s = id->id.slots; s != NIL; s = s->next) {
00318         for (w = s->wmes; w != NIL; w = w->next)
00319             list[attr++] = w;
00320         for (w = s->acceptable_preference_wmes; w != NIL; w = w->next)
00321             list[attr++] = w;
00322     }
00323     qsort(list, n, sizeof(wme *), compare_attr);
00324 
00325     *num_attr = n;
00326     return list;
00327 
00328 }
00329 
00330 void print_augs_of_id(Symbol * id, int depth, bool internal, int indent, tc_number tc)
00331 {
00332     slot *s;
00333     wme *w;
00334 
00335     wme **list;                 /* array of WME pointers, AGR 652 */
00336     int num_attr;               /* number of attributes, AGR 652 */
00337     int attr;                   /* attribute index, AGR 652 */
00338 
00339     list = get_augs_of_id(id, tc, &num_attr);
00340     if (!list)
00341         return;
00342 
00343     /* --- finally, print the sorted wmes and deallocate the array --- */
00344     if (internal) {
00345         for (attr = 0; attr < num_attr; attr++) {
00346             w = list[attr];
00347             print_spaces(indent);
00348             print_wme(w);
00349         }
00350     } else {
00351         print_spaces(indent);
00352         print_with_symbols("(%y", id);
00353         for (attr = 0; attr < num_attr; attr++) {
00354             w = list[attr];
00355             neatly_print_wme_augmentation_of_id(w, indent);
00356         }
00357         print(")\n");
00358     }
00359     free_memory(list, MISCELLANEOUS_MEM_USAGE);
00360 /* AGR 652 end */
00361 
00362     /* --- if depth<=1, we're done --- */
00363     if (depth <= 1)
00364         return;
00365 
00366     /* --- call this routine recursively --- */
00367     for (w = id->id.input_wmes; w != NIL; w = w->next) {
00368         print_augs_of_id(w->attr, depth - 1, internal, indent + 2, tc);
00369         print_augs_of_id(w->value, depth - 1, internal, indent + 2, tc);
00370     }
00371     for (w = id->id.impasse_wmes; w != NIL; w = w->next) {
00372         print_augs_of_id(w->attr, depth - 1, internal, indent + 2, tc);
00373         print_augs_of_id(w->value, depth - 1, internal, indent + 2, tc);
00374     }
00375     for (s = id->id.slots; s != NIL; s = s->next) {
00376         for (w = s->wmes; w != NIL; w = w->next) {
00377             print_augs_of_id(w->attr, depth - 1, internal, indent + 2, tc);
00378             print_augs_of_id(w->value, depth - 1, internal, indent + 2, tc);
00379         }
00380         for (w = s->acceptable_preference_wmes; w != NIL; w = w->next) {
00381             print_augs_of_id(w->attr, depth - 1, internal, indent + 2, tc);
00382             print_augs_of_id(w->value, depth - 1, internal, indent + 2, tc);
00383         }
00384     }
00385 }
00386 
00387 /* AGR 652 begin */
00388 /* Comment from Bob:  
00389    Also, if speed becomes an issue, you might put in a special case check
00390    for the common case where both p1 and p2 are SYM_CONSTANT's, in which
00391    case you could avoid the symbol_to_string() calls entirely and just
00392    call strcmp() directly on the attribute names.  (Maybe just leave this
00393    as a comment for now, just in case somebody complains about print speed
00394    some day.)  */
00395 
00396 /* The header for compare_attr needs to be defined in this way because
00397    otherwise we get compiler warnings at the qsort lines about the 4th
00398    argument being an incompatible pointer type.  */
00399 
00400 #define S1_SIZE MAX_LEXEME_LENGTH*2+20
00401 #define S2_SIZE MAX_LEXEME_LENGTH*2+20
00402 int compare_attr(const void *e1, const void *e2)
00403 {
00404     wme **p1, **p2;
00405 
00406     char s1[S1_SIZE], s2[S2_SIZE];
00407 
00408     p1 = (wme **) e1;
00409     p2 = (wme **) e2;
00410 
00411     symbol_to_string((*p1)->attr, TRUE, s1, S1_SIZE);
00412     symbol_to_string((*p2)->attr, TRUE, s2, S2_SIZE);
00413 
00414     return (strcmp(s1, s2));
00415 }
00416 
00417 /* This should probably be in the Soar kernel interface. */
00418 #define NEATLY_PRINT_BUF_SIZE 10000
00419 void neatly_print_wme_augmentation_of_id(wme * w, int indentation)
00420 {
00421     char buf[NEATLY_PRINT_BUF_SIZE], *ch;
00422 
00423     strncpy(buf, " ^", NEATLY_PRINT_BUF_SIZE);
00424     buf[NEATLY_PRINT_BUF_SIZE - 1] = 0;
00425     ch = buf;
00426     while (*ch)
00427         ch++;
00428     symbol_to_string(w->attr, TRUE, ch, NEATLY_PRINT_BUF_SIZE - (ch - buf));
00429     while (*ch)
00430         ch++;
00431     *(ch++) = ' ';
00432     symbol_to_string(w->value, TRUE, ch, NEATLY_PRINT_BUF_SIZE - (ch - buf));
00433     while (*ch)
00434         ch++;
00435 
00436     if (w->acceptable) {
00437         strncpy(ch, " +", NEATLY_PRINT_BUF_SIZE - (ch - buf));
00438         ch[NEATLY_PRINT_BUF_SIZE - (ch - buf) - 1] = 0;
00439         while (*ch)
00440             ch++;
00441     }
00442 
00443     if (get_printer_output_column() + (ch - buf) >= 80) {
00444         print("\n");
00445         print_spaces(indentation + 6);
00446     }
00447     print_string(buf);
00448 }
00449 
00450 /*
00451  *----------------------------------------------------------------------
00452  *
00453  * string_match --
00454  *
00455  *      This procedure compares two strings to see if there 
00456  *      are equal.
00457  *
00458  * Results:
00459  *      TRUE if the strings match, FALSE otherwise.
00460  *
00461  * Side effects:
00462  *      None.
00463  *
00464  *----------------------------------------------------------------------
00465  */
00466 
00467 bool string_match(const char *string1, const char *string2)
00468 {
00469     if ((string1 == NULL) && (string2 == NULL))
00470         return TRUE;
00471 
00472     if ((string1 != NULL)
00473         && (string2 != NULL)
00474         && !(strcmp(string1, string2)))
00475         return TRUE;
00476     else
00477         return FALSE;
00478 }
00479 
00480 /*
00481  *----------------------------------------------------------------------
00482  *
00483  * string_match_up_to --
00484  *
00485  *      This procedure compares two strings to see if there 
00486  *      are equal up to the indicated number of positions.
00487  *
00488  * Results:
00489  *      TRUE if the strings match over the given number of
00490  *      characters, FALSE otherwise.
00491  *
00492  * Side effects:
00493  *      None.
00494  *
00495  *----------------------------------------------------------------------
00496  */
00497 
00498 bool string_match_up_to(const char *string1, const char *string2, int positions)
00499 {
00500     unsigned int i, num;
00501 
00502     /*  what we really want is to require a match over the length of
00503        the shorter of the two strings, with positions being a minimum */
00504 
00505     num = strlen(string1);
00506     if (num > strlen(string2))
00507         num = strlen(string2);
00508     if ((unsigned int) positions < num)
00509         positions = num;
00510 
00511     for (i = 0; i < (unsigned int) positions; i++) {
00512         if (string1[i] != string2[i])
00513             return FALSE;
00514     }
00515 
00516     return TRUE;
00517 }
00518 
00519 void soar_default_create_agent_procedure(const char *agent_name)
00520 {
00521     int i;                      /* loop index */
00522     char cur_path[MAXPATHLEN];  /* AGR 536 */
00523 
00524     agent *curr_agent;
00525     agent *this_agent;
00526 
00527     this_agent = (agent *) malloc(sizeof(agent));
00528     memset(this_agent, 0, sizeof(*this_agent));
00529 
00530     curr_agent = soar_agent;
00531     soar_agent = this_agent;
00532 
00533     agent_counter++;
00534     agent_count++;
00535 
00536     current_agent(id) = next_available_agent_id();
00537     current_agent(name) = savestring(agent_name);
00538 
00539     /* mvp 5-17-94 */
00540     current_agent(variables_set) = NIL;
00541 
00542     /* String redirection */
00543     /*
00544        current_agent(using_output_string)             = FALSE;
00545        current_agent(output_string)                           = NIL;
00546      */
00547 
00548     /* Who needs it if there's an alternate_input_string? */
00549     /*
00550        current_agent(input_string)                            = NIL;
00551        current_agent(using_input_string)              = FALSE;
00552      */
00553 
00554     current_agent(alias_list) = NIL;    /* AGR 568 */
00555     current_agent(all_wmes_in_rete) = NIL;
00556     current_agent(alpha_mem_id_counter) = 0;
00557     current_agent(alternate_input_string) = NIL;
00558     current_agent(alternate_input_suffix) = NIL;
00559     current_agent(alternate_input_exit) = FALSE;        /* Soar-Bugs #54 */
00560     current_agent(backtrace_number) = 0;
00561     current_agent(beta_node_id_counter) = 0;
00562     current_agent(bottom_goal) = NIL;
00563     current_agent(changed_slots) = NIL;
00564     current_agent(chunk_count) = 1;
00565     current_agent(chunk_free_problem_spaces) = NIL;
00566     current_agent(chunky_problem_spaces) = NIL; /* AGR MVL1 */
00567     strncpy(current_agent(chunk_name_prefix), "chunk", kChunkNamePrefixMaxLength);      /* kjh (B14) */
00568     current_agent(chunk_name_prefix)[kChunkNamePrefixMaxLength - 1] = 0;
00569     current_agent(context_slots_with_changed_acceptable_preferences) = NIL;
00570     current_agent(current_file) = NIL;
00571     current_agent(current_phase) = INPUT_PHASE;
00572     current_agent(current_symbol_hash_id) = 0;
00573     current_agent(current_variable_gensym_number) = 0;
00574     current_agent(current_wme_timetag) = 1;
00575     current_agent(default_wme_depth) = 1;       /* AGR 646 */
00576     current_agent(disconnected_ids) = NIL;
00577     current_agent(existing_output_links) = NIL;
00578     current_agent(output_link_changed) = FALSE; /* KJC 11/9/98 */
00579     /* current_agent(explain_flag)                       = FALSE; */
00580     current_agent(go_number) = 1;
00581     current_agent(go_type) = GO_DECISION;
00582     current_agent(grounds_tc) = 0;
00583     current_agent(highest_goal_whose_context_changed) = NIL;
00584     current_agent(ids_with_unknown_level) = NIL;
00585     current_agent(input_period) = 0;    /* AGR REW1 */
00586     current_agent(input_cycle_flag) = TRUE;     /* AGR REW1 */
00587     current_agent(justification_count) = 1;
00588     current_agent(lex_alias) = NIL;     /* AGR 568 */
00589     current_agent(link_update_mode) = UPDATE_LINKS_NORMALLY;
00590     current_agent(locals_tc) = 0;
00591     current_agent(logging_to_file) = FALSE;
00592     current_agent(max_chunks_reached) = FALSE;  /* MVP 6-24-94 */
00593     current_agent(mcs_counter) = 1;
00594     current_agent(memory_pools_in_use) = NIL;
00595     current_agent(ms_assertions) = NIL;
00596     current_agent(ms_retractions) = NIL;
00597     current_agent(multi_attributes) = NIL;
00598     current_agent(num_existing_wmes) = 0;
00599     current_agent(num_wmes_in_rete) = 0;
00600     current_agent(potentials_tc) = 0;
00601     current_agent(prev_top_state) = NIL;
00602     current_agent(print_prompt_flag) = TRUE;
00603     current_agent(printer_output_column) = 1;
00604     current_agent(production_being_fired) = NIL;
00605     current_agent(productions_being_traced) = NIL;
00606     current_agent(promoted_ids) = NIL;
00607     current_agent(reason_for_stopping) = "Startup";
00608     current_agent(redirecting_to_file) = FALSE;
00609     current_agent(slots_for_possible_removal) = NIL;
00610     current_agent(stop_soar) = TRUE;
00611     current_agent(system_halted) = FALSE;
00612     current_agent(token_additions) = 0;
00613     current_agent(top_dir_stack) = NIL; /* AGR 568 */
00614     current_agent(top_goal) = NIL;
00615     current_agent(top_state) = NIL;
00616     current_agent(wmes_to_add) = NIL;
00617     current_agent(wmes_to_remove) = NIL;
00618     current_agent(wme_filter_list) = NIL;
00619 
00620     /* REW: begin 09.15.96 */
00621 
00622     current_agent(did_PE) = FALSE;
00623 
00624 #ifndef SOAR_8_ONLY
00625     current_agent(operand2_mode) = TRUE;
00626 #endif
00627 
00628     current_agent(soar_verbose_flag) = FALSE;
00629     current_agent(FIRING_TYPE) = IE_PRODS;
00630     current_agent(ms_o_assertions) = NIL;
00631     current_agent(ms_i_assertions) = NIL;
00632 
00633     /* REW: end   09.15.96 */
00634 
00635     /* REW: begin 08.20.97 */
00636     current_agent(active_goal) = NIL;
00637     current_agent(active_level) = 0;
00638     current_agent(previous_active_level) = 0;
00639 
00640     /* Initialize Waterfall-specific lists */
00641     current_agent(nil_goal_retractions) = NIL;
00642     /* REW: end   08.20.97 */
00643 
00644     /* KJC: delineate between Pref/WM(propose) and Pref/WM (apply) 10.05.98 */
00645     current_agent(applyPhase) = FALSE;
00646 
00647     /* REW: begin 10.24.97 */
00648     current_agent(waitsnc) = FALSE;
00649     current_agent(waitsnc_detect) = FALSE;
00650     /* REW: end   10.24.97 */
00651 
00652     if (!sys_getwd(cur_path, MAXPATHLEN))
00653         print("Unable to set current directory while initializing agent.\n");
00654 
00655     current_agent(top_dir_stack) = (dir_stack_struct *) malloc(sizeof(dir_stack_struct));       /* AGR 568 */
00656 
00657     current_agent(top_dir_stack)->directory = (char *) malloc(MAXPATHLEN * sizeof(char));       /* AGR 568 */
00658 
00659     current_agent(top_dir_stack)->next = NIL;   /* AGR 568 */
00660 
00661     strncpy(current_agent(top_dir_stack)->directory, cur_path, MAXPATHLEN);     /* AGR 568 */
00662     current_agent(top_dir_stack)->directory[MAXPATHLEN - 1] = 0;
00663 
00664     for (i = 0; i < NUM_PRODUCTION_TYPES; i++) {
00665         current_agent(all_productions_of_type)[i] = NIL;
00666         current_agent(num_productions_of_type)[i] = 0;
00667     }
00668 
00669     current_agent(o_support_calculation_type) = 3;      /* KJC 7/00 */
00670     current_agent(numeric_indifferent_mode) = NUMERIC_INDIFFERENT_MODE_AVG;     /* KJC 7/00 */
00671     current_agent(attribute_preferences_mode) = 0;      /* RBD 4/17/95 */
00672 
00673 #ifdef USE_AGENT_DBG_FILE
00674     current_agent(dbgFile) = fopen("soarDbg", "w");
00675 #endif
00676 #ifdef WARN_IF_TIMERS_REPORT_ZERO
00677     current_agent(warn_on_zero_timers) = TRUE;
00678 #endif
00679 #ifdef USE_CAPTURE_REPLAY
00680     current_agent(capture_fileID) = NIL;
00681     current_agent(replay_fileID) = NIL;
00682     current_agent(timetag_mismatch) = FALSE;
00683 #endif
00684 #ifdef DC_HISTOGRAM
00685     current_agent(dc_histogram_sz) = 0;
00686 
00687     /* Set the offset high when this funct is not in use to speed up
00688      * d.c. increment
00689      */
00690     current_agent(dc_histogram_offset) = 1000000;
00691     current_agent(dc_histogram_freq) = 10;
00692 #endif                          /* DC_HISTOGRAM */
00693 
00694 #ifdef KT_HISTOGRAM
00695     current_agent(kt_histogram_sz) = 450;
00696     current_agent(kt_histogram_tv) = (struct timeval *)
00697         malloc(current_agent(kt_histogram_sz) * sizeof(struct timeval));
00698 #endif                          /* KT_HISTOGRAM */
00699 
00700     /* Also sets callback_error to 0 */
00701     soar_init_callbacks((soar_callback_agent) soar_agent);
00702 
00703     init_soar_agent();
00704     /* Add agent to global list   */
00705     /* of all agents.             */
00706     push(soar_agent, all_soar_agents);
00707 
00708     soar_invoke_global_callbacks(soar_agent, GLB_AGENT_CREATED, (soar_call_data) soar_agent);
00709 
00710     /* 
00711      * If this is not the first agent created, reset the current agent
00712      * pointer
00713      */
00714     if (curr_agent != NULL) {
00715         soar_agent = curr_agent;
00716     }
00717 
00718 }
00719 
00720 void soar_default_destroy_agent_procedure(psoar_agent delete_agent)
00721 {
00722     cons *c;
00723     cons *prev = NULL;          /* Initialized to placate gcc -Wall */
00724     agent *the_agent;
00725     bool already_deleted;
00726 
00727     already_deleted = TRUE;
00728     /* Splice agent structure out of global list of agents. */
00729     for (c = all_soar_agents; c != NIL; c = c->rest) {
00730         the_agent = (agent *) c->first;
00731         if (the_agent == delete_agent) {
00732             if (c == all_soar_agents) {
00733                 all_soar_agents = c->rest;
00734             } else {
00735                 prev->rest = c->rest;
00736             }
00737             already_deleted = FALSE;
00738             break;
00739         }
00740         prev = c;
00741     }
00742 
00743     /* save current-agent in temp variable */
00744     if (delete_agent == soar_agent)
00745         the_agent = (struct agent_struct *) c->rest;
00746     else
00747         the_agent = soar_agent;
00748 
00749     /* change the current agent to the one to delete */
00750     soar_agent = delete_agent;
00751     remove_built_in_rhs_functions();
00752     remove_bot_rhs_functions();
00753 
00754     if (already_deleted) {
00755         char msg[MESSAGE_SIZE];
00756         snprintf(msg, MESSAGE_SIZE, "Tried to delete invalid agent (%p).\n", soar_agent);
00757         msg[MESSAGE_SIZE - 1] = 0;      /* snprintf doesn't set last char to null if output is truncated */
00758         abort_with_fatal_error(msg);
00759     }
00760 
00761     /* Free agent id */
00762     soar_agent_ids[((agent *) soar_agent)->id] = TOUCHED;
00763 
00764     /* Free structures stored in agent structure */
00765     free(((agent *) soar_agent)->name);
00766 
00767     /* KNOWN MEMORY LEAK! Need to track down and free ALL structures */
00768     /* pointed to be fields in the agent structure.                  */
00769 
00770     /* Free soar agent structure */
00771     free((void *) soar_agent);
00772 
00773     soar_agent = the_agent;
00774     agent_count--;
00775 
00776 }

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