00001
00042 #include "soarkernel.h"
00043 #include <time.h>
00044 #include "soar_ecore_api.h"
00045 #include "soar_ecore_utils.h"
00046 #include "rete.h"
00047 #include "sysdep.h"
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 void soar_ecSetDefaultWmeDepth(int depth)
00069 {
00070
00071 current_agent(default_wme_depth) = depth;
00072
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 int soar_ecOpenLog(const char *filename, char *mode)
00085 {
00086
00087 FILE *f;
00088
00089 f = fopen(filename, mode);
00090
00091 if (!f) {
00092 return -1;
00093 }
00094
00095
00096 soar_cPushCallback(soar_agent,
00097 LOG_CALLBACK,
00098 (soar_callback_fn) cb_soar_PrintToFile, (soar_callback_data) f, (soar_callback_free_fn) fclose);
00099 soar_invoke_first_callback(soar_agent, LOG_CALLBACK, "**** log opened ****\n");
00100
00101 return 0;
00102
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 int soar_ecCloseLog()
00115 {
00116
00117 if (soar_exists_callback(soar_agent, LOG_CALLBACK)) {
00118 soar_invoke_first_callback(soar_agent, LOG_CALLBACK, "\n**** log closed ****\n");
00119 soar_cPopCallback(soar_agent, LOG_CALLBACK);
00120
00121 return 0;
00122 }
00123
00124 return -1;
00125
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 #ifdef USE_CAPTURE_REPLAY
00138 int soar_ecCaptureInput(const char *filename)
00139 {
00140
00141 FILE *f;
00142
00143 if (filename == NIL) {
00144
00145 if (!current_agent(capture_fileID)) {
00146 return -1;
00147 }
00148 fclose(current_agent(capture_fileID));
00149 current_agent(capture_fileID) = NIL;
00150 return 0;
00151 } else {
00152 if (current_agent(capture_fileID)) {
00153 return -2;
00154 }
00155 f = fopen(filename, "w");
00156 if (!f) {
00157 return -3;
00158 } else {
00159 current_agent(capture_fileID) = f;
00160 fprintf(f, "##soar captured input file.\n");
00161 return 0;
00162 }
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 int soar_ecReplayInput(const char *filename)
00176 {
00177
00178 if (filename == NIL) {
00179 soar_cRemoveInputFunction(soar_agent, "replay-input");
00180
00181 } else {
00182
00183
00184 long begin, end;
00185 char input[1024];
00186 char id[1024];
00187 char attr[1024];
00188 char value[1024];
00189 int action;
00190 int numargs, cycle;
00191 int hashfreq, lasthash;
00192 unsigned long old_timetag, tt;
00193 int ndc;
00194 captured_action *c_action = NIL;
00195 int last_dc;
00196 int actions_in_dc = 0;
00197 int i;
00198 FILE *f;
00199 char header[80];
00200 soarapi_wme *sapiw;
00201
00202 f = fopen(filename, "r");
00203 if (!f) {
00204 return -1;
00205 } else {
00206 fgets(header, 28, f);
00207 if (strcmp(header, "##soar captured input file.") != 0) {
00208 return -2;
00209 }
00210
00211
00212
00213 soar_cAddInputFunction(soar_agent, replay_input_wme, NULL, NULL, "replay-input");
00214
00215 ndc = -1;
00216 tt = 1;
00217 begin = ftell(f);
00218 while (!feof(f)) {
00219 numargs = fscanf(f, "%i : %*d : %*s : %ld", &cycle, &old_timetag);
00220 if (old_timetag > tt)
00221 tt = old_timetag;
00222 if (cycle > ndc)
00223 ndc = cycle;
00224 fgets(input, 1024, f);
00225 }
00226
00227 end = ftell(f);
00228
00229 hashfreq = (end - begin) / 10;
00230 lasthash = 0;
00231
00232
00233 current_agent(replay_timetags) = (unsigned long *) allocate_memory(tt * sizeof(tt),
00234 current_agent(memory_for_usage)
00235 [MISCELLANEOUS_MEM_USAGE]);
00236
00237 current_agent(dc_to_replay) = ndc;
00238 current_agent(replay_actions) = (captured_action **) allocate_memory(((ndc +
00239 1) * sizeof(captured_action *)),
00240 current_agent(memory_for_usage)
00241 [MISCELLANEOUS_MEM_USAGE]);
00242
00243 for (i = 0; i < ndc; i++) {
00244 current_agent(replay_actions)[i] = NULL;
00245 }
00246
00247 fseek(f, begin, SEEK_SET);
00248
00249
00250 last_dc = -1;
00251 while (!feof(f)) {
00252 numargs = fscanf(f, "%i : %i : %*s :", &cycle, &action);
00253
00254 if (numargs < 2)
00255 break;
00256
00257 begin = ftell(f);
00258 if (begin / hashfreq > lasthash) {
00259 lasthash = begin / hashfreq;
00260 print("+");
00261 }
00262
00263 if (cycle != last_dc) {
00264 current_agent(replay_actions)[cycle] =
00265 (captured_action *) allocate_memory(sizeof(captured_action),
00266 current_agent(memory_for_usage)[MISCELLANEOUS_MEM_USAGE]);
00267 c_action = current_agent(replay_actions)[cycle];
00268
00269 if (current_agent(soar_verbose_flag) && last_dc != -1) {
00270 print(" -- (%d actions)\n", actions_in_dc);
00271 }
00272
00273 actions_in_dc = 1;
00274 last_dc = cycle;
00275 c_action->next = NULL;
00276
00277 if (current_agent(soar_verbose_flag))
00278 print("Building Actions for Decision Cycle %d\n", cycle);
00279
00280 } else {
00281 c_action->next = (captured_action *)
00282 allocate_memory(sizeof(captured_action),
00283 current_agent(memory_for_usage)[MISCELLANEOUS_MEM_USAGE]);
00284
00285 c_action = c_action->next;
00286 c_action->next = NULL;
00287 actions_in_dc++;
00288 }
00289
00290 c_action->dc = cycle;
00291 c_action->action = action;
00292
00293 switch (action) {
00294
00295 case ADD_WME:
00296 if (current_agent(soar_verbose_flag))
00297 print(" -- Reading ADD Wme Action\n");
00298
00299 fscanf(f, "%ld : %s %s %s", &old_timetag, id, attr, value);
00300
00301 c_action->args = malloc(sizeof(soarapi_wme));
00302 sapiw = (soarapi_wme *) c_action->args;
00303
00304 sapiw->id = savestring(id);
00305 sapiw->attr = savestring(attr);
00306 sapiw->value = savestring(value);
00307 sapiw->timetag = old_timetag;
00308
00309 break;
00310
00311 case REMOVE_WME:
00312 if (current_agent(soar_verbose_flag))
00313 print(" -- Reading REMOVE Wme Action\n");
00314
00315 fscanf(f, " : %ld", &old_timetag);
00316 c_action->args = malloc(sizeof(soarapi_wme));
00317 ((soarapi_wme *) c_action->args)->timetag = old_timetag;
00318 break;
00319
00320 default:
00321 print("Warning: don't know what to do with an action type of %d\n", action);
00322 break;
00323
00324 }
00325 fgets(input, 1025, f);
00326
00327 }
00328 if (current_agent(soar_verbose_flag))
00329 print(" -- (%d actions)\n", actions_in_dc);
00330 }
00331 fclose(f);
00332 }
00333 return 0;
00334 }
00335 #endif
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 void soar_ecGDSPrint()
00347 {
00348 wme *w;
00349 Symbol *goal;
00350
00351 print("********************* Current GDS **************************\n");
00352 print("stepping thru all wmes in rete, looking for any that are in a gds...\n");
00353 for (w = current_agent(all_wmes_in_rete); w != NIL; w = w->rete_next) {
00354 if (w->gds) {
00355 if (w->gds->goal) {
00356 print_with_symbols(" For Goal %y ", w->gds->goal);
00357 } else {
00358 print(" Old GDS value ");
00359 }
00360 print("(%lu: ", w->timetag);
00361 print_with_symbols("%y ^%y %y", w->id, w->attr, w->value);
00362 if (w->acceptable)
00363 print_string(" +");
00364 print_string(")");
00365 print("\n");
00366 }
00367 }
00368 print("************************************************************\n");
00369 for (goal = current_agent(top_goal); goal != NIL; goal = goal->id.lower_goal) {
00370 print_with_symbols(" For Goal %y ", goal);
00371 if (goal->id.gds) {
00372
00373 print("\n");
00374 for (w = goal->id.gds->wmes_in_gds; w != NIL; w = w->gds_next) {
00375 print(" (%lu: ", w->timetag);
00376 print_with_symbols("%y ^%y %y", w->id, w->attr, w->value);
00377 if (w->acceptable)
00378 print_string(" +");
00379 print_string(")");
00380 print("\n");
00381 }
00382
00383 } else
00384 print(": No GDS for this goal.\n");
00385 }
00386
00387 print("************************************************************\n");
00388
00389 }
00390
00391
00392
00393 void soar_ecExplainChunkTrace(char *chunk_name)
00394 {
00395
00396 explain_chunk_str *chunk;
00397
00398 chunk = find_chunk(current_agent(explain_chunk_list), chunk_name);
00399
00400
00401 if (chunk)
00402 explain_trace_chunk(chunk);
00403 }
00404
00405 void soar_ecExplainChunkCondition(char *chunk_name, int cond_number)
00406 {
00407
00408 explain_chunk_str *chunk;
00409 condition *ground;
00410
00411 chunk = find_chunk(current_agent(explain_chunk_list), chunk_name);
00412
00413
00414 if (chunk == NULL)
00415 return;
00416
00417 ground = find_ground(chunk, cond_number);
00418 if (ground == NIL)
00419 return;
00420
00421 explain_trace(chunk_name, chunk->backtrace, ground);
00422 }
00423
00424 void soar_ecExplainChunkConditionList(char *chunk_name)
00425 {
00426
00427 explain_chunk_str *chunk;
00428 condition *cond, *ground;
00429 int i;
00430
00431 chunk = find_chunk(current_agent(explain_chunk_list), chunk_name);
00432
00433
00434 if (chunk == NULL)
00435 return;
00436
00437
00438
00439 print("(sp %s\n ", chunk->name);
00440 print_condition_list(chunk->conds, 2, FALSE);
00441 print("\n-->\n ");
00442 print_action_list(chunk->actions, 3, FALSE);
00443 print(")\n\n");
00444
00445
00446
00447 i = 0;
00448 ground = chunk->all_grounds;
00449
00450 for (cond = chunk->conds; cond != NIL; cond = cond->next) {
00451 i++;
00452 print(" %2d : ", i);
00453 print_condition(cond);
00454 while (get_printer_output_column() < COLUMNS_PER_LINE - 40)
00455 print(" ");
00456
00457 print(" Ground :");
00458 print_condition(ground);
00459 print("\n");
00460 ground = ground->next;
00461 }
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 void soar_ecPrintFiringsForProduction(const char *name)
00476 {
00477
00478 production *p;
00479
00480 p = name_to_production(name);
00481 if (p) {
00482 print("%6lu: %s\n", p->firing_count, name);
00483 } else {
00484 print("No production named %s", name);
00485 }
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 void soar_ecPrintTopProductionFirings(int n)
00499 {
00500 int i;
00501 long num_prods;
00502 production *((*all_prods)[]), **ap_item, *p;
00503
00504 num_prods = current_agent(num_productions_of_type)[DEFAULT_PRODUCTION_TYPE] +
00505 current_agent(num_productions_of_type)[USER_PRODUCTION_TYPE] +
00506 current_agent(num_productions_of_type)[CHUNK_PRODUCTION_TYPE];
00507
00508 if (num_prods == 0) {
00509 print("*** No productions Defined ***\n");
00510 return;
00511 }
00512
00513
00514 all_prods = allocate_memory(num_prods * sizeof(production *), MISCELLANEOUS_MEM_USAGE);
00515
00516
00517
00518 ap_item = &((*all_prods)[0]);
00519 for (p = current_agent(all_productions_of_type)[DEFAULT_PRODUCTION_TYPE]; p != NIL; p = p->next)
00520 *(ap_item++) = p;
00521 for (p = current_agent(all_productions_of_type)[USER_PRODUCTION_TYPE]; p != NIL; p = p->next)
00522 *(ap_item++) = p;
00523 for (p = current_agent(all_productions_of_type)[CHUNK_PRODUCTION_TYPE]; p != NIL; p = p->next)
00524 *(ap_item++) = p;
00525
00526
00527 if (n == 0) {
00528
00529 ap_item = &((*all_prods)[0]);
00530 for (i = 0; i < num_prods; i++) {
00531 if ((*ap_item)->firing_count == 0) {
00532 print_with_symbols("%y\n", (*ap_item)->name);
00533 }
00534 ap_item++;
00535 }
00536 } else {
00537
00538 qsort(all_prods, num_prods, sizeof(production *), compare_firing_counts);
00539
00540 if ((n < 0) || (n > num_prods)) {
00541 n = num_prods;
00542 }
00543
00544 ap_item = &((*all_prods)[num_prods - 1]);
00545 while (n) {
00546 print("%6lu: ", (*ap_item)->firing_count);
00547 print_with_symbols("%y\n", (*ap_item)->name);
00548 ap_item--;
00549 n--;
00550 }
00551 }
00552
00553
00554 free_memory(all_prods, MISCELLANEOUS_MEM_USAGE);
00555
00556 }
00557
00558 void soar_exPrintMemoryPoolStatistics(void)
00559 {
00560 memory_pool *p;
00561
00562 #ifdef MEMORY_POOL_STATS
00563 long total_items;
00564 #endif
00565
00566 print("Memory pool statistics:\n\n");
00567 #ifdef MEMORY_POOL_STATS
00568 print("Pool Name Used Items Free Items Item Size Total Bytes\n");
00569 print("--------------- ---------- ---------- --------- -----------\n");
00570 #else
00571 print("Pool Name Item Size Total Bytes\n");
00572 print("--------------- --------- -----------\n");
00573 #endif
00574
00575 for (p = current_agent(memory_pools_in_use); p != NIL; p = p->next) {
00576 print_string(p->name);
00577 print_spaces(MAX_POOL_NAME_LENGTH - strlen(p->name));
00578 #ifdef MEMORY_POOL_STATS
00579 print(" %10lu", p->used_count);
00580 total_items = p->num_blocks * p->items_per_block;
00581 print(" %10lu", total_items - p->used_count);
00582 #endif
00583 print(" %9lu", p->item_size);
00584 print(" %11lu\n", p->num_blocks * p->items_per_block * p->item_size);
00585 }
00586 }
00587
00588 void soar_ecPrintMemoryStatistics(void)
00589 {
00590 unsigned long total;
00591 int i;
00592
00593 total = 0;
00594 for (i = 0; i < NUM_MEM_USAGE_CODES; i++)
00595 total += current_agent(memory_for_usage)[i];
00596
00597 print("%8lu bytes total memory allocated\n", total);
00598 print("%8lu bytes statistics overhead\n", current_agent(memory_for_usage)[STATS_OVERHEAD_MEM_USAGE]);
00599 print("%8lu bytes for strings\n", current_agent(memory_for_usage)[STRING_MEM_USAGE]);
00600 print("%8lu bytes for hash tables\n", current_agent(memory_for_usage)[HASH_TABLE_MEM_USAGE]);
00601 print("%8lu bytes for various memory pools\n", current_agent(memory_for_usage)[POOL_MEM_USAGE]);
00602 print("%8lu bytes for miscellaneous other things\n", current_agent(memory_for_usage)[MISCELLANEOUS_MEM_USAGE]);
00603 }
00604
00605 void soar_ecPrintReteStatistics(void)
00606 {
00607
00608 #ifdef TOKEN_SHARING_STATS
00609 print("Token additions: %lu If no sharing: %lu\n",
00610 current_agent(token_additions), current_agent(token_additions_without_sharing));
00611 #endif
00612
00613 print_node_count_statistics();
00614 print_null_activation_stats();
00615 }
00616
00617 void soar_ecPrintSystemStatistics(void)
00618 {
00619
00620 unsigned long wme_changes;
00621
00622
00623 #ifndef NO_TIMING_STUFF
00624 double total_kernel_time, total_kernel_msec, derived_kernel_time, monitors_sum, input_function_time, input_phase_total_time, output_function_time, output_phase_total_time, determine_level_phase_total_time,
00625 preference_phase_total_time, wm_phase_total_time, decision_phase_total_time, derived_total_cpu_time;
00626
00627 #ifdef DETAILED_TIMING_STATS
00628 double match_time, match_msec;
00629 double ownership_time, chunking_time;
00630 double other_phase_kernel_time[6], other_total_kernel_time;
00631 #endif
00632 #endif
00633
00634
00635
00636 char hostname[MAX_LEXEME_LENGTH + 1];
00637 long current_time;
00638
00639 #if !defined (THINK_C) && !defined (__SC__) && !defined(MACINTOSH) && !defined(WIN32) && !defined(_WINDOWS)
00640 if (gethostname(hostname, MAX_LEXEME_LENGTH)) {
00641 #endif
00642
00643 strncpy(hostname, "[host name unknown]", MAX_LEXEME_LENGTH + 1);
00644 hostname[MAX_LEXEME_LENGTH] = 0;
00645
00646 #if !defined (THINK_C) && !defined (__SC__) && !defined(MACINTOSH) && !defined(WIN32) && !defined(_WINDOWS)
00647 }
00648 #endif
00649
00650 current_time = time(NULL);
00651
00652
00653
00654 #ifndef NO_TIMING_STUFF
00655 total_kernel_time = timer_value(¤t_agent(total_kernel_time));
00656 total_kernel_msec = total_kernel_time * 1000.0;
00657
00658
00659
00660
00661
00662
00663 #ifndef KERNEL_TIME_ONLY
00664 derived_kernel_time = timer_value(¤t_agent(decision_cycle_phase_timers[INPUT_PHASE]))
00665 + timer_value(¤t_agent(decision_cycle_phase_timers[DETERMINE_LEVEL_PHASE]))
00666 + timer_value(¤t_agent(decision_cycle_phase_timers[PREFERENCE_PHASE]))
00667 + timer_value(¤t_agent(decision_cycle_phase_timers[WM_PHASE]))
00668 + timer_value(¤t_agent(decision_cycle_phase_timers[OUTPUT_PHASE]))
00669 + timer_value(¤t_agent(decision_cycle_phase_timers[DECISION_PHASE]));
00670
00671 input_function_time = timer_value(¤t_agent(input_function_cpu_time));
00672
00673 output_function_time = timer_value(¤t_agent(output_function_cpu_time));
00674
00675
00676 monitors_sum = timer_value(¤t_agent(monitors_cpu_time[INPUT_PHASE]))
00677 + timer_value(¤t_agent(monitors_cpu_time[DETERMINE_LEVEL_PHASE]))
00678 + timer_value(¤t_agent(monitors_cpu_time[PREFERENCE_PHASE]))
00679 + timer_value(¤t_agent(monitors_cpu_time[WM_PHASE]))
00680 + timer_value(¤t_agent(monitors_cpu_time[OUTPUT_PHASE]))
00681 + timer_value(¤t_agent(monitors_cpu_time[DECISION_PHASE]));
00682
00683 derived_total_cpu_time = derived_kernel_time + monitors_sum + input_function_time + output_function_time;
00684
00685
00686 input_phase_total_time = timer_value(¤t_agent(decision_cycle_phase_timers[INPUT_PHASE]))
00687 + timer_value(¤t_agent(monitors_cpu_time[INPUT_PHASE]))
00688 + timer_value(¤t_agent(input_function_cpu_time));
00689
00690
00691 determine_level_phase_total_time = timer_value(¤t_agent(decision_cycle_phase_timers[DETERMINE_LEVEL_PHASE]))
00692 + timer_value(¤t_agent(monitors_cpu_time[DETERMINE_LEVEL_PHASE]));
00693
00694
00695
00696 preference_phase_total_time = timer_value(¤t_agent(decision_cycle_phase_timers[PREFERENCE_PHASE]))
00697 + timer_value(¤t_agent(monitors_cpu_time[PREFERENCE_PHASE]));
00698
00699
00700 wm_phase_total_time = timer_value(¤t_agent(decision_cycle_phase_timers[WM_PHASE]))
00701 + timer_value(¤t_agent(monitors_cpu_time[WM_PHASE]));
00702
00703
00704 output_phase_total_time = timer_value(¤t_agent(decision_cycle_phase_timers[OUTPUT_PHASE]))
00705 + timer_value(¤t_agent(monitors_cpu_time[OUTPUT_PHASE]))
00706 + timer_value(¤t_agent(output_function_cpu_time));
00707
00708
00709 decision_phase_total_time = timer_value(¤t_agent(decision_cycle_phase_timers[DECISION_PHASE]))
00710 + timer_value(¤t_agent(monitors_cpu_time[DECISION_PHASE]));
00711
00712
00713
00714
00715
00716 #ifdef DETAILED_TIMING_STATS
00717
00718 match_time = timer_value(¤t_agent(match_cpu_time[INPUT_PHASE]))
00719 + timer_value(¤t_agent(match_cpu_time[DETERMINE_LEVEL_PHASE]))
00720 + timer_value(¤t_agent(match_cpu_time[PREFERENCE_PHASE]))
00721 + timer_value(¤t_agent(match_cpu_time[WM_PHASE]))
00722 + timer_value(¤t_agent(match_cpu_time[OUTPUT_PHASE]))
00723 + timer_value(¤t_agent(match_cpu_time[DECISION_PHASE]));
00724
00725 match_msec = 1000 * match_time;
00726
00727 ownership_time = timer_value(¤t_agent(ownership_cpu_time[INPUT_PHASE]))
00728 + timer_value(¤t_agent(ownership_cpu_time[DETERMINE_LEVEL_PHASE]))
00729 + timer_value(¤t_agent(ownership_cpu_time[PREFERENCE_PHASE]))
00730 + timer_value(¤t_agent(ownership_cpu_time[WM_PHASE]))
00731 + timer_value(¤t_agent(ownership_cpu_time[OUTPUT_PHASE]))
00732 + timer_value(¤t_agent(ownership_cpu_time[DECISION_PHASE]));
00733
00734 chunking_time = timer_value(¤t_agent(chunking_cpu_time[INPUT_PHASE]))
00735 + timer_value(¤t_agent(chunking_cpu_time[DETERMINE_LEVEL_PHASE]))
00736 + timer_value(¤t_agent(chunking_cpu_time[PREFERENCE_PHASE]))
00737 + timer_value(¤t_agent(chunking_cpu_time[WM_PHASE]))
00738 + timer_value(¤t_agent(chunking_cpu_time[OUTPUT_PHASE]))
00739 + timer_value(¤t_agent(chunking_cpu_time[DECISION_PHASE]));
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 other_phase_kernel_time[INPUT_PHASE] = timer_value(¤t_agent(decision_cycle_phase_timers[INPUT_PHASE]))
00751 - timer_value(¤t_agent(match_cpu_time[INPUT_PHASE]))
00752 - timer_value(¤t_agent(ownership_cpu_time[INPUT_PHASE]))
00753 - timer_value(¤t_agent(chunking_cpu_time[INPUT_PHASE]));
00754
00755 other_phase_kernel_time[DETERMINE_LEVEL_PHASE] =
00756 timer_value(¤t_agent(decision_cycle_phase_timers[DETERMINE_LEVEL_PHASE]))
00757 - timer_value(¤t_agent(match_cpu_time[DETERMINE_LEVEL_PHASE]))
00758 - timer_value(¤t_agent(ownership_cpu_time[DETERMINE_LEVEL_PHASE]))
00759 - timer_value(¤t_agent(chunking_cpu_time[DETERMINE_LEVEL_PHASE]));
00760
00761 other_phase_kernel_time[PREFERENCE_PHASE] =
00762 timer_value(¤t_agent(decision_cycle_phase_timers[PREFERENCE_PHASE]))
00763 - timer_value(¤t_agent(match_cpu_time[PREFERENCE_PHASE]))
00764 - timer_value(¤t_agent(ownership_cpu_time[PREFERENCE_PHASE]))
00765 - timer_value(¤t_agent(chunking_cpu_time[PREFERENCE_PHASE]));
00766
00767 other_phase_kernel_time[WM_PHASE] = timer_value(¤t_agent(decision_cycle_phase_timers[WM_PHASE]))
00768 - timer_value(¤t_agent(match_cpu_time[WM_PHASE]))
00769 - timer_value(¤t_agent(ownership_cpu_time[WM_PHASE]))
00770 - timer_value(¤t_agent(chunking_cpu_time[WM_PHASE]));
00771
00772 other_phase_kernel_time[OUTPUT_PHASE] = timer_value(¤t_agent(decision_cycle_phase_timers[OUTPUT_PHASE]))
00773 - timer_value(¤t_agent(match_cpu_time[OUTPUT_PHASE]))
00774 - timer_value(¤t_agent(ownership_cpu_time[OUTPUT_PHASE]))
00775 - timer_value(¤t_agent(chunking_cpu_time[OUTPUT_PHASE]));
00776
00777 other_phase_kernel_time[DECISION_PHASE] = timer_value(¤t_agent(decision_cycle_phase_timers[DECISION_PHASE]))
00778 - timer_value(¤t_agent(match_cpu_time[DECISION_PHASE]))
00779 - timer_value(¤t_agent(ownership_cpu_time[DECISION_PHASE]))
00780 - timer_value(¤t_agent(chunking_cpu_time[DECISION_PHASE]));
00781
00782 other_total_kernel_time = other_phase_kernel_time[INPUT_PHASE]
00783 + other_phase_kernel_time[DETERMINE_LEVEL_PHASE]
00784 + other_phase_kernel_time[PREFERENCE_PHASE]
00785 + other_phase_kernel_time[WM_PHASE]
00786 + other_phase_kernel_time[OUTPUT_PHASE]
00787 + other_phase_kernel_time[DECISION_PHASE];
00788
00789 #endif
00790 #endif
00791 #endif
00792
00793
00794 print("Soar %s on %s at %s\n", soar_version_string, hostname, ctime((const time_t *) ¤t_time));
00795
00796 print("%lu productions (%lu default, %lu user, %lu chunks)\n",
00797 current_agent(num_productions_of_type)[DEFAULT_PRODUCTION_TYPE] +
00798 current_agent(num_productions_of_type)[USER_PRODUCTION_TYPE] +
00799 current_agent(num_productions_of_type)[CHUNK_PRODUCTION_TYPE],
00800 current_agent(num_productions_of_type)[DEFAULT_PRODUCTION_TYPE],
00801 current_agent(num_productions_of_type)[USER_PRODUCTION_TYPE],
00802 current_agent(num_productions_of_type)[CHUNK_PRODUCTION_TYPE]);
00803 print(" + %lu justifications\n", current_agent(num_productions_of_type)[JUSTIFICATION_PRODUCTION_TYPE]);
00804
00805
00806 #ifndef NO_TIMING_STUFF
00807
00808
00809
00810
00811
00812
00813 #ifndef KERNEL_TIME_ONLY
00814 print(" | Derived\n");
00815 print("Phases: Input DLP Pref W/M Output Decision | Totals\n");
00816 print("================================================================|===========\n");
00817
00818 print("Kernel: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00819 timer_value(¤t_agent(decision_cycle_phase_timers[INPUT_PHASE])),
00820 timer_value(¤t_agent(decision_cycle_phase_timers[DETERMINE_LEVEL_PHASE])),
00821 timer_value(¤t_agent(decision_cycle_phase_timers[PREFERENCE_PHASE])),
00822 timer_value(¤t_agent(decision_cycle_phase_timers[WM_PHASE])),
00823 timer_value(¤t_agent(decision_cycle_phase_timers[OUTPUT_PHASE])),
00824 timer_value(¤t_agent(decision_cycle_phase_timers[DECISION_PHASE])), derived_kernel_time);
00825
00826 #ifdef DETAILED_TIMING_STATS
00827
00828 print("==================== Detailed Timing Statistics ==============|===========\n");
00829
00830 print(" Match: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00831 timer_value(¤t_agent(match_cpu_time[INPUT_PHASE])),
00832 timer_value(¤t_agent(match_cpu_time[DETERMINE_LEVEL_PHASE])),
00833 timer_value(¤t_agent(match_cpu_time[PREFERENCE_PHASE])),
00834 timer_value(¤t_agent(match_cpu_time[WM_PHASE])),
00835 timer_value(¤t_agent(match_cpu_time[OUTPUT_PHASE])),
00836 timer_value(¤t_agent(match_cpu_time[DECISION_PHASE])), match_time);
00837
00838 print("Own'ship: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00839 timer_value(¤t_agent(ownership_cpu_time[INPUT_PHASE])),
00840 timer_value(¤t_agent(ownership_cpu_time[DETERMINE_LEVEL_PHASE])),
00841 timer_value(¤t_agent(ownership_cpu_time[PREFERENCE_PHASE])),
00842 timer_value(¤t_agent(ownership_cpu_time[WM_PHASE])),
00843 timer_value(¤t_agent(ownership_cpu_time[OUTPUT_PHASE])),
00844 timer_value(¤t_agent(ownership_cpu_time[DECISION_PHASE])), ownership_time);
00845
00846 print("Chunking: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00847 timer_value(¤t_agent(chunking_cpu_time[INPUT_PHASE])),
00848 timer_value(¤t_agent(chunking_cpu_time[DETERMINE_LEVEL_PHASE])),
00849 timer_value(¤t_agent(chunking_cpu_time[PREFERENCE_PHASE])),
00850 timer_value(¤t_agent(chunking_cpu_time[WM_PHASE])),
00851 timer_value(¤t_agent(chunking_cpu_time[OUTPUT_PHASE])),
00852 timer_value(¤t_agent(chunking_cpu_time[DECISION_PHASE])), chunking_time);
00853
00854 print(" Other: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00855 other_phase_kernel_time[INPUT_PHASE],
00856 other_phase_kernel_time[DETERMINE_LEVEL_PHASE],
00857 other_phase_kernel_time[PREFERENCE_PHASE],
00858 other_phase_kernel_time[WM_PHASE],
00859 other_phase_kernel_time[OUTPUT_PHASE], other_phase_kernel_time[DECISION_PHASE], other_total_kernel_time);
00860
00861
00862 print("Operand2: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00863 timer_value(¤t_agent(gds_cpu_time[INPUT_PHASE])),
00864 timer_value(¤t_agent(gds_cpu_time[DETERMINE_LEVEL_PHASE])),
00865 timer_value(¤t_agent(gds_cpu_time[PREFERENCE_PHASE])),
00866 timer_value(¤t_agent(gds_cpu_time[WM_PHASE])),
00867 timer_value(¤t_agent(gds_cpu_time[OUTPUT_PHASE])),
00868 timer_value(¤t_agent(gds_cpu_time[DECISION_PHASE])),
00869 timer_value(¤t_agent(gds_cpu_time[INPUT_PHASE])) +
00870 timer_value(¤t_agent(gds_cpu_time[DETERMINE_LEVEL_PHASE])) +
00871 timer_value(¤t_agent(gds_cpu_time[PREFERENCE_PHASE])) +
00872 timer_value(¤t_agent(gds_cpu_time[WM_PHASE])) +
00873 timer_value(¤t_agent(gds_cpu_time[OUTPUT_PHASE])) +
00874 timer_value(¤t_agent(gds_cpu_time[DECISION_PHASE])));
00875
00876
00877
00878 #endif
00879
00880 print("================================================================|===========\n");
00881 print("Input fn: %8.3f | %10.3f\n",
00882 input_function_time, input_function_time);
00883
00884 print("================================================================|===========\n");
00885 print("Outpt fn: %8.3f | %10.3f\n",
00886 output_function_time, output_function_time);
00887
00888 print("================================================================|===========\n");
00889 print("Callbcks: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n",
00890 timer_value(¤t_agent(monitors_cpu_time[INPUT_PHASE])),
00891 timer_value(¤t_agent(monitors_cpu_time[DETERMINE_LEVEL_PHASE])),
00892 timer_value(¤t_agent(monitors_cpu_time[PREFERENCE_PHASE])),
00893 timer_value(¤t_agent(monitors_cpu_time[WM_PHASE])),
00894 timer_value(¤t_agent(monitors_cpu_time[OUTPUT_PHASE])),
00895 timer_value(¤t_agent(monitors_cpu_time[DECISION_PHASE])), monitors_sum);
00896
00897 print("================================================================|===========\n");
00898 print("Derived---------------------------------------------------------+-----------\n");
00899 print("Totals: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f | %10.3f\n\n",
00900 input_phase_total_time,
00901 determine_level_phase_total_time,
00902 preference_phase_total_time,
00903 wm_phase_total_time, output_phase_total_time, decision_phase_total_time, derived_total_cpu_time);
00904
00905 if (!current_agent(stop_soar)) {
00906
00907
00908 stop_timer(¤t_agent(start_total_tv), ¤t_agent(total_cpu_time));
00909 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
00910 start_timer(¤t_agent(start_total_tv));
00911 start_timer(¤t_agent(start_kernel_tv));
00912 }
00913
00914 print("Values from single timers:\n");
00915 #endif
00916 #endif
00917 #ifndef NO_TIMING_STUFF
00918
00919 #ifdef WARN_IF_TIMERS_REPORT_ZERO
00920
00921
00922
00923
00924 if (!current_agent(warn_on_zero_timers))
00925 print(" Warning: one or more timers have reported zero during this run\n");
00926 #endif
00927
00928 #ifndef PII_TIMERS
00929 print(" Kernel CPU Time: %11.3f sec. \n", total_kernel_time);
00930 print(" Total CPU Time: %11.3f sec.\n\n", timer_value(¤t_agent(total_cpu_time)));
00931 #else
00932 print(" Using PII Timers ... Assuming Processor Speed of %d MHZ\n", MHZ);
00933 print(" Kernel CPU Time: %11.5f sec. \n", total_kernel_time);
00934 print(" Total CPU Time: %11.5f sec.\n\n", timer_value(¤t_agent(total_cpu_time)));
00935
00936 #endif
00937
00938 #ifdef COUNT_KERNEL_TIMER_STOPS
00939 print(" Kernel CPU Timer Stops: %d\n", current_agent(kernelTimerStops));
00940 print(" Non-Kernel Timer Stops: %d\n", current_agent(nonKernelTimerStops));
00941
00942 #endif
00943 #endif
00944
00945 #if !defined(NO_TIMING_STUFF)
00946 print("%lu decision cycles (%.3f msec/dc)\n",
00947 current_agent(d_cycle_count),
00948 current_agent(d_cycle_count) ? total_kernel_msec / current_agent(d_cycle_count) : 0.0);
00949 print("%lu elaboration cycles (%.3f ec's per dc, %.3f msec/ec)\n",
00950 current_agent(e_cycle_count),
00951 current_agent(d_cycle_count) ? (double) current_agent(e_cycle_count) / current_agent(d_cycle_count) : 0,
00952 current_agent(e_cycle_count) ? total_kernel_msec / current_agent(e_cycle_count) : 0);
00953
00954
00955 #ifndef SOAR_8_ONLY
00956 if (current_agent(operand2_mode))
00957 #endif
00958 print("%lu p-elaboration cycles (%.3f pe's per dc, %.3f msec/pe)\n",
00959 current_agent(pe_cycle_count),
00960 current_agent(d_cycle_count) ? (double) current_agent(pe_cycle_count) / current_agent(d_cycle_count) : 0,
00961 current_agent(pe_cycle_count) ? total_kernel_msec / current_agent(pe_cycle_count) : 0);
00962
00963 print("%lu production firings (%.3f pf's per ec, %.3f msec/pf)\n",
00964 current_agent(production_firing_count),
00965 current_agent(e_cycle_count) ? (double) current_agent(production_firing_count) /
00966 current_agent(e_cycle_count) : 0.0,
00967 current_agent(production_firing_count) ? total_kernel_msec / current_agent(production_firing_count) : 0.0);
00968
00969 #else
00970 print("%lu decision cycles\n", current_agent(d_cycle_count));
00971 print("%lu elaboration cycles \n", current_agent(e_cycle_count));
00972 print("%lu production firings \n", current_agent(production_firing_count));
00973 #endif
00974
00975 wme_changes = current_agent(wme_addition_count) + current_agent(wme_removal_count);
00976 print("%lu wme changes (%lu additions, %lu removals)\n",
00977 wme_changes, current_agent(wme_addition_count), current_agent(wme_removal_count));
00978 #ifdef DETAILED_TIMING_STATS
00979 print(" match time: %.3f msec/wm change\n", wme_changes ? match_msec / wme_changes : 0.0);
00980 #endif
00981
00982 print("WM size: %lu current, %.3f mean, %lu maximum\n",
00983 current_agent(num_wmes_in_rete),
00984 (current_agent(num_wm_sizes_accumulated) ?
00985 (current_agent(cumulative_wm_size) / current_agent(num_wm_sizes_accumulated)) :
00986 0.0), current_agent(max_wm_size));
00987
00988 #ifndef NO_TIMING_STUFF
00989 print("\n");
00990 print(" *** Time/<x> statistics use the total kernel time from a ***\n");
00991 print(" *** single kernel timer. Differences between this value ***\n");
00992 print(" *** and the derived total kernel time are expected. See ***\n");
00993 print(" *** help for the stats command for more information. ***\n");
00994 #endif
00995
00996 }
00997
00998 #ifdef DC_HISTOGRAM
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 int soar_ecPrintDCHistogram(void)
01014 {
01015
01016 double total_k_time;
01017 int i, end;
01018
01019 total_k_time = 0;
01020 end = current_agent(d_cycle_count) / current_agent(dc_histogram_freq);
01021 if (end > current_agent(dc_histogram_sz))
01022 end = current_agent(dc_histogram_sz);
01023
01024 print("------------- D.C. Histogram --------------\n");
01025 print("Each Bucket encapsulates %d decision cycles\n", current_agent(dc_histogram_freq));
01026 print("%d Buckets have been filled during %d decision cycles\n", end, current_agent(d_cycle_count));
01027 print("-------------------------------------------\n");
01028 print("Bucket\t1st DC\tTime\n");
01029 for (i = 0; i < end; i++) {
01030
01031 print("%d\t%d\t%8.5f\n", i, i * current_agent(dc_histogram_freq),
01032 timer_value(¤t_agent(dc_histogram_tv)[i]));
01033
01034 total_k_time += timer_value(¤t_agent(dc_histogram_tv)[i]);
01035 }
01036 print("Total Time In Buckets:\t%8.5f\n", total_k_time);
01037
01038 return SOAR_OK;
01039 }
01040 #endif
01041
01042 #ifdef KT_HISTOGRAM
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 int soar_ecPrintKTHistogram(void)
01058 {
01059 double total_k_time;
01060 int i, end;
01061
01062 total_k_time = 0;
01063 end = current_agent(d_cycle_count);
01064 if (end > current_agent(dc_histogram_sz))
01065 end = current_agent(dc_histogram_sz);
01066
01067 print("------------- K.T. Histogram --------------\n");
01068
01069 print("Bucket\tTime\n");
01070 for (i = 0; i < end; i++) {
01071
01072 print("%d\t%8.5f\n", i, timer_value(¤t_agent(kt_histogram_tv)[i]));
01073
01074 total_k_time += timer_value(¤t_agent(kt_histogram_tv)[i]);
01075 }
01076 print("Total Time In Buckets:\t%8.5f\n", total_k_time);
01077
01078 return SOAR_OK;
01079 }
01080 #endif
01081
01082 void soar_ecPrintMemories(int num_to_print, int to_print[])
01083 {
01084 int i, num_prods;
01085 production_memory_use *temp, *first, *tempnext;
01086 production *prod;
01087 production_memory_use *print_memories_insert_in_list();
01088
01089 print("\nMemory use for productions:\n\n");
01090
01091
01092 first = NULL;
01093 num_prods = 0;
01094
01095 for (i = 0; i < NUM_PRODUCTION_TYPES; i++)
01096 if (to_print[i])
01097 for (prod = current_agent(all_productions_of_type)[i]; prod != NIL; prod = prod->next) {
01098 temp = allocate_memory(sizeof(production_memory_use), MISCELLANEOUS_MEM_USAGE);
01099 temp->next = NULL;
01100 temp->name = prod->name;
01101
01102 temp->mem = count_rete_tokens_for_production(prod);
01103
01104 first = print_memories_insert_in_list(temp, first);
01105 num_prods++;
01106 }
01107
01108 i = 0;
01109 if (num_to_print < 0)
01110 num_to_print = num_prods;
01111
01112 for (temp = first; ((temp != NULL) && (i < num_to_print)); temp = tempnext) {
01113 print_with_symbols("%y: ", temp->name);
01114 print("%d\n", temp->mem);
01115 tempnext = temp->next;
01116 free_memory(temp, MISCELLANEOUS_MEM_USAGE);
01117 i++;
01118 }
01119 }
01120
01121 int soar_ecPrintAllProductionsOfType(int type, bool internal, bool print_fname, bool full_prod)
01122 {
01123
01124 production *prod;
01125
01126
01127
01128
01129
01130 if (type < 0 || type >= NUM_PRODUCTION_TYPES) {
01131 return -1;
01132 }
01133
01134 for (prod = current_agent(all_productions_of_type)[type]; prod != NIL && prod->next != NIL; prod = prod->next)
01135 ;
01136
01137 while (prod != NIL) {
01138
01139 if (!full_prod) {
01140 print_with_symbols("%y ", prod->name);
01141 }
01142 if (print_fname) {
01143 print_string("# sourcefile : ");
01144 if (prod->filename) {
01145 print_string(prod->filename);
01146 } else {
01147 print_string(" _unknown_ ");
01148 }
01149 }
01150 print("\n");
01151 if (full_prod) {
01152 print_production(prod, internal);
01153 print("\n");
01154 }
01155 prod = prod->prev;
01156 }
01157
01158 return 0;
01159 }
01160
01161 void soar_ecPrintAllProductionsWithInterruptSetting(enum soar_InterruptSetting interrupt_setting) {
01162 production *prod;
01163
01164
01165
01166
01167
01168 int type;
01169 for (type = 0; type < NUM_PRODUCTION_TYPES; type++) {
01170 for (prod = current_agent(all_productions_of_type)[type]; prod != NIL && prod->next != NIL; prod = prod->next)
01171 ;
01172
01173 while (prod != NIL) {
01174
01175
01176 if( (interrupt_setting == INTERRUPT_ON && prod->interrupt) || (interrupt_setting == INTERRUPT_OFF && !prod->interrupt) ) {
01177 print("%s\n", prod->name->var.name);
01178 }
01179
01180 prod = prod->prev;
01181 }
01182 }
01183 }
01184
01185 int soar_ecAddWmeFilter(const char *szId, const char *szAttr, const char *szValue, bool adds, bool removes)
01186 {
01187
01188 Symbol *id, *attr, *value;
01189 wme_filter *wf, *existing_wf;
01190 cons *c;
01191 int return_value;
01192
01193 id = NIL;
01194 attr = NIL;
01195 value = NIL;
01196 return_value = 0;
01197
01198 if (read_wme_filter_component(szId, &id)) {
01199 return_value = -1;
01200 goto error_out;
01201 }
01202 if (read_wme_filter_component(szAttr, &attr)) {
01203 return_value = -2;
01204 goto error_out;
01205 }
01206 if (read_wme_filter_component(szValue, &value)) {
01207 return_value = -3;
01208 goto error_out;
01209 }
01210
01211 if (id && attr && value) {
01212
01213 for (c = current_agent(wme_filter_list); c != NIL; c = c->rest) {
01214 existing_wf = (wme_filter *) c->first;
01215 if ((existing_wf->adds == adds) && (existing_wf->removes == removes)
01216 && (existing_wf->id == id) && (existing_wf->attr == attr)
01217 && (existing_wf->value == value)) {
01218
01219 print("Filter already exists.\n");
01220 return_value = -4;
01221 goto error_out;
01222 }
01223 }
01224
01225 wf = allocate_memory(sizeof(wme_filter), MISCELLANEOUS_MEM_USAGE);
01226 wf->id = id;
01227 wf->attr = attr;
01228 wf->value = value;
01229 wf->adds = adds;
01230 wf->removes = removes;
01231
01232
01233
01234
01235
01236
01237 push(wf, current_agent(wme_filter_list));
01238 return 0;
01239 }
01240 error_out:
01241
01242 if (id)
01243 symbol_remove_ref(id);
01244 if (attr)
01245 symbol_remove_ref(attr);
01246 if (value)
01247 symbol_remove_ref(value);
01248 return return_value;
01249 }
01250
01251 int soar_ecRemoveWmeFilter(const char *szId, const char *szAttr, const char *szValue, bool adds, bool removes)
01252 {
01253 Symbol *id, *attr, *value;
01254 wme_filter *wf;
01255 int return_value = -4;
01256 cons *c;
01257 cons **prev_cons_rest;
01258
01259 id = NIL;
01260 attr = NIL;
01261 value = NIL;
01262
01263 if (read_wme_filter_component(szId, &id)) {
01264 return_value = -1;
01265 goto clean_up;
01266 }
01267 if (read_wme_filter_component(szAttr, &attr)) {
01268 return_value = -2;
01269 goto clean_up;
01270 }
01271 if (read_wme_filter_component(szValue, &value)) {
01272 return_value = -3;
01273 goto clean_up;
01274 }
01275
01276 if (id && attr && value) {
01277 prev_cons_rest = ¤t_agent(wme_filter_list);
01278 for (c = current_agent(wme_filter_list); c != NIL; c = c->rest) {
01279 wf = (wme_filter *) c->first;
01280 if (((adds && wf->adds) || ((removes) && wf->removes))
01281 && (wf->id == id) && (wf->attr == attr) && (wf->value == value)) {
01282 *prev_cons_rest = c->rest;
01283 symbol_remove_ref(id);
01284 symbol_remove_ref(attr);
01285 symbol_remove_ref(value);
01286 free_memory(wf, MISCELLANEOUS_MEM_USAGE);
01287 free_cons(c);
01288 break;
01289 }
01290 prev_cons_rest = &(c->rest);
01291 }
01292 if (c != NIL)
01293 return_value = 0;
01294 }
01295
01296 clean_up:
01297
01298 if (id)
01299 symbol_remove_ref(id);
01300 if (attr)
01301 symbol_remove_ref(attr);
01302 if (value)
01303 symbol_remove_ref(value);
01304 return return_value;
01305 }
01306
01307 int soar_ecResetWmeFilters(bool adds, bool removes)
01308 {
01309 wme_filter *wf;
01310 cons *c;
01311 cons **prev_cons_rest;
01312 bool didRemoveSome;
01313
01314 didRemoveSome = FALSE;
01315 prev_cons_rest = ¤t_agent(wme_filter_list);
01316 for (c = current_agent(wme_filter_list); c != NIL; c = c->rest) {
01317 wf = (wme_filter *) c->first;
01318 if ((adds && wf->adds) || (removes && wf->removes)) {
01319 *prev_cons_rest = c->rest;
01320 print_with_symbols("Removed: (%y ^%y %y) ", wf->id, wf->attr, wf->value);
01321 print("%s %s\n", (wf->adds ? "adds" : ""), (wf->removes ? "removes" : ""));
01322 symbol_remove_ref(wf->id);
01323 symbol_remove_ref(wf->attr);
01324 symbol_remove_ref(wf->value);
01325 free_memory(wf, MISCELLANEOUS_MEM_USAGE);
01326 free_cons(c);
01327 didRemoveSome = TRUE;
01328 }
01329 prev_cons_rest = &(c->rest);
01330 }
01331 if (didRemoveSome)
01332 return 0;
01333 else
01334 return -1;
01335 }
01336
01337 void soar_ecListWmeFilters(bool adds, bool removes)
01338 {
01339 wme_filter *wf;
01340 cons *c;
01341
01342 for (c = current_agent(wme_filter_list); c != NIL; c = c->rest) {
01343 wf = (wme_filter *) c->first;
01344 if ((adds && wf->adds) || (removes && wf->removes)) {
01345 print_with_symbols("wme filter: (%y ^%y %y) ", wf->id, wf->attr, wf->value);
01346
01347 print("%s %s\n", (wf->adds ? "adds" : ""), (wf->removes ? "removes" : ""));
01348 }
01349 }
01350 }
01351
01352 int soar_ecSp(const char *rule, const char *sourceFile)
01353 {
01354
01355 production *p;
01356
01357
01358
01359
01360
01361 soar_alternate_input(soar_agent, rule, ") ", TRUE);
01362 set_lexer_allow_ids(FALSE);
01363 get_lexeme();
01364 p = parse_production();
01365 set_lexer_allow_ids(TRUE);
01366 soar_alternate_input(soar_agent, NIL, NIL, FALSE);
01367
01368 if (p) {
01369
01370 if (sourceFile != NULL) {
01371 p->filename = make_memory_block_for_string(sourceFile);
01372 }
01373
01374 if (current_agent(sysparams)[TRACE_LOADING_SYSPARAM])
01375 print("*");
01376
01377
01378 if (p->type == CHUNK_PRODUCTION_TYPE) {
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389 char *chunk_name, *c;
01390 unsigned long this_chunk_count;
01391
01392 chunk_name = p->name->sc.name;
01393 c = chunk_name;
01394 while (*c && (*c != '*'))
01395 c++;
01396 do
01397 c--;
01398 while (*c && (*c != '-'));
01399 c++;
01400 if (sscanf(c, "%lu", &this_chunk_count) != 1)
01401 print("Warning: failed to extract chunk_num from chunk \"%s\"\n", chunk_name);
01402 else if (this_chunk_count > current_agent(chunk_count)) {
01403 current_agent(chunk_count) = this_chunk_count;
01404 print("updated chunk_num=%lu\n", current_agent(chunk_count));
01405 }
01406 }
01407
01408
01409 return 0;
01410 } else {
01411
01412
01413
01414
01415
01416 return -1;
01417
01418
01419 }
01420 }
01421
01422 void soar_ecPrintInternalSymbols(void)
01423 {
01424 print_string("\n--- Symbolic Constants: ---\n");
01425 do_for_all_items_in_hash_table(current_agent(sym_constant_hash_table), print_sym);
01426 print_string("\n--- Integer Constants: ---\n");
01427 do_for_all_items_in_hash_table(current_agent(int_constant_hash_table), print_sym);
01428 print_string("\n--- Floating-Point Constants: ---\n");
01429 do_for_all_items_in_hash_table(current_agent(float_constant_hash_table), print_sym);
01430 print_string("\n--- Identifiers: ---\n");
01431 do_for_all_items_in_hash_table(current_agent(identifier_hash_table), print_sym);
01432 print_string("\n--- Variables: ---\n");
01433 do_for_all_items_in_hash_table(current_agent(variable_hash_table), print_sym);
01434 }
01435
01436 int soar_ecPrintPreferences(char *szId, char *szAttr, bool print_prod, wme_trace_type wtt)
01437 {
01438
01439 Symbol *id, *attr;
01440 slot *s;
01441 preference *p;
01442 int i;
01443
01444 if (read_id_or_context_var_from_string(szId, &id) == SOAR_ERROR) {
01445 print("Could not find the id '%s'\n", szId);
01446 return -1;
01447 }
01448 if (read_attribute_from_string(id, szAttr, &attr) == SOAR_ERROR) {
01449 print("Could not find the id,attribute pair: %s ^%s\n", szId, szAttr);
01450 return -2;
01451 }
01452
01453 s = find_slot(id, attr);
01454 if (!s) {
01455 print("There are no preferences for %s ^%s.", szId, szAttr);
01456 return -3;
01457 }
01458
01459 print_with_symbols("Preferences for %y ^%y:\n", id, attr);
01460
01461 for (i = 0; i < NUM_PREFERENCE_TYPES; i++) {
01462 if (s->preferences[i]) {
01463 print("\n%ss:\n", preference_name[i]);
01464 for (p = s->preferences[i]; p; p = p->next) {
01465 print_preference_and_source(p, print_prod, wtt);
01466 }
01467 }
01468 }
01469
01470 return 0;
01471 }
01472
01473 void soar_ecPrintProductionsBeingTraced()
01474 {
01475
01476 cons *c;
01477
01478 for (c = current_agent(productions_being_traced); c != NIL; c = c->rest)
01479 print_with_symbols(" %y\n", ((production *) (c->first))->name);
01480 }
01481
01482 void soar_ecStopAllProductionTracing()
01483 {
01484
01485 cons *c, *next;
01486
01487
01488
01489
01490
01491
01492 for (c = current_agent(productions_being_traced); c != NIL; c = next) {
01493 production *prod;
01494
01495 next = c->rest;
01496 prod = current_agent(productions_being_traced)->first;
01497 remove_pwatch(prod);
01498 }
01499
01500 }
01501
01502 int soar_ecBeginTracingProductions(int n, const char **names)
01503 {
01504
01505 int i;
01506 production *prod;
01507
01508 for (i = 0; i < n; i++) {
01509
01510 prod = name_to_production(names[i]);
01511 if (prod) {
01512 add_pwatch(prod);
01513 } else {
01514 print("No Production named %s", names[i]);
01515 return (-1 - i);
01516 }
01517 }
01518 return 0;
01519 }
01520
01521 int soar_ecStopTracingProductions(int n, const char **names)
01522 {
01523
01524 int i;
01525 production *prod;
01526
01527 for (i = 0; i < n; i++) {
01528
01529 prod = name_to_production(names[i]);
01530 if (prod) {
01531 remove_pwatch(prod);
01532 } else {
01533 print("No Production named %s", names[i]);
01534 return (-1 - i);
01535 }
01536 }
01537 return 0;
01538 }
01539
01540 void soar_ecPrintMatchSet(wme_trace_type wtt, ms_trace_type mst)
01541 {
01542 print_match_set(wtt, mst);
01543 }
01544
01545 int soar_ecPrintMatchInfoForProduction(const char *name, wme_trace_type wtt)
01546 {
01547 production *p;
01548 struct rete_node_struct *p_node;
01549
01550 p = name_to_production(name);
01551 if (!p) {
01552 return -1;
01553 }
01554
01555 p_node = p->p_node;
01556 print_partial_match_information(p_node, wtt);
01557 return 0;
01558 }
01559
01560 void soar_ecPrintMemoryPoolStatistics(void)
01561 {
01562 memory_pool *p;
01563 #ifdef MEMORY_POOL_STATS
01564 long total_items;
01565 #endif
01566
01567 print("Memory pool statistics:\n\n");
01568 #ifdef MEMORY_POOL_STATS
01569 print("Pool Name Used Items Free Items Item Size Total Bytes\n");
01570 print("--------------- ---------- ---------- --------- -----------\n");
01571 #else
01572 print("Pool Name Item Size Total Bytes\n");
01573 print("--------------- --------- -----------\n");
01574 #endif
01575
01576 for (p = current_agent(memory_pools_in_use); p != NIL; p = p->next) {
01577 print_string(p->name);
01578 print_spaces(MAX_POOL_NAME_LENGTH - strlen(p->name));
01579 #ifdef MEMORY_POOL_STATS
01580 print(" %10lu", p->used_count);
01581 total_items = p->num_blocks * p->items_per_block;
01582 print(" %10lu", total_items - p->used_count);
01583 #endif
01584 print(" %9lu", p->item_size);
01585 print(" %11lu\n", p->num_blocks * p->items_per_block * p->item_size);
01586 }
01587 }
01588
01589 #ifdef ATTENTION_LAPSE
01590 void soar_ecPrintAttentionLapseSettings(void)
01591 {
01592 print("Current attention-lapse setting:\n");
01593 print(" %s\n", current_agent(sysparams)[ATTENTION_LAPSE_ON_SYSPARAM] ? "-on" : "-off");
01594
01595 }
01596 #endif
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608 int soar_ecWatchLevel(int level)
01609 {
01610
01611 if (level > 5 || level < 0)
01612 return -1;
01613
01614 set_sysparam(TRACE_CONTEXT_DECISIONS_SYSPARAM, FALSE);
01615 set_sysparam(TRACE_PHASES_SYSPARAM, FALSE);
01616 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, FALSE);
01617 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, FALSE);
01618 set_sysparam(TRACE_FIRINGS_OF_CHUNKS_SYSPARAM, FALSE);
01619 set_sysparam(TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM, FALSE);
01620 set_sysparam(TRACE_WM_CHANGES_SYSPARAM, FALSE);
01621 set_sysparam(TRACE_FIRINGS_PREFERENCES_SYSPARAM, FALSE);
01622 set_sysparam(TRACE_OPERAND2_REMOVALS_SYSPARAM, FALSE);
01623
01624 switch (level) {
01625 case 0:
01626
01627 set_sysparam(TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM, NONE_WME_TRACE);
01628 set_sysparam(TRACE_CHUNK_NAMES_SYSPARAM, FALSE);
01629 set_sysparam(TRACE_JUSTIFICATION_NAMES_SYSPARAM, FALSE);
01630 set_sysparam(TRACE_CHUNKS_SYSPARAM, FALSE);
01631 set_sysparam(TRACE_JUSTIFICATIONS_SYSPARAM, FALSE);
01632 set_sysparam(TRACE_OPERAND2_REMOVALS_SYSPARAM, FALSE);
01633 break;
01634
01635 case 5:
01636
01637 set_sysparam(TRACE_FIRINGS_PREFERENCES_SYSPARAM, TRUE);
01638
01639 case 4:
01640
01641 set_sysparam(TRACE_WM_CHANGES_SYSPARAM, TRUE);
01642
01643 case 3:
01644
01645 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, TRUE);
01646 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, TRUE);
01647 set_sysparam(TRACE_FIRINGS_OF_CHUNKS_SYSPARAM, TRUE);
01648 set_sysparam(TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM, TRUE);
01649
01650 case 2:
01651
01652 set_sysparam(TRACE_PHASES_SYSPARAM, TRUE);
01653
01654 case 1:
01655
01656 set_sysparam(TRACE_CONTEXT_DECISIONS_SYSPARAM, TRUE);
01657 }
01658
01659 return 0;
01660 }