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
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00074
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
00120
00121
00122
00123
00124
00125
00126
00127
00128
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
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
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';
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;
00283 int attr;
00284 int n;
00285
00286
00287
00288
00289
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
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
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;
00336 int num_attr;
00337 int attr;
00338
00339 list = get_augs_of_id(id, tc, &num_attr);
00340 if (!list)
00341 return;
00342
00343
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
00361
00362
00363 if (depth <= 1)
00364 return;
00365
00366
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
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
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
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
00454
00455
00456
00457
00458
00459
00460
00461
00462
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
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
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
00503
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;
00522 char cur_path[MAXPATHLEN];
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
00540 current_agent(variables_set) = NIL;
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 current_agent(alias_list) = NIL;
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;
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;
00567 strncpy(current_agent(chunk_name_prefix), "chunk", kChunkNamePrefixMaxLength);
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;
00576 current_agent(disconnected_ids) = NIL;
00577 current_agent(existing_output_links) = NIL;
00578 current_agent(output_link_changed) = FALSE;
00579
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;
00586 current_agent(input_cycle_flag) = TRUE;
00587 current_agent(justification_count) = 1;
00588 current_agent(lex_alias) = NIL;
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;
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;
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
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
00634
00635
00636 current_agent(active_goal) = NIL;
00637 current_agent(active_level) = 0;
00638 current_agent(previous_active_level) = 0;
00639
00640
00641 current_agent(nil_goal_retractions) = NIL;
00642
00643
00644
00645 current_agent(applyPhase) = FALSE;
00646
00647
00648 current_agent(waitsnc) = FALSE;
00649 current_agent(waitsnc_detect) = FALSE;
00650
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));
00656
00657 current_agent(top_dir_stack)->directory = (char *) malloc(MAXPATHLEN * sizeof(char));
00658
00659 current_agent(top_dir_stack)->next = NIL;
00660
00661 strncpy(current_agent(top_dir_stack)->directory, cur_path, MAXPATHLEN);
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;
00670 current_agent(numeric_indifferent_mode) = NUMERIC_INDIFFERENT_MODE_AVG;
00671 current_agent(attribute_preferences_mode) = 0;
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
00688
00689
00690 current_agent(dc_histogram_offset) = 1000000;
00691 current_agent(dc_histogram_freq) = 10;
00692 #endif
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
00699
00700
00701 soar_init_callbacks((soar_callback_agent) soar_agent);
00702
00703 init_soar_agent();
00704
00705
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
00712
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;
00724 agent *the_agent;
00725 bool already_deleted;
00726
00727 already_deleted = TRUE;
00728
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
00744 if (delete_agent == soar_agent)
00745 the_agent = (struct agent_struct *) c->rest;
00746 else
00747 the_agent = soar_agent;
00748
00749
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;
00758 abort_with_fatal_error(msg);
00759 }
00760
00761
00762 soar_agent_ids[((agent *) soar_agent)->id] = TOUCHED;
00763
00764
00765 free(((agent *) soar_agent)->name);
00766
00767
00768
00769
00770
00771 free((void *) soar_agent);
00772
00773 soar_agent = the_agent;
00774 agent_count--;
00775
00776 }