00001
00043 #include "soarkernel.h"
00044 #include <time.h>
00045 #include <stdlib.h>
00046
00047 #include "soar_core_api.h"
00048 #include "soar_core_utils.h"
00049 #include "scheduler.h"
00050
00051 extern char *soar_callback_names[];
00052 void soar_cTestCallback(soar_callback_agent the_agent, soar_callback_data data, soar_call_data call_data);
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 void set_sysparam(int param_number, long new_value)
00067 {
00068
00069 if ((param_number < 0) || (param_number > HIGHEST_SYSPARAM_NUMBER)) {
00070 print("Internal error: tried to set bad sysparam #: %d\n", param_number);
00071 return;
00072 }
00073 current_agent(sysparams)[param_number] = new_value;
00074
00075 soar_invoke_callbacks(soar_agent, SYSTEM_PARAMETER_CHANGED_CALLBACK, (soar_call_data) param_number);
00076
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 extern int soar_agent_ids[];
00094 extern int agent_counter;
00095 extern soar_global_callback_array soar_global_callbacks;
00096
00097 extern void gds_invalid_so_remove_goal(wme * w);
00098
00099 #if defined(WIN32)
00100 #include <stdio.h>
00101 #include <stdlib.h>
00102 #include <string.h>
00103
00104 #define popen(command, mode) _popen((command), (mode))
00105 #define pclose(stream) _pclose(stream)
00106 #endif
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 #define SOAR_CINITIALIZESOAR_BUFFER_SIZE 1000
00120 void soar_cInitializeSoar(void)
00121 {
00122 char buffer[SOAR_CINITIALIZESOAR_BUFFER_SIZE];
00123 int i;
00124
00125 #if MICRO_VERSION_NUMBER > 0
00126 snprintf(buffer, SOAR_CINITIALIZESOAR_BUFFER_SIZE,
00127 "%d.%d.%d", MAJOR_VERSION_NUMBER, MINOR_VERSION_NUMBER, MICRO_VERSION_NUMBER);
00128 buffer[SOAR_CINITIALIZESOAR_BUFFER_SIZE - 1] = 0;
00129 #else
00130 snprintf(buffer, SOAR_CINITIALIZESOAR_BUFFER_SIZE, "%d.%d", MAJOR_VERSION_NUMBER, MINOR_VERSION_NUMBER);
00131 buffer[SOAR_CINITIALIZESOAR_BUFFER_SIZE - 1] = 0;
00132 #endif
00133
00134 soar_version_string = savestring(buffer);
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 sys_srandom(time(NULL));
00150
00151 setup_signal_handling();
00152
00153
00154
00155 for (i = 0; i < MAX_SIMULTANEOUS_AGENTS; i++)
00156 soar_agent_ids[i] = UNTOUCHED;
00157
00158 soar_init_global_callbacks();
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 int soar_cReInitSoar(void)
00172 {
00173
00174
00175 long cur_TRACE_CONTEXT_DECISIONS_SYSPARAM;
00176 long cur_TRACE_PHASES_SYSPARAM;
00177 long cur_TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM;
00178 long cur_TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM;
00179 long cur_TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM;
00180 long cur_TRACE_FIRINGS_PREFERENCES_SYSPARAM;
00181 long cur_TRACE_WM_CHANGES_SYSPARAM;
00182
00183
00184 current_agent(did_PE) = FALSE;
00185
00186 soar_invoke_callbacks(soar_agent, BEFORE_INIT_SOAR_CALLBACK, (soar_call_data) NULL);
00187
00188
00189
00190 cur_TRACE_CONTEXT_DECISIONS_SYSPARAM = current_agent(sysparams)[TRACE_CONTEXT_DECISIONS_SYSPARAM];
00191 cur_TRACE_PHASES_SYSPARAM = current_agent(sysparams)[TRACE_PHASES_SYSPARAM];
00192 cur_TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM = current_agent(sysparams)[TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM];
00193 cur_TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM = current_agent(sysparams)[TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM];
00194 cur_TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM = current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM];
00195 cur_TRACE_FIRINGS_PREFERENCES_SYSPARAM = current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM];
00196 cur_TRACE_WM_CHANGES_SYSPARAM = current_agent(sysparams)[TRACE_WM_CHANGES_SYSPARAM];
00197
00198
00199 set_sysparam(TRACE_CONTEXT_DECISIONS_SYSPARAM, FALSE);
00200 set_sysparam(TRACE_PHASES_SYSPARAM, FALSE);
00201 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, FALSE);
00202 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, FALSE);
00203 set_sysparam(TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM, NONE_WME_TRACE);
00204 set_sysparam(TRACE_FIRINGS_PREFERENCES_SYSPARAM, FALSE);
00205 set_sysparam(TRACE_WM_CHANGES_SYSPARAM, FALSE);
00206
00207
00208 clear_goal_stack();
00209
00210 #ifndef SOAR_8_ONLY
00211 if (current_agent(operand2_mode) == TRUE) {
00212 #endif
00213
00214
00215 current_agent(active_level) = 0;
00216
00217 current_agent(FIRING_TYPE) = IE_PRODS;
00218 do_preference_phase();
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 #ifndef SOAR_8_ONLY
00230 }
00231
00232
00233 else
00234 do_preference_phase();
00235 #endif
00236
00237 reset_explain();
00238 reset_id_counters();
00239 reset_wme_timetags();
00240 reset_statistics();
00241 current_agent(system_halted) = FALSE;
00242 current_agent(go_number) = 1;
00243 current_agent(go_type) = GO_DECISION;
00244
00245
00246
00247 set_sysparam(TRACE_CONTEXT_DECISIONS_SYSPARAM, cur_TRACE_CONTEXT_DECISIONS_SYSPARAM);
00248 set_sysparam(TRACE_PHASES_SYSPARAM, cur_TRACE_PHASES_SYSPARAM);
00249 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, cur_TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM);
00250 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, cur_TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM);
00251 set_sysparam(TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM, cur_TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM);
00252 set_sysparam(TRACE_FIRINGS_PREFERENCES_SYSPARAM, cur_TRACE_FIRINGS_PREFERENCES_SYSPARAM);
00253 set_sysparam(TRACE_WM_CHANGES_SYSPARAM, cur_TRACE_WM_CHANGES_SYSPARAM);
00254
00255
00256 soar_invoke_callbacks(soar_agent, AFTER_INIT_SOAR_CALLBACK, (soar_call_data) NULL);
00257
00258 current_agent(input_cycle_flag) = TRUE;
00259
00260
00261 #ifndef SOAR_8_ONLY
00262 if (current_agent(operand2_mode) == TRUE) {
00263 #endif
00264
00265 current_agent(FIRING_TYPE) = IE_PRODS;
00266 current_agent(current_phase) = INPUT_PHASE;
00267 current_agent(did_PE) = FALSE;
00268 #ifndef SOAR_8_ONLY
00269 }
00270 #endif
00271
00272
00273 #ifdef WARN_IF_TIMERS_REPORT_ZERO
00274 current_agent(warn_on_zero_timers) = TRUE;
00275 #endif
00276
00277 return 0;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 void soar_cCreateAgent(const char *agent_name)
00291 {
00292
00293 if (soar_exists_global_callback(GLB_CREATE_AGENT)) {
00294 soar_invoke_global_callbacks(NULL, GLB_CREATE_AGENT, (soar_call_data) agent_name);
00295 } else {
00296 soar_default_create_agent_procedure(agent_name);
00297 }
00298
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 int soar_cRun(long n, bool allAgents, enum go_type_enum type, enum soar_apiSlotType slot)
00312 {
00313
00314 int levels_up;
00315 Symbol *attribute, *goal;
00316 cons *c;
00317
00318 if (type != GO_SLOT && slot != NO_SLOT)
00319 return -1;
00320
00321 if (n < -1)
00322 n = -1;
00323
00324 switch (type) {
00325
00326 case GO_PHASE:
00327 run_for_n_phases(n);
00328 break;
00329 case GO_ELABORATION:
00330 run_for_n_elaboration_cycles(n);
00331 break;
00332 case GO_DECISION:
00333 run_for_n_decision_cycles(n);
00334 break;
00335 case GO_STATE:
00336 run_for_n_selections_of_slot(n, soar_agent->state_symbol);
00337 break;
00338 case GO_OPERATOR:
00339 run_for_n_selections_of_slot(n, soar_agent->operator_symbol);
00340 break;
00341
00342 case GO_OUTPUT:
00343 run_for_n_modifications_of_output(n);
00344 break;
00345
00346 case GO_SLOT:
00347 switch (slot) {
00348
00349 case STATE_SLOT:
00350 levels_up = 0;
00351 attribute = current_agent(state_symbol);
00352 break;
00353 case OPERATOR_SLOT:
00354 levels_up = 0;
00355 attribute = current_agent(operator_symbol);
00356 break;
00357 case SUPERSTATE_SLOT:
00358 levels_up = 1;
00359 attribute = current_agent(state_symbol);
00360 break;
00361 case SUPEROPERATOR_SLOT:
00362 levels_up = 1;
00363 attribute = current_agent(operator_symbol);
00364 break;
00365 case SUPERSUPERSTATE_SLOT:
00366 levels_up = 2;
00367 attribute = current_agent(state_symbol);
00368 break;
00369 case SUPERSUPEROPERATOR_SLOT:
00370 levels_up = 2;
00371 attribute = current_agent(operator_symbol);
00372 break;
00373
00374 default:
00375 return -2;
00376 break;
00377
00378 }
00379
00380 goal = current_agent(bottom_goal);
00381 while (goal && levels_up) {
00382 goal = goal->id.higher_goal;
00383 levels_up--;
00384 }
00385
00386 if (!goal)
00387 return -3;
00388
00389 run_all_agents(n, GO_SLOT, attribute, goal->id.level);
00390
00391 break;
00392
00393 }
00394
00395 if (allAgents) {
00396 for (c = all_soar_agents; c != NIL; c = c->rest) {
00397 if (((agent *) c->first)->system_halted)
00398 return -4;
00399 }
00400 } else {
00401 if (current_agent(system_halted))
00402 return -4;
00403 }
00404 return 0;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 void soar_cStopAllAgents(void)
00417 {
00418 control_c_handler(0);
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 void soar_cStopCurrentAgent(const char *reason)
00431 {
00432 current_agent(stop_soar) = TRUE;
00433 current_agent(reason_for_stopping) = reason;
00434
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 int soar_cDestroyAgentByName(const char *name)
00450 {
00451 cons *c;
00452 int name_count = 0;
00453 psoar_agent *delete_me = NULL;
00454
00455 for (c = all_soar_agents; c != NIL; c = c->rest) {
00456 if (string_match(name, ((agent *) c->first)->name)) {
00457 name_count++;
00458 delete_me = (psoar_agent) c->first;
00459 }
00460 }
00461 if (name_count > 1)
00462 return -1;
00463 if (name_count == 0)
00464 return -2;
00465 soar_cDestroyAgentByAddress(delete_me);
00466
00467 return 0;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 int soar_cDestroyAllAgentsWithName(char *name)
00483 {
00484 cons *c;
00485 int count;
00486
00487 count = 0;
00488 for (c = all_soar_agents; c != NIL; c = c->rest) {
00489 if (string_match(name, ((agent *) c->first)->name)) {
00490 count++;
00491 soar_cDestroyAgentByAddress((psoar_agent) c->first);
00492
00493 }
00494 }
00495 if (count == 0)
00496 return -1;
00497 return 0;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 void soar_cDestroyAgentByAddress(psoar_agent delete_agent)
00513 {
00514
00515 if (soar_exists_global_callback(GLB_DESTROY_AGENT)) {
00516 soar_invoke_global_callbacks(delete_agent, GLB_DESTROY_AGENT, (soar_call_data) delete_agent);
00517 } else {
00518 soar_default_destroy_agent_procedure(delete_agent);
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 int soar_cDestroyAgentById(int agent_id)
00535 {
00536 cons *c;
00537
00538 for (c = all_soar_agents; c != NIL; c = c->rest) {
00539 if (agent_id == ((agent *) c->first)->id) {
00540 soar_cDestroyAgentByAddress((psoar_agent) c->first);
00541 return 0;
00542 }
00543 }
00544
00545
00546 return -1;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 void soar_cQuit(void)
00559 {
00560
00561
00562 if (!soar_agent)
00563 return;
00564
00565 just_before_exit_soar();
00566
00567
00568 while (soar_exists_callback(soar_agent, LOG_CALLBACK)) {
00569
00570 soar_invoke_first_callback(soar_agent, LOG_CALLBACK, "\n**** quit cmd issued ****\n");
00571 soar_cPopCallback(soar_agent, LOG_CALLBACK);
00572 }
00573 #ifdef USE_AGENT_DBG_FILE
00574 fclose(current_agent(dbgFile));
00575 #endif
00576
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 int soar_cLoadReteNet(const char *filename)
00601 {
00602
00603 char pipe_command[] = "zcat ";
00604 bool using_compression_filter;
00605 char *append_loc, *command_line;
00606 FILE *f;
00607 bool result;
00608 int i;
00609
00610 if (!filename) {
00611 print("Internal error: No file name specified.\n");
00612 return SOAR_ERROR;
00613 }
00614
00615
00616 if (current_agent(all_wmes_in_rete)) {
00617 print("Internal error: Can't load RETE in non-empty system. Restart Soar first.\n");
00618 return SOAR_ERROR;
00619 }
00620
00621 for (i = 0; i < NUM_PRODUCTION_TYPES; i++)
00622 if (current_agent(num_productions_of_type)[i]) {
00623 print("Internal error: Can't load RETE in non-empty system. Restart Soar first.\n");
00624 return SOAR_ERROR;
00625 }
00626
00627 #if !defined(MACINTOSH)
00628 if ((!(strcmp((char *) (filename + strlen(filename) - 2), ".Z")))
00629 || (!(strcmp((char *) (filename + strlen(filename) - 2), ".z")))) {
00630
00631
00632
00633
00634
00635 f = fopen(filename, "rb");
00636
00637 if (!f) {
00638
00639 print("Internal error: Error opening file.\n");
00640 return SOAR_ERROR;
00641
00642 } else {
00643 fclose(f);
00644 }
00645
00646 command_line = allocate_memory(strlen(pipe_command) + strlen(filename) + 1, STRING_MEM_USAGE);
00647
00648 strcpy(command_line, pipe_command);
00649
00650 append_loc = command_line;
00651 while (*append_loc)
00652 append_loc++;
00653
00654 strcpy(append_loc, filename);
00655
00656 f = (FILE *) popen(command_line, "rb");
00657 free_memory(command_line, STRING_MEM_USAGE);
00658
00659 using_compression_filter = TRUE;
00660 } else
00661 #endif
00662 {
00663
00664 f = fopen(filename, "rb");
00665 using_compression_filter = FALSE;
00666 }
00667
00668 if (!f) {
00669
00670 print("Internal error: error opening file.\n");
00671 return SOAR_ERROR;
00672
00673 }
00674
00675 result = load_rete_net(f);
00676
00677 #if !defined(MACINTOSH)
00678 if (using_compression_filter == TRUE) {
00679 pclose(f);
00680 } else
00681 #endif
00682 {
00683 fclose(f);
00684 }
00685
00686 return SOAR_OK;
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 int soar_cSaveReteNet(const char *filename)
00700 {
00701
00702 char *command_line;
00703 char pipe_command[] = "compress > ";
00704 FILE *f;
00705 bool using_compression_filter = FALSE;
00706 char *append_loc;
00707
00708 if (current_agent(all_productions_of_type)[JUSTIFICATION_PRODUCTION_TYPE]) {
00709 print("Internal error: can't save rete with justifications present.\n");
00710 return SOAR_ERROR;
00711 }
00712
00713 #if !defined(MACINTOSH)
00714 if ((!(strcmp((char *) (filename + strlen(filename) - 2), ".Z")))
00715 || (!(strcmp((char *) (filename + strlen(filename) - 2), ".z")))) {
00716
00717 command_line = allocate_memory(strlen(pipe_command) + strlen(filename) + 1, STRING_MEM_USAGE);
00718
00719 strcpy(command_line, pipe_command);
00720
00721 append_loc = command_line;
00722 while (*append_loc)
00723 append_loc++;
00724
00725 strcpy(append_loc, filename);
00726
00727 f = (FILE *) popen(command_line, "wb");
00728 free_memory(command_line, STRING_MEM_USAGE);
00729
00730 using_compression_filter = TRUE;
00731
00732 } else
00733 #endif
00734 {
00735
00736 f = fopen(filename, "wb");
00737 using_compression_filter = FALSE;
00738 }
00739
00740 if (!f) {
00741
00742 print("Internal error: error opening file.\n");
00743 return SOAR_ERROR;
00744 }
00745
00746 save_rete_net(f);
00747
00748 #if !defined(MACINTOSH)
00749 if (using_compression_filter == TRUE) {
00750 pclose(f);
00751 } else
00752 #endif
00753 {
00754 fclose(f);
00755 }
00756
00757 return SOAR_OK;
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 long soar_cAddWme(const char *szId, const char *szAttr, const char *szValue,
00771 bool acceptable_preference, psoar_wme * new_wme)
00772 {
00773
00774 Symbol *id, *attr, *value;
00775 wme *w;
00776
00777
00778 if (read_id_or_context_var_from_string(szId, &id) == SOAR_ERROR)
00779 return -1;
00780
00781
00782
00783 if (*szAttr == '^')
00784 szAttr++;
00785
00786
00787 if (string_match("*", szAttr) == TRUE) {
00788 #ifdef USE_AGENT_DBG_FILE
00789 fprintf(current_agent(dbgFile), "'%s' matches '*'\n", szAttr);
00790 #endif
00791
00792 attr = make_new_identifier('I', id->id.level);
00793 } else {
00794 get_lexeme_from_string(szAttr);
00795
00796 switch (current_agent(lexeme).type) {
00797 case SYM_CONSTANT_LEXEME:
00798 attr = make_sym_constant(current_agent(lexeme).string);
00799 break;
00800 case INT_CONSTANT_LEXEME:
00801 attr = make_int_constant(current_agent(lexeme).int_val);
00802 break;
00803 case FLOAT_CONSTANT_LEXEME:
00804 attr = make_float_constant(current_agent(lexeme).float_val);
00805 break;
00806 case IDENTIFIER_LEXEME:
00807 case VARIABLE_LEXEME:
00808 attr = read_identifier_or_context_variable();
00809 if (!attr) {
00810 return -2;
00811 }
00812 symbol_add_ref(attr);
00813 break;
00814 default:
00815 return -2;
00816 }
00817 }
00818
00819
00820
00821 if (string_match("*", szValue) == TRUE) {
00822 value = make_new_identifier('I', id->id.level);
00823 } else {
00824 get_lexeme_from_string(szValue);
00825 switch (current_agent(lexeme).type) {
00826 case SYM_CONSTANT_LEXEME:
00827 value = make_sym_constant(current_agent(lexeme).string);
00828 break;
00829 case INT_CONSTANT_LEXEME:
00830 value = make_int_constant(current_agent(lexeme).int_val);
00831 break;
00832 case FLOAT_CONSTANT_LEXEME:
00833 value = make_float_constant(current_agent(lexeme).float_val);
00834 break;
00835 case IDENTIFIER_LEXEME:
00836 case VARIABLE_LEXEME:
00837 value = read_identifier_or_context_variable();
00838 if (!value) {
00839 symbol_remove_ref(attr);
00840 return -3;
00841 }
00842 symbol_add_ref(value);
00843 break;
00844 default:
00845 symbol_remove_ref(attr);
00846 return -3;
00847 }
00848 }
00849
00850
00851 w = make_wme(id, attr, value, acceptable_preference);
00852
00853 symbol_remove_ref(w->attr);
00854 symbol_remove_ref(w->value);
00855 insert_at_head_of_dll(w->id->id.input_wmes, w, next, prev);
00856 add_wme_to_wm(w);
00857
00858 #ifdef USE_CAPTURE_REPLAY
00859
00860
00861 if (current_agent(capture_fileID) && (current_agent(current_phase) == INPUT_PHASE)) {
00862
00863 soarapi_wme sapi_wme;
00864
00865
00866
00867
00868 sapi_wme.id = szId;
00869 sapi_wme.attr = szAttr;
00870 sapi_wme.value = szValue;
00871 sapi_wme.timetag = w->timetag;
00872
00873 capture_input_wme(ADD_WME, &sapi_wme, w);
00874 }
00875
00876
00877 #endif
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 #ifndef NO_TIMING_STUFF
00907 if (current_agent(current_phase) == INPUT_PHASE) {
00908
00909 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(input_function_cpu_time));
00910 start_timer(¤t_agent(start_kernel_tv));
00911
00912 #ifndef KERNEL_TIME_ONLY
00913 start_timer(¤t_agent(start_phase_tv));
00914 #endif
00915 }
00916 #endif
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 #ifndef NO_TOP_LEVEL_REFS
00940 do_buffered_wm_and_ownership_changes();
00941 #endif
00942
00943
00944 #ifndef NO_TIMING_STUFF
00945 if (current_agent(current_phase) == INPUT_PHASE) {
00946
00947 #ifndef KERNEL_TIME_ONLY
00948 stop_timer(¤t_agent(start_phase_tv),
00949 ¤t_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00950 #endif
00951 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
00952 start_timer(¤t_agent(start_kernel_tv));
00953 }
00954 #endif
00955
00956
00957
00958 *new_wme = (psoar_wme) w;
00959 return w->timetag;
00960
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 int soar_cRemoveWmeUsingTimetag(int num)
00980 {
00981
00982 wme *w;
00983
00984 for (w = current_agent(all_wmes_in_rete); w != NIL; w = w->rete_next)
00985 if (w->timetag == (unsigned long) num)
00986 break;
00987
00988 if (!w)
00989 return -1;
00990
00991 if (!soar_cRemoveWme(w))
00992 return 0;
00993
00994 return -2;
00995 }
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 int soar_cRemoveWme(psoar_wme the_wme)
01010 {
01011
01012 wme *w, *w2;
01013 Symbol *id;
01014 slot *s;
01015
01016 w = (wme *) the_wme;
01017
01018 id = w->id;
01019
01020
01021 for (w2 = id->id.input_wmes; w2 != NIL; w2 = w2->next)
01022 if (w == w2)
01023 break;
01024
01025 if (w2)
01026 remove_from_dll(id->id.input_wmes, w, next, prev);
01027
01028 for (w2 = id->id.impasse_wmes; w2 != NIL; w2 = w2->next)
01029 if (w == w2)
01030 break;
01031
01032 if (w2)
01033 remove_from_dll(id->id.impasse_wmes, w, next, prev);
01034
01035 for (s = id->id.slots; s != NIL; s = s->next) {
01036
01037 for (w2 = s->wmes; w2 != NIL; w2 = w2->next)
01038 if (w == w2)
01039 break;
01040
01041 if (w2)
01042 remove_from_dll(s->wmes, w, next, prev);
01043
01044 for (w2 = s->acceptable_preference_wmes; w2 != NIL; w2 = w2->next)
01045 if (w == w2)
01046 break;
01047
01048 if (w2)
01049 remove_from_dll(s->acceptable_preference_wmes, w, next, prev);
01050 }
01051
01052 #ifdef USE_CAPTURE_REPLAY
01053
01054
01055
01056 if (current_agent(capture_fileID) && (current_agent(current_phase) == INPUT_PHASE)) {
01057 soarapi_wme sapi_wme;
01058
01059 sapi_wme.id = NULL;
01060 sapi_wme.attr = NULL;
01061 sapi_wme.value = NULL;
01062 sapi_wme.timetag = w->timetag;
01063
01064 capture_input_wme(REMOVE_WME, &sapi_wme, NULL);
01065 }
01066
01067 #endif
01068
01069
01070 #ifndef SOAR_8_ONLY
01071 if (current_agent(operand2_mode)) {
01072 #endif
01073 if (w->gds) {
01074 if (w->gds->goal != NIL) {
01075
01076 gds_invalid_so_remove_goal(w);
01077
01078
01079
01080 }
01081 }
01082 #ifndef SOAR_8_ONLY
01083 }
01084 #endif
01085
01086
01087
01088
01089 remove_wme_from_wm(w);
01090
01091
01092
01093
01094 if (current_agent(current_phase) != INPUT_PHASE) {
01095 #ifndef NO_TIMING_STUFF
01096 start_timer(¤t_agent(start_kernel_tv));
01097 #ifndef KERNEL_TIME_ONLY
01098 start_timer(¤t_agent(start_phase_tv));
01099 #endif
01100 #endif
01101
01102
01103
01104 #ifndef NO_TIMING_STUFF
01105 #ifndef KERNEL_TIME_ONLY
01106 stop_timer(¤t_agent(start_phase_tv),
01107 ¤t_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
01108 #endif
01109 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
01110 start_timer(¤t_agent(start_kernel_tv));
01111 #endif
01112 }
01113
01114
01115
01116 #ifndef NO_TOP_LEVEL_REFS
01117 do_buffered_wm_and_ownership_changes();
01118 #endif
01119
01120 return 0;
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 void soar_cExciseAllProductions(void)
01134 {
01135
01136 soar_cExciseAllProductionsOfType(DEFAULT_PRODUCTION_TYPE);
01137 soar_cExciseAllProductionsOfType(CHUNK_PRODUCTION_TYPE);
01138 soar_cExciseAllProductionsOfType(JUSTIFICATION_PRODUCTION_TYPE);
01139 soar_cExciseAllProductionsOfType(USER_PRODUCTION_TYPE);
01140 soar_cReInitSoar();
01141 }
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 void soar_cExciseAllTaskProductions(void)
01155 {
01156 soar_cExciseAllProductionsOfType(CHUNK_PRODUCTION_TYPE);
01157 soar_cExciseAllProductionsOfType(JUSTIFICATION_PRODUCTION_TYPE);
01158 soar_cExciseAllProductionsOfType(USER_PRODUCTION_TYPE);
01159 soar_cReInitSoar();
01160 }
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 void soar_cExciseAllProductionsOfType(byte type)
01173 {
01174 while (current_agent(all_productions_of_type)[type])
01175 excise_production(current_agent(all_productions_of_type)[type],
01176 (bool) (TRUE && current_agent(sysparams)[TRACE_LOADING_SYSPARAM]));
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 int soar_cExciseProductionByName(const char *name)
01189 {
01190 production *p;
01191
01192 p = name_to_production(name);
01193 if (p) {
01194 excise_production(p, (bool) (TRUE && current_agent(sysparams)[TRACE_LOADING_SYSPARAM]));
01195 return 0;
01196 }
01197
01198 return -1;
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 #ifndef NO_TIMING_STUFF
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 double soar_cDetermineTimerResolution(double *min, double *max)
01222 {
01223
01224 double delta, max_delta, min_delta, min_nz_delta;
01225 float q;
01226 int i, j, top;
01227 #ifdef PII_TIMERS
01228 unsigned long long int start, end, total;
01229 #else
01230 struct timeval start, end, total;
01231 #endif
01232
01233 top = ONE_MILLION;
01234 min_delta = ONE_MILLION;
01235 min_nz_delta = ONE_MILLION;
01236 max_delta = -1;
01237 reset_timer(&total);
01238
01239 for (i = 0; i < ONE_MILLION; i = (i + 1) * 2) {
01240 reset_timer(&end);
01241 start_timer(&start);
01242 for (j = 0; j < i * top; j++) {
01243 q = (float) (j * i);
01244 }
01245 stop_timer(&start, &end);
01246 stop_timer(&start, &total);
01247 delta = timer_value(&end);
01248
01249 if (delta < min_delta)
01250 min_delta = delta;
01251 if (delta && delta < min_nz_delta)
01252 min_nz_delta = delta;
01253 if (delta > max_delta)
01254 max_delta = delta;
01255
01256
01257 if (timer_value(&total) >= 2) {
01258 break;
01259 }
01260
01261 }
01262
01263 if (min_nz_delta == ONE_MILLION)
01264 min_nz_delta = -1;
01265 if (min_delta == ONE_MILLION)
01266 min_delta = -1;
01267
01268 if (min != NULL)
01269 *min = min_delta;
01270 if (max != NULL)
01271 *max = max_delta;
01272 return min_nz_delta;
01273
01274 }
01275 #endif
01276
01277 #ifdef DC_HISTOGRAM
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 void soar_cInitializeDCHistogram(int nDC, int freq)
01288 {
01289 int i;
01290
01291 current_agent(dc_histogram_freq) = freq;
01292
01293 if (nDC < current_agent(dc_histogram_sz)) {
01294 current_agent(dc_histogram_sz) = nDC;
01295 } else {
01296 free(current_agent(dc_histogram_tv));
01297 current_agent(dc_histogram_sz) = nDC;
01298 current_agent(dc_histogram_tv) = (struct timeval *) malloc(nDC * sizeof(struct timeval));
01299 }
01300
01301 for (i = 0; i < nDC; i++) {
01302 reset_timer(¤t_agent(dc_histogram_tv)[i]);
01303 }
01304 }
01305 #endif
01306
01307 #ifdef KT_HISTOGRAM
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 void soar_cInitializeKTHistogram(int size)
01318 {
01319 int i;
01320
01321 if (size < current_agent(kt_histogram_sz)) {
01322 current_agent(kt_histogram_sz) = size;
01323 } else {
01324 free(current_agent(kt_histogram_tv));
01325 current_agent(kt_histogram_sz) = size;
01326 current_agent(kt_histogram_tv) = (struct timeval *) malloc(size * sizeof(struct timeval));
01327 }
01328
01329 for (i = 0; i < size; i++) {
01330 reset_timer(¤t_agent(kt_histogram_tv)[i]);
01331 }
01332 }
01333 #endif
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345 void soar_cSetChunkNameLong(bool truly)
01346 {
01347
01348 set_sysparam(USE_LONG_CHUNK_NAMES, truly);
01349
01350 }
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 int soar_cSetChunkNameCount(long count)
01364 {
01365
01366 if (count < 0)
01367 return -1;
01368
01369 if (count >= current_agent(sysparams)[MAX_CHUNKS_SYSPARAM])
01370 return -2;
01371
01372 if ((unsigned long) count < current_agent(chunk_count))
01373 return -3;
01374
01375 current_agent(chunk_count) = count;
01376 return 0;
01377 }
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389 int soar_cSetChunkNamePrefix(const char *prefix)
01390 {
01391
01392 if (strchr(prefix, '*')) {
01393 return -1;
01394 }
01395 strncpy(current_agent(chunk_name_prefix), prefix, kChunkNamePrefixMaxLength);
01396 current_agent(chunk_name_prefix)[kChunkNamePrefixMaxLength - 1] = 0;
01397 return 0;
01398
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 void soar_cSetLearning(enum soar_apiLearningSetting setting)
01411 {
01412
01413 switch (setting) {
01414
01415 case ON:
01416 set_sysparam(LEARNING_ON_SYSPARAM, TRUE);
01417 set_sysparam(LEARNING_ONLY_SYSPARAM, FALSE);
01418 set_sysparam(LEARNING_EXCEPT_SYSPARAM, FALSE);
01419 break;
01420 case OFF:
01421 set_sysparam(LEARNING_ON_SYSPARAM, FALSE);
01422 set_sysparam(LEARNING_ONLY_SYSPARAM, FALSE);
01423 set_sysparam(LEARNING_EXCEPT_SYSPARAM, FALSE);
01424 break;
01425 case ONLY:
01426 set_sysparam(LEARNING_ON_SYSPARAM, TRUE);
01427 set_sysparam(LEARNING_ONLY_SYSPARAM, TRUE);
01428 set_sysparam(LEARNING_EXCEPT_SYSPARAM, FALSE);
01429 break;
01430 case EXCEPT:
01431 set_sysparam(LEARNING_ON_SYSPARAM, TRUE);
01432 set_sysparam(LEARNING_ONLY_SYSPARAM, FALSE);
01433 set_sysparam(LEARNING_EXCEPT_SYSPARAM, TRUE);
01434 break;
01435 case ALL_LEVELS:
01436 set_sysparam(LEARNING_ALL_GOALS_SYSPARAM, TRUE);
01437 break;
01438 case BOTTOM_UP:
01439 set_sysparam(LEARNING_ALL_GOALS_SYSPARAM, FALSE);
01440 break;
01441
01442 }
01443
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453 int soar_cSetOperand2(bool turnOn)
01454 {
01455 int i;
01456
01457
01458 if (current_agent(all_wmes_in_rete)) {
01459 return -1;
01460 }
01461 for (i = 0; i < NUM_PRODUCTION_TYPES; i++)
01462 if (current_agent(num_productions_of_type)[i]) {
01463 return -2;
01464 }
01465
01466 current_agent(operand2_mode) = turnOn;
01467 soar_cReInitSoar();
01468
01469 return 0;
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483 void soar_cSetWaitSNC(bool on)
01484 {
01485
01486 current_agent(waitsnc) = on;
01487 }
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499 int soar_cMultiAttributes(const char *attribute, int value)
01500 {
01501 multi_attribute *m;
01502 Symbol *s;
01503
01504 get_lexeme_from_string(attribute);
01505
01506 if (current_agent(lexeme).type != SYM_CONSTANT_LEXEME) {
01507 return -1;
01508 }
01509 if (value < 1) {
01510 return -2;
01511 }
01512
01513 m = current_agent(multi_attributes);
01514 s = make_sym_constant(attribute);
01515
01516 while (m) {
01517 if (m->symbol == s) {
01518 m->value = value;
01519 symbol_remove_ref(s);
01520 return 0;
01521 }
01522 m = m->next;
01523 }
01524
01525 m = (multi_attribute *) allocate_memory(sizeof(multi_attribute), MISCELLANEOUS_MEM_USAGE);
01526 m->value = value;
01527 m->symbol = s;
01528 m->next = current_agent(multi_attributes);
01529 current_agent(multi_attributes) = m;
01530
01531 return 0;
01532 }
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543 #ifndef SOAR_8_ONLY
01544 int soar_cAttributePreferencesMode(int mode)
01545 {
01546
01547 if (current_agent(operand2_mode) && (mode != 2)) {
01548
01549
01550 return -1;
01551 }
01552
01553 if (mode >= 0 && mode <= 2) {
01554 current_agent(attribute_preferences_mode) = mode;
01555 } else {
01556
01557
01558
01559 return -2;
01560 }
01561
01562 return 0;
01563 }
01564
01565 #else
01566
01567 int soar_cAttributePreferencesMode(int mode)
01568 {
01569
01570 if (mode != 2) {
01571
01572
01573 return -1;
01574 }
01575
01576 return 0;
01577 }
01578
01579 #endif
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610 void soar_cAddInputFunction(agent * a, soar_callback_fn f,
01611 soar_callback_data cb_data, soar_callback_free_fn free_fn, const char *name)
01612 {
01613 soar_cAddCallback(a, INPUT_PHASE_CALLBACK, f, cb_data, free_fn, name);
01614 }
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625 void soar_cRemoveInputFunction(agent * a, const char *name)
01626 {
01627 soar_cRemoveCallback(a, INPUT_PHASE_CALLBACK, name);
01628 }
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639 void soar_cAddOutputFunction(agent * a, soar_callback_fn f,
01640 soar_callback_data cb_data, soar_callback_free_fn free_fn, const char *output_link_name)
01641 {
01642 if (soar_exists_callback_id(a, OUTPUT_PHASE_CALLBACK, output_link_name)
01643 != NULL) {
01644 print("Error: tried to add_output_function with duplicate name %s\n", output_link_name);
01645 control_c_handler(0);
01646 } else {
01647 soar_cAddCallback(a, OUTPUT_PHASE_CALLBACK, f, cb_data, free_fn, output_link_name);
01648 }
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 void soar_cRemoveOutputFunction(agent * a, const char *name)
01661 {
01662 soar_callback *cb;
01663 output_link *ol;
01664
01665
01666
01667 cb = soar_exists_callback_id(a, OUTPUT_PHASE_CALLBACK, name);
01668 if (!cb)
01669 return;
01670
01671 for (ol = a->existing_output_links; ol != NIL; ol = ol->next) {
01672 if (ol->cb == cb) {
01673
01674 ol->link_wme->output_link = NULL;
01675 wme_remove_ref(ol->link_wme);
01676 remove_from_dll(a->existing_output_links, ol, next, prev);
01677 free_with_pool(&(a->output_link_pool), ol);
01678 break;
01679 }
01680 }
01681
01682 soar_cRemoveCallback(a, OUTPUT_PHASE_CALLBACK, name);
01683 }
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 void soar_cPushCallback(soar_callback_agent the_agent,
01694 SOAR_CALLBACK_TYPE callback_type,
01695 soar_callback_fn fn, soar_callback_data data, soar_callback_free_fn free_fn)
01696 {
01697 soar_callback *cb;
01698
01699 cb = (soar_callback *) malloc(sizeof(soar_callback));
01700 cb->function = fn;
01701 cb->data = data;
01702 cb->free_function = free_fn;
01703 cb->id = NULL;
01704
01705
01706
01707
01708
01709
01710
01711 push(cb, ((agent *) the_agent)->soar_callbacks[callback_type]);
01712 }
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 void soar_cAddCallback(soar_callback_agent the_agent,
01723 SOAR_CALLBACK_TYPE callback_type,
01724 soar_callback_fn fn, soar_callback_data data, soar_callback_free_fn free_fn, soar_callback_id id)
01725 {
01726 soar_callback *cb;
01727
01728 cb = (soar_callback *) malloc(sizeof(soar_callback));
01729 cb->function = fn;
01730 cb->data = data;
01731 cb->free_function = free_fn;
01732 cb->id = savestring((char *) id);
01733
01734 push(cb, ((agent *) the_agent)->soar_callbacks[callback_type]);
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 void soar_cPopCallback(soar_callback_agent the_agent, SOAR_CALLBACK_TYPE callback_type)
01746 {
01747 list *head;
01748 soar_callback *cb;
01749
01750 head = ((agent *) the_agent)->soar_callbacks[callback_type];
01751
01752 if (head == NULL) {
01753 print_string("Attempt to remove non-existant callback.\n");
01754 return;
01755 }
01756
01757 if ((callback_type == PRINT_CALLBACK)
01758 && (head->rest == NULL)) {
01759 print_string("Attempt to remove last print callback. Ignored.\n");
01760 return;
01761 }
01762
01763 cb = (soar_callback *) head->first;
01764
01765 ((agent *) the_agent)->soar_callbacks[callback_type] = head->rest;
01766 soar_destroy_callback(cb);
01767 free_cons(head);
01768 }
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778 void soar_cRemoveCallback(soar_callback_agent the_agent, SOAR_CALLBACK_TYPE callback_type, soar_callback_id id)
01779 {
01780 cons *c;
01781 cons *prev_c = NULL;
01782 list *head;
01783
01784 head = ((agent *) the_agent)->soar_callbacks[callback_type];
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796 for (c = head; c != NULL; ) {
01797 soar_callback *cb;
01798
01799 cb = (soar_callback *) c->first;
01800
01801 if (!strcmp(cb->id, id)) {
01802 if (c != head) {
01803 prev_c->rest = c->rest;
01804 soar_destroy_callback(cb);
01805 free_cons(c);
01806 c = prev_c->rest;
01807
01808 } else {
01809 ((agent *) the_agent)->soar_callbacks[callback_type]
01810 = head->rest;
01811 soar_destroy_callback(cb);
01812 free_cons(c);
01813 head = ((agent *) the_agent)->soar_callbacks[callback_type];
01814 c = head;
01815 prev_c = NULL;
01816
01817 }
01818
01819 }
01820 else {
01821 prev_c = c;
01822 c = c->rest;
01823
01824 }
01825
01826
01827 }
01828 }
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 void soar_cAddGlobalCallback(SOAR_GLOBAL_CALLBACK_TYPE callback_type,
01839 soar_callback_fn fn,
01840 soar_callback_data data, soar_callback_free_fn free_fn, soar_callback_id id)
01841 {
01842 soar_callback *cb;
01843
01844 cb = (soar_callback *) malloc(sizeof(soar_callback));
01845 cb->function = fn;
01846 cb->data = data;
01847 cb->free_function = free_fn;
01848 cb->id = savestring((char *) id);
01849
01850
01851
01852
01853 {
01854 cons *push_cons_xy298;
01855 push_cons_xy298 = (cons *) malloc(sizeof(cons));
01856 push_cons_xy298->first = (cb);
01857 push_cons_xy298->rest = (soar_global_callbacks[callback_type]);
01858 soar_global_callbacks[callback_type] = push_cons_xy298;
01859 }
01860
01861 }
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871 void soar_cRemoveGlobalCallback(SOAR_GLOBAL_CALLBACK_TYPE callback_type, soar_callback_id id)
01872 {
01873 list *head;
01874 cons *c;
01875 cons *prev_c = NULL;
01876 soar_callback *cb;
01877
01878 head = soar_global_callbacks[callback_type];
01879
01880 for (c = head; c != NIL; c = c->rest) {
01881
01882 cb = (soar_callback *) c->first;
01883
01884 if (!strcmp(cb->id, id)) {
01885 if (c != head) {
01886 prev_c->rest = c->rest;
01887 soar_destroy_callback(cb);
01888 free_cons(c);
01889 return;
01890 } else {
01891 soar_global_callbacks[callback_type] = head->rest;
01892 soar_destroy_callback(cb);
01893 free_cons(c);
01894 return;
01895 }
01896 }
01897 prev_c = c;
01898 }
01899 }
01900
01901 void soar_cListAllCallbacks(soar_callback_agent the_agent, bool monitorable_only)
01902 {
01903 int limit;
01904 SOAR_CALLBACK_TYPE ct;
01905
01906 if (monitorable_only) {
01907 limit = NUMBER_OF_MONITORABLE_CALLBACKS;
01908 } else {
01909 limit = NUMBER_OF_CALLBACKS;
01910 }
01911
01912 for (ct = 1; ct < limit; ct++) {
01913 print("%s: ", soar_callback_enum_to_name(ct, FALSE));
01914 soar_cListAllCallbacksForEvent(the_agent, ct);
01915 print("\n");
01916 }
01917 }
01918
01919 void soar_cListAllCallbacksForEvent(soar_callback_agent the_agent, SOAR_CALLBACK_TYPE ct)
01920 {
01921 cons *c;
01922
01923 for (c = ((agent *) the_agent)->soar_callbacks[ct]; c != NIL; c = c->rest) {
01924 soar_callback *cb;
01925
01926 cb = (soar_callback *) c->first;
01927
01928 print("%s ", cb->id);
01929 }
01930 }
01931
01932 void soar_cRemoveAllMonitorableCallbacks(soar_callback_agent the_agent)
01933 {
01934 SOAR_CALLBACK_TYPE ct;
01935
01936 for (ct = 1; ct < NUMBER_OF_MONITORABLE_CALLBACKS; ct++) {
01937 soar_cRemoveAllCallbacksForEvent(the_agent, ct);
01938 }
01939 }
01940
01941 void soar_cRemoveAllCallbacksForEvent(soar_callback_agent the_agent, SOAR_CALLBACK_TYPE ct)
01942 {
01943 cons *c;
01944 list *next;
01945
01946 next = ((agent *) the_agent)->soar_callbacks[ct];
01947
01948 for (c = next; c != NIL; c = next) {
01949 soar_callback *cb;
01950
01951 cb = (soar_callback *) c->first;
01952
01953 next = next->rest;
01954 soar_destroy_callback(cb);
01955 free_cons(c);
01956 }
01957
01958 ((agent *) the_agent)->soar_callbacks[ct] = NIL;
01959 }
01960
01961 void soar_cTestAllMonitorableCallbacks(soar_callback_agent the_agent)
01962 {
01963 SOAR_CALLBACK_TYPE i;
01964 static char *test_callback_name = "test";
01965
01966 for (i = 1; i < NUMBER_OF_MONITORABLE_CALLBACKS; i++) {
01967 soar_cAddCallback(the_agent, i,
01968 (soar_callback_fn) soar_cTestCallback,
01969 soar_callback_enum_to_name(i, TRUE), NULL, test_callback_name);
01970 }
01971 }
01972
01973 SOAR_CALLBACK_TYPE soar_cCallbackNameToEnum(const char *name, bool monitorable_only)
01974 {
01975 int limit;
01976 SOAR_CALLBACK_TYPE i;
01977
01978 if (monitorable_only) {
01979 limit = NUMBER_OF_MONITORABLE_CALLBACKS;
01980 } else {
01981 limit = NUMBER_OF_CALLBACKS;
01982 }
01983
01984 for (i = 1; i < limit; i++) {
01985 if (!strcmp(name, soar_callback_names[i])) {
01986 return i;
01987 }
01988 }
01989
01990 return NO_CALLBACK;
01991 }
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017 char *soar_cGetWmeId(psoar_wme w, char *buff, size_t buff_size)
02018 {
02019 char *temp;
02020 char *ret;
02021
02022 temp = symbol_to_string(((wme *) w)->id, TRUE, buff, buff_size);
02023 if (buff)
02024 return buff;
02025
02026 ret = (char *) malloc((strlen(temp) + 1) * sizeof(char));
02027 strcpy(ret, temp);
02028
02029 return ret;
02030 }
02031
02032 char *soar_cGetWmeAttr(psoar_wme w, char *buff, size_t buff_size)
02033 {
02034 char *temp;
02035 char *ret;
02036
02037 temp = symbol_to_string(((wme *) w)->attr, TRUE, buff, buff_size);
02038 if (buff)
02039 return buff;
02040
02041 ret = (char *) malloc((strlen(temp) + 1) * sizeof(char));
02042 strcpy(ret, temp);
02043
02044 return ret;
02045
02046 }
02047
02048 char *soar_cGetWmeValue(psoar_wme w, char *buff, size_t buff_size)
02049 {
02050 char *temp;
02051 char *ret;
02052
02053 temp = symbol_to_string(((wme *) w)->value, TRUE, buff, buff_size);
02054 if (buff)
02055 return buff;
02056
02057 ret = (char *) malloc((strlen(temp) + 1) * sizeof(char));
02058 strcpy(ret, temp);
02059
02060 return ret;
02061
02062 }
02063
02064 unsigned long soar_cGetWmeTimetag(psoar_wme w)
02065 {
02066 return ((wme *) w)->timetag;
02067 }
02068
02069 #define SOAR_CADDINTWME_TEMP_SIZE 128
02070 unsigned long soar_cAddIntWme(char *szId, char *szAttr, int value, bool acceptable, psoar_wme * w)
02071 {
02072 char temp[SOAR_CADDINTWME_TEMP_SIZE];
02073
02074 snprintf(temp, SOAR_CADDINTWME_TEMP_SIZE, "%d", value);
02075 temp[SOAR_CADDINTWME_TEMP_SIZE - 1] = 0;
02076
02077 return soar_cAddWme(szId, szAttr, temp, acceptable, w);
02078 }
02079
02080 #define SOAR_CADDFLOATWME_TEMP_SIZE 128
02081 unsigned long soar_cAddFloatWme(char *szId, char *szAttr, float value, bool acceptable, psoar_wme * w)
02082 {
02083 char temp[SOAR_CADDFLOATWME_TEMP_SIZE];
02084
02085 snprintf(temp, SOAR_CADDFLOATWME_TEMP_SIZE, "%f", value);
02086 temp[SOAR_CADDFLOATWME_TEMP_SIZE - 1] = 0;
02087
02088 return soar_cAddWme(szId, szAttr, temp, acceptable, w);
02089 }
02090
02091 void soar_cInitAgentIterator(soar_apiAgentIterator * ai)
02092 {
02093 cons *c;
02094
02095 ai->_begin = NIL;
02096
02097 for (c = all_soar_agents; c != NIL; c = c->rest) {
02098 if (((agent *) c->first) == soar_agent) {
02099 ai->_begin = c;
02100 ai->_current = c;
02101 ai->more = (bool) ((agent_count > 0) ? TRUE : FALSE);
02102 }
02103 }
02104 if (ai->_begin == NIL) {
02105 print("ERROR!!!!!!!!!!");
02106 }
02107
02108 }
02109
02110 bool soar_cStepAgentIterator(soar_apiAgentIterator * ai)
02111 {
02112
02113 ai->_current = ai->_current->rest;
02114 if (ai->_current == NIL) {
02115 ai->_current = all_soar_agents;
02116 }
02117 ai->more = TRUE;
02118
02119 if (ai->_current == ai->_begin) {
02120 ai->more = FALSE;
02121 } else if (ai->_current->rest == NIL && all_soar_agents == ai->_current) {
02122 ai->more = FALSE;
02123 }
02124
02125 soar_agent = ai->_current->first;
02126
02127 return ai->more;
02128 }
02129
02130 psoar_agent soar_cGetAgentByName(char *name)
02131 {
02132 cons *c;
02133
02134 for (c = all_soar_agents; c != NIL; c = c->rest) {
02135 if (!strcmp(((agent *) c->first)->name, name)) {
02136 return (psoar_agent) c->first;
02137 }
02138 }
02139 return NIL;
02140
02141 }
02142
02143 int soar_cGetIdForAgentByName(char *name)
02144 {
02145 psoar_agent a;
02146
02147 a = soar_cGetAgentByName(name);
02148 if (!a)
02149 return -1;
02150
02151 return ((agent *) a)->id;
02152
02153 }
02154
02155 bool soar_cSetCurrentAgentByName(char *name)
02156 {
02157 psoar_agent a;
02158
02159 a = soar_cGetAgentByName(name);
02160 if (!a)
02161 return FALSE;
02162
02163 soar_agent = (agent *) a;
02164 return TRUE;
02165 }
02166
02167 void soar_cSetCurrentAgent(psoar_agent a)
02168 {
02169
02170 soar_agent = (agent *) a;
02171 }
02172
02173 psoar_agent soar_cGetCurrentAgent()
02174 {
02175 return (psoar_agent) soar_agent;
02176 }
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189 char *soar_cGetAgentInputLinkId(psoar_agent a, char *buff, size_t buff_size)
02190 {
02191 char *temp;
02192 char *ret;
02193
02194 if (((agent *) a)->io_header_input == NULL) {
02195 if (buff)
02196 *buff = '\0';
02197 return "";
02198 }
02199
02200 temp = symbol_to_string(((agent *) a)->io_header_input, TRUE, buff, buff_size);
02201 if (buff)
02202 return buff;
02203
02204 ret = (char *) malloc((strlen(temp) + 1) * sizeof(char));
02205 strcpy(ret, temp);
02206
02207 return ret;
02208 }
02209
02210 char *soar_cGetAgentOutputLinkId(psoar_agent a, char *buff, size_t buff_size)
02211 {
02212 char *temp;
02213 char *ret;
02214
02215 if (((agent *) a)->io_header_output == NULL) {
02216 if (buff)
02217 *buff = '\0';
02218 return "";
02219 }
02220
02221 temp = symbol_to_string(((agent *) a)->io_header_output, TRUE, buff, buff_size);
02222 if (buff)
02223 return buff;
02224
02225 ret = (char *) malloc((strlen(temp) + 1) * sizeof(char));
02226 strcpy(ret, temp);
02227
02228 return ret;
02229 }
02230
02231 int soar_cGetAgentId(psoar_agent a)
02232 {
02233
02234 if (a == NULL)
02235 return -1;
02236
02237 return ((agent *) a)->id;
02238 }
02239
02240 void soar_cTestCallback(soar_callback_agent the_agent, soar_callback_data data, soar_call_data call_data)
02241 {
02242 the_agent = the_agent;
02243 call_data = call_data;
02244
02245 print("%s test callback executed.\n", (char *) data);
02246 }
02247
02248 #define SOAR_CDEFAULTASKCALLBACK_TEMP_SIZE 50
02249 void soar_cDefaultAskCallback(soar_callback_agent the_agent, soar_callback_data data, soar_call_data call_data)
02250 {
02251
02252 int num_candidates, chosen_num;
02253 preference *cand;
02254
02255 the_agent = the_agent;
02256 data = data;
02257
02258 *((soar_apiAskCallbackData *) call_data)->selection = NULL;
02259
02260 num_candidates = 0;
02261 print("\nPlease choose one of the following:\n");
02262 for (cand = ((soar_apiAskCallbackData *) call_data)->candidates; cand != NIL; cand = cand->next_candidate) {
02263
02264 num_candidates++;
02265 print(" %d: ", num_candidates);
02266 print_object_trace(cand->value);
02267 print("\n");
02268 }
02269
02270
02271 print("Or choose one of the following to change the user-select mode\n");
02272 print("to something else: %d (first)", ++num_candidates);
02273 print(", %d (last)", ++num_candidates);
02274 print(", %d (random)\n", ++num_candidates);
02275
02276 for (;;) {
02277 char ch;
02278
02279
02280 print("Enter selection (1-%d): ", num_candidates);
02281 chosen_num = -1;
02282 scanf(" %d", &chosen_num);
02283 do {
02284 ch = (char) getchar();
02285 } while ((ch != '\n') && (ch != EOF_AS_CHAR));
02286
02287 if (ch == EOF_AS_CHAR)
02288 clearerr(stdin);
02289
02290
02291
02292
02293
02294
02295 if ((chosen_num >= 1) && (chosen_num <= num_candidates))
02296 break;
02297 print("You must enter a number between 1 and %d\n", num_candidates);
02298 }
02299 if (current_agent(logging_to_file)) {
02300 char temp[SOAR_CDEFAULTASKCALLBACK_TEMP_SIZE];
02301 snprintf(temp, SOAR_CDEFAULTASKCALLBACK_TEMP_SIZE, "%d\n", chosen_num);
02302 temp[SOAR_CDEFAULTASKCALLBACK_TEMP_SIZE - 1] = 0;
02303 print_string_to_log_file_only(temp);
02304 }
02305
02306 switch (num_candidates - chosen_num) {
02307
02308 case 2:
02309 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_FIRST);
02310 print("User-select mode changed to: first\n");
02311 *((soar_apiAskCallbackData *) call_data)->selection = ((soar_apiAskCallbackData *) call_data)->candidates;
02312 break;
02313
02314 case 1:
02315 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_LAST);
02316 print("User-select mode changed to: last\n");
02317 for (cand = ((soar_apiAskCallbackData *) call_data)->candidates;
02318 cand->next_candidate != NIL; cand = cand->next_candidate);
02319
02320 *((soar_apiAskCallbackData *) call_data)->selection = cand;
02321 break;
02322
02323 case 0:
02324 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_RANDOM);
02325 print("User-select mode changed to: random\n");
02326
02327 chosen_num = sys_random() % (num_candidates - 3);
02328
02329 cand = ((soar_apiAskCallbackData *) call_data)->candidates;
02330 while (chosen_num) {
02331 cand = cand->next_candidate;
02332 chosen_num--;
02333 }
02334 *((soar_apiAskCallbackData *) call_data)->selection = cand;
02335 break;
02336
02337 default:
02338 cand = ((soar_apiAskCallbackData *) call_data)->candidates;
02339 while (chosen_num > 1) {
02340 cand = cand->next_candidate;
02341 chosen_num--;
02342 }
02343 *((soar_apiAskCallbackData *) call_data)->selection = cand;
02344 }
02345
02346
02347 return;
02348 }