00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "soarkernel.h"
00044 #include <ctype.h>
00045 #include <errno.h>
00046
00047 #include <stdlib.h>
00048 #include <string.h>
00049 #include <time.h>
00050 #include <stdarg.h>
00051
00052 #include "soarapi.h"
00053 #include "soarapiUtils.h"
00054
00055 #define MAXPATHLEN 1024
00056
00057
00058 #define dealloc_and_return(x,y) { deallocate_test(x) ; return (y) ; }
00059
00060 char *preference_name[] = {
00061 "acceptable",
00062 "require",
00063 "reject",
00064 "prohibit",
00065 "reconsider",
00066 "unary indifferent",
00067 "unary parallel",
00068 "best",
00069 "worst",
00070 "binary indifferent",
00071 "binary parallel",
00072 "better",
00073 "worse"
00074 };
00075
00076 int getInt(const char *string, int *i)
00077 {
00078
00079 long l;
00080 char *c;
00081
00082 if (*string == '\0')
00083 return SOAR_ERROR;
00084
00085 l = strtol(string, &c, 10);
00086
00087 if (*c == '\0') {
00088 *i = (int) l;
00089 return SOAR_OK;
00090 }
00091
00092 return SOAR_ERROR;
00093 }
00094
00095 Symbol *space_to_remove_from_cfps;
00096
00097 bool cfps_removal_test_function(cons * c)
00098 {
00099 return (bool) (c->first == space_to_remove_from_cfps);
00100 }
00101
00102 void do_print_for_production_name(const char *prod_name, bool internal, bool print_filename, bool full_prod)
00103 {
00104 Symbol *sym;
00105
00106 sym = find_sym_constant(current_agent(lexeme).string);
00107 if (sym && sym->sc.production) {
00108
00109 if (print_filename) {
00110 if (full_prod)
00111 print_string("# sourcefile : ");
00112 print("%s\n", sym->sc.production->filename);
00113 }
00114
00115 if ((full_prod) || (!print_filename)) {
00116 print_production(sym->sc.production, internal);
00117 print("\n");
00118 }
00119 } else {
00120 print("No production named %s\n", prod_name);
00121 print_location_of_most_recent_lexeme();
00122 }
00123 }
00124
00125 void do_print_for_wme(wme * w, int depth, bool internal)
00126 {
00127 tc_number tc;
00128
00129 if (internal && (depth == 0)) {
00130 print_wme(w);
00131
00132 } else {
00133 tc = get_new_tc_number();
00134 print_augs_of_id(w->id, depth, internal, 0, tc);
00135 }
00136 }
00137
00138 void execute_go_selection(agent * the_agent,
00139 long go_number,
00140 enum go_type_enum go_type, Symbol * go_slot_attr, goal_stack_level go_slot_level)
00141 {
00142 switch (go_type) {
00143 case GO_PHASE:
00144 run_for_n_phases(go_number);
00145 break;
00146 case GO_ELABORATION:
00147 run_for_n_elaboration_cycles(go_number);
00148 break;
00149 case GO_DECISION:
00150 run_for_n_decision_cycles(go_number);
00151 break;
00152 case GO_STATE:
00153 run_for_n_selections_of_slot(go_number, the_agent->state_symbol);
00154 break;
00155 case GO_OPERATOR:
00156 run_for_n_selections_of_slot(go_number, the_agent->operator_symbol);
00157 break;
00158 case GO_SLOT:
00159 run_for_n_selections_of_slot_at_level(go_number, go_slot_attr, go_slot_level);
00160 break;
00161 case GO_OUTPUT:
00162 run_for_n_modifications_of_output(go_number);
00163 break;
00164 }
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 void print_current_learn_settings(void)
00205 {
00206 print("Current learn settings:\n");
00207
00208 if ((!current_agent(sysparams)[LEARNING_ONLY_SYSPARAM]) && (!current_agent(sysparams)[LEARNING_EXCEPT_SYSPARAM]))
00209 print(" %s\n", current_agent(sysparams)[LEARNING_ON_SYSPARAM] ? "-on" : "-off");
00210 else
00211 print(" %s\n", current_agent(sysparams)[LEARNING_ONLY_SYSPARAM] ? "-only" : "-except");
00212
00213
00214 print(" %s\n", current_agent(sysparams)[LEARNING_ALL_GOALS_SYSPARAM] ? "-all-levels" : "-bottom-up");
00215
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 void print_multi_attribute_symbols(void)
00235 {
00236 multi_attribute *m = current_agent(multi_attributes);
00237
00238 print("\n");
00239 if (!m) {
00240 print("No multi-attributes declared for this agent.\n");
00241 } else {
00242 print("Value\tSymbol\n");
00243 while (m) {
00244 print("%ld\t%s\n", m->value, symbol_to_string(m->symbol, TRUE, NIL, 0));
00245 m = m->next;
00246 }
00247 }
00248 print("\n");
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 int read_pref_detail_from_string(const char *the_lexeme, bool * print_productions, wme_trace_type * wtt)
00272 {
00273 if (!strncmp(the_lexeme, "-none", 3)
00274 || !strcmp(the_lexeme, "0")) {
00275 *print_productions = FALSE;
00276 *wtt = NONE_WME_TRACE;
00277 } else if (!strncmp(the_lexeme, "-names", 3)
00278 || !strcmp(the_lexeme, "1")) {
00279 *print_productions = TRUE;
00280 *wtt = NONE_WME_TRACE;
00281 } else if (!strncmp(the_lexeme, "-timetags", 2)
00282 || !strcmp(the_lexeme, "2")) {
00283 *print_productions = TRUE;
00284 *wtt = TIMETAG_WME_TRACE;
00285 } else if (!strncmp(the_lexeme, "-wmes", 2)
00286 || !strcmp(the_lexeme, "3")) {
00287 *print_productions = TRUE;
00288 *wtt = FULL_WME_TRACE;
00289 } else {
00290 return SOAR_ERROR;
00291 }
00292 return SOAR_OK;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 int read_pattern_component(Symbol ** dest_sym)
00312 {
00313
00314
00315 if (strcmp(current_agent(lexeme).string, "*") == 0)
00316 return 1;
00317 switch (current_agent(lexeme).type) {
00318 case SYM_CONSTANT_LEXEME:
00319 *dest_sym = find_sym_constant(current_agent(lexeme).string);
00320 return 2;
00321 case INT_CONSTANT_LEXEME:
00322 *dest_sym = find_int_constant(current_agent(lexeme).int_val);
00323 return 2;
00324 case FLOAT_CONSTANT_LEXEME:
00325 *dest_sym = find_float_constant(current_agent(lexeme).float_val);
00326 return 2;
00327 case IDENTIFIER_LEXEME:
00328 *dest_sym = find_identifier(current_agent(lexeme).id_letter, current_agent(lexeme).id_number);
00329 return 2;
00330 case VARIABLE_LEXEME:
00331 *dest_sym = read_identifier_or_context_variable();
00332 if (*dest_sym)
00333 return 2;
00334 return 0;
00335 default:
00336 print("Expected identifier or constant in wme pattern\n");
00337 print_location_of_most_recent_lexeme();
00338 return 0;
00339 }
00340 }
00341
00342 list *read_pattern_and_get_matching_wmes(void)
00343 {
00344 int parentheses_level;
00345 list *wmes;
00346 wme *w;
00347 Symbol *id, *attr, *value;
00348 int id_result, attr_result, value_result;
00349 bool acceptable;
00350
00351 if (current_agent(lexeme).type != L_PAREN_LEXEME) {
00352 print("Expected '(' to begin wme pattern not string '%s' or char '%c'\n",
00353 current_agent(lexeme).string, current_agent(current_char));
00354 print_location_of_most_recent_lexeme();
00355 return NIL;
00356 }
00357 parentheses_level = current_lexer_parentheses_level();
00358
00359 get_lexeme();
00360 id_result = read_pattern_component(&id);
00361 if (!id_result) {
00362 skip_ahead_to_balanced_parentheses(parentheses_level - 1);
00363 return NIL;
00364 }
00365 get_lexeme();
00366 if (current_agent(lexeme).type != UP_ARROW_LEXEME) {
00367 print("Expected ^ in wme pattern\n");
00368 print_location_of_most_recent_lexeme();
00369 skip_ahead_to_balanced_parentheses(parentheses_level - 1);
00370 return NIL;
00371 }
00372 get_lexeme();
00373 attr_result = read_pattern_component(&attr);
00374 if (!attr_result) {
00375 skip_ahead_to_balanced_parentheses(parentheses_level - 1);
00376 return NIL;
00377 }
00378 get_lexeme();
00379 value_result = read_pattern_component(&value);
00380 if (!value_result) {
00381 skip_ahead_to_balanced_parentheses(parentheses_level - 1);
00382 return NIL;
00383 }
00384 get_lexeme();
00385 if (current_agent(lexeme).type == PLUS_LEXEME) {
00386 acceptable = TRUE;
00387 get_lexeme();
00388 } else {
00389 acceptable = FALSE;
00390 }
00391 if (current_agent(lexeme).type != R_PAREN_LEXEME) {
00392 print("Expected ')' to end wme pattern\n");
00393 print_location_of_most_recent_lexeme();
00394 skip_ahead_to_balanced_parentheses(parentheses_level - 1);
00395 return NIL;
00396 }
00397 {
00398 int i = 0;
00399 wmes = NIL;
00400 for (w = current_agent(all_wmes_in_rete); w != NIL; w = w->rete_next) {
00401 if ((id_result == 1) || (id == w->id))
00402 if ((attr_result == 1) || (attr == w->attr))
00403 if ((value_result == 1) || (value == w->value))
00404 if (acceptable == w->acceptable) {
00405 push(w, wmes);
00406 i++;
00407 }
00408
00409 }
00410
00411 }
00412 return wmes;
00413 }
00414
00415 void cb_appendToSoarResultResult(agent * the_agent, soar_callback_data data, soar_call_data call_data)
00416 {
00417
00418 the_agent = the_agent;
00419
00420 appendSoarResultResult(((soarResult *) data), (char *) call_data);
00421
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 bool soar_agent_already_defined(char *name)
00443 {
00444 cons *c;
00445 agent *the_agent;
00446
00447 for (c = all_soar_agents; c != NIL; c = c->rest) {
00448 the_agent = (agent *) c->first;
00449 if (!strcmp(the_agent->name, name)) {
00450 return TRUE;
00451 }
00452 }
00453
00454 return FALSE;
00455 }
00456
00457 typedef struct binding_structure {
00458 Symbol *from, *to;
00459 } Binding;
00460
00461 Symbol *get_binding(Symbol * f, list * bindings)
00462 {
00463 cons *c;
00464
00465 for (c = bindings; c != NIL; c = c->rest) {
00466 if (((Binding *) c->first)->from == f)
00467 return ((Binding *) c->first)->to;
00468 }
00469 return NIL;
00470 }
00471
00472 void reset_old_binding_point(list ** bindings, list ** current_binding_point)
00473 {
00474 cons *c, *c_next;
00475
00476 c = *bindings;
00477 while (c != *current_binding_point) {
00478 c_next = c->rest;
00479 free_memory(c->first, MISCELLANEOUS_MEM_USAGE);
00480 free_cons(c);
00481 c = c_next;
00482 }
00483
00484 bindings = current_binding_point;
00485 }
00486
00487 void free_binding_list(list * bindings)
00488 {
00489 cons *c;
00490
00491 for (c = bindings; c != NIL; c = c->rest)
00492 free_memory(c->first, MISCELLANEOUS_MEM_USAGE);
00493 free_list(bindings);
00494 }
00495
00496 void print_binding_list(list * bindings)
00497 {
00498 cons *c;
00499
00500 for (c = bindings; c != NIL; c = c->rest)
00501 print_with_symbols(" (%y -> %y)\n", ((Binding *) c->first)->from, ((Binding *) c->first)->to);
00502 }
00503
00504 bool symbols_are_equal_with_bindings(Symbol * s1, Symbol * s2, list ** bindings)
00505 {
00506 Binding *b;
00507 Symbol *bvar;
00508
00509
00510 if ((s1 == s2) && (s1->common.symbol_type != VARIABLE_SYMBOL_TYPE))
00511 return TRUE;
00512
00513
00514 if ((s1->common.symbol_type == SYM_CONSTANT_SYMBOL_TYPE) && (!strcmp(s1->sc.name, "*")))
00515 return TRUE;
00516 if ((s2->common.symbol_type == SYM_CONSTANT_SYMBOL_TYPE) && (!strcmp(s2->sc.name, "*")))
00517 return TRUE;
00518
00519 if ((s1->common.symbol_type != VARIABLE_SYMBOL_TYPE) || (s2->common.symbol_type != VARIABLE_SYMBOL_TYPE))
00520 return FALSE;
00521
00522 bvar = get_binding(s1, *bindings);
00523 if (bvar == NIL) {
00524 b = (Binding *) allocate_memory(sizeof(Binding), MISCELLANEOUS_MEM_USAGE);
00525 b->from = s1;
00526 b->to = s2;
00527 push(b, *bindings);
00528 return TRUE;
00529 } else if (bvar == s2) {
00530 return TRUE;
00531 } else
00532 return FALSE;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541 bool tests_are_equal_with_bindings(test t1, test test2, list ** bindings)
00542 {
00543 cons *c1, *c2;
00544 complex_test *ct1, *ct2;
00545 bool goal_test, impasse_test;
00546
00547
00548
00549
00550
00551
00552
00553 test t2;
00554
00555
00556 if (test_is_blank_test(t1)) {
00557 return (bool) (test_is_blank_test(test2));
00558 }
00559
00560
00561
00562 if ((!test_includes_goal_or_impasse_id_test(t1, TRUE, FALSE)) &&
00563 test_includes_goal_or_impasse_id_test(test2, TRUE, FALSE)) {
00564 goal_test = FALSE;
00565 impasse_test = FALSE;
00566 t2 = copy_test_removing_goal_impasse_tests(test2, &goal_test, &impasse_test);
00567 } else {
00568 t2 = copy_test(test2);
00569 }
00570
00571 if (test_is_blank_or_equality_test(t1)) {
00572 if (!(test_is_blank_or_equality_test(t2) && !(test_is_blank_test(t2)))) {
00573 dealloc_and_return(t2, FALSE);
00574 } else {
00575 if (symbols_are_equal_with_bindings(referent_of_equality_test(t1), referent_of_equality_test(t2), bindings)) {
00576 dealloc_and_return(t2, TRUE);
00577 } else {
00578 dealloc_and_return(t2, FALSE);
00579 }
00580 }
00581 }
00582
00583 ct1 = complex_test_from_test(t1);
00584 ct2 = complex_test_from_test(t2);
00585
00586 if (ct1->type != ct2->type) {
00587 dealloc_and_return(t2, FALSE);
00588 }
00589
00590 switch (ct1->type) {
00591 case GOAL_ID_TEST:
00592 dealloc_and_return(t2, TRUE);
00593 case IMPASSE_ID_TEST:
00594 dealloc_and_return(t2, TRUE);
00595
00596 case DISJUNCTION_TEST:
00597 for (c1 = ct1->data.disjunction_list, c2 = ct2->data.disjunction_list; ((c1 != NIL) && (c2 != NIL));
00598 c1 = c1->rest, c2 = c2->rest) {
00599 if (c1->first != c2->first) {
00600 dealloc_and_return(t2, FALSE);
00601 }
00602 }
00603 if (c1 == c2) {
00604 dealloc_and_return(t2, TRUE);
00605 }
00606 dealloc_and_return(t2, FALSE);
00607
00608 case CONJUNCTIVE_TEST:
00609 for (c1 = ct1->data.conjunct_list, c2 = ct2->data.conjunct_list; ((c1 != NIL) && (c2 != NIL));
00610 c1 = c1->rest, c2 = c2->rest) {
00611 if (!tests_are_equal_with_bindings(c1->first, c2->first, bindings)) {
00612 dealloc_and_return(t2, FALSE);
00613 }
00614 }
00615 if (c1 == c2) {
00616 dealloc_and_return(t2, TRUE);
00617 }
00618 dealloc_and_return(t2, FALSE);
00619
00620 default:
00621 if (symbols_are_equal_with_bindings(ct1->data.referent, ct2->data.referent, bindings)) {
00622 dealloc_and_return(t2, TRUE);
00623 }
00624 dealloc_and_return(t2, FALSE);
00625 }
00626 }
00627
00628 bool conditions_are_equal_with_bindings(condition * c1, condition * c2, list ** bindings)
00629 {
00630 if (c1->type != c2->type)
00631 return FALSE;
00632 switch (c1->type) {
00633 case POSITIVE_CONDITION:
00634 case NEGATIVE_CONDITION:
00635 if (!tests_are_equal_with_bindings(c1->data.tests.id_test, c2->data.tests.id_test, bindings))
00636 return FALSE;
00637 if (!tests_are_equal_with_bindings(c1->data.tests.attr_test, c2->data.tests.attr_test, bindings))
00638
00639 return FALSE;
00640 if (!tests_are_equal_with_bindings(c1->data.tests.value_test, c2->data.tests.value_test, bindings))
00641 return FALSE;
00642 if (c1->test_for_acceptable_preference != c2->test_for_acceptable_preference)
00643 return FALSE;
00644 return TRUE;
00645
00646 case CONJUNCTIVE_NEGATION_CONDITION:
00647 for (c1 = c1->data.ncc.top, c2 = c2->data.ncc.top; ((c1 != NIL) && (c2 != NIL)); c1 = c1->next, c2 = c2->next)
00648 if (!conditions_are_equal_with_bindings(c1, c2, bindings))
00649 return FALSE;
00650 if (c1 == c2)
00651 return TRUE;
00652 return FALSE;
00653 }
00654 return FALSE;
00655 }
00656
00657
00658 void read_pattern_and_get_matching_productions(list ** current_pf_list, bool show_bindings,
00659 bool just_chunks, bool no_chunks)
00660 {
00661 condition *c, *clist, *top, *bottom, *pc;
00662 int i;
00663 production *prod;
00664 list *bindings, *current_binding_point;
00665 bool match, match_this_c;
00666
00667 bindings = NIL;
00668 current_binding_point = NIL;
00669
00670
00671 clist = (condition *) parse_lhs();
00672 if (!clist) {
00673 print("Error: not a valid condition list.\n");
00674 current_pf_list = NIL;
00675 return;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 for (i = 0; i < NUM_PRODUCTION_TYPES; i++)
00687 if ((i == CHUNK_PRODUCTION_TYPE && !no_chunks) || (i != CHUNK_PRODUCTION_TYPE && !just_chunks))
00688 for (prod = current_agent(all_productions_of_type)[i]; prod != NIL; prod = prod->next) {
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 match = TRUE;
00704 p_node_to_conditions_and_nots(prod->p_node, NIL, NIL, &top, &bottom, NIL, NIL);
00705
00706 free_binding_list(bindings);
00707 bindings = NIL;
00708
00709 for (c = clist; c != NIL; c = c->next) {
00710 match_this_c = FALSE;
00711 current_binding_point = bindings;
00712
00713 for (pc = top; pc != NIL; pc = pc->next) {
00714 if (conditions_are_equal_with_bindings(c, pc, &bindings)) {
00715 match_this_c = TRUE;
00716 break;
00717 } else {
00718
00719 reset_old_binding_point(&bindings, ¤t_binding_point);
00720 bindings = current_binding_point;
00721 }
00722 }
00723 if (!match_this_c) {
00724 match = FALSE;
00725 break;
00726 }
00727 }
00728 deallocate_condition_list(top);
00729 if (match) {
00730 push(prod, (*current_pf_list));
00731 if (show_bindings) {
00732 print_with_symbols("%y, with bindings:\n", prod->name);
00733 print_binding_list(bindings);
00734 } else
00735 print_with_symbols("%y\n", prod->name);
00736 }
00737 }
00738 if (bindings)
00739 free_binding_list(bindings);
00740 }
00741
00742 bool funcalls_match(list * fc1, list * fc2)
00743 {
00744
00745
00746
00747
00748 fc1 = fc1;
00749 fc2 = fc2;
00750
00751 return FALSE;
00752 }
00753
00754 bool actions_are_equal_with_bindings(action * a1, action * a2, list ** bindings)
00755 {
00756 if (a1->type == FUNCALL_ACTION) {
00757 if ((a2->type == FUNCALL_ACTION)) {
00758 if (funcalls_match(rhs_value_to_funcall_list(a1->value), rhs_value_to_funcall_list(a2->value))) {
00759 return TRUE;
00760 } else
00761 return FALSE;
00762 } else
00763 return FALSE;
00764 }
00765 if (a2->type == FUNCALL_ACTION)
00766 return FALSE;
00767
00768
00769
00770 if (a1->preference_type != a2->preference_type)
00771 return FALSE;
00772
00773 if (!symbols_are_equal_with_bindings(rhs_value_to_symbol(a1->id), rhs_value_to_symbol(a2->id), bindings))
00774 return FALSE;
00775
00776 if ((rhs_value_is_symbol(a1->attr)) && (rhs_value_is_symbol(a2->attr))) {
00777 if (!symbols_are_equal_with_bindings(rhs_value_to_symbol(a1->attr), rhs_value_to_symbol(a2->attr), bindings))
00778 return FALSE;
00779 } else {
00780 if ((rhs_value_is_funcall(a1->attr)) && (rhs_value_is_funcall(a2->attr))) {
00781 if (!funcalls_match(rhs_value_to_funcall_list(a1->attr), rhs_value_to_funcall_list(a2->attr)))
00782 return FALSE;
00783 }
00784 }
00785
00786
00787
00788 if ((rhs_value_is_symbol(a1->value)) && (rhs_value_is_symbol(a2->value))) {
00789 if (symbols_are_equal_with_bindings(rhs_value_to_symbol(a1->value), rhs_value_to_symbol(a2->value), bindings))
00790 return TRUE;
00791 else
00792 return FALSE;
00793 }
00794 if ((rhs_value_is_funcall(a1->value)) && (rhs_value_is_funcall(a2->value))) {
00795 if (funcalls_match(rhs_value_to_funcall_list(a1->value), rhs_value_to_funcall_list(a2->value)))
00796 return TRUE;
00797 else
00798 return FALSE;
00799 }
00800 return FALSE;
00801 }
00802
00803
00804 void read_rhs_pattern_and_get_matching_productions(list ** current_pf_list, bool show_bindings,
00805 bool just_chunks, bool no_chunks)
00806 {
00807 action *a, *alist, *pa;
00808 int i;
00809 production *prod;
00810 list *bindings, *current_binding_point;
00811 bool match, match_this_a, parsed_ok;
00812 action *rhs;
00813 condition *top_cond, *bottom_cond;
00814
00815 bindings = NIL;
00816 current_binding_point = NIL;
00817
00818
00819 parsed_ok = parse_rhs(&alist);
00820 if (!parsed_ok) {
00821 print("Error: not a valid rhs.\n");
00822 current_pf_list = NIL;
00823 return;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832 for (i = 0; i < NUM_PRODUCTION_TYPES; i++)
00833 if ((i == CHUNK_PRODUCTION_TYPE && !no_chunks) || (i != CHUNK_PRODUCTION_TYPE && !just_chunks))
00834 for (prod = current_agent(all_productions_of_type)[i]; prod != NIL; prod = prod->next) {
00835 match = TRUE;
00836
00837 free_binding_list(bindings);
00838 bindings = NIL;
00839
00840 p_node_to_conditions_and_nots(prod->p_node, NIL, NIL, &top_cond, &bottom_cond, NIL, &rhs);
00841 deallocate_condition_list(top_cond);
00842 for (a = alist; a != NIL; a = a->next) {
00843 match_this_a = FALSE;
00844 current_binding_point = bindings;
00845
00846 for (pa = rhs; pa != NIL; pa = pa->next) {
00847 if (actions_are_equal_with_bindings(a, pa, &bindings)) {
00848 match_this_a = TRUE;
00849 break;
00850 } else {
00851
00852 reset_old_binding_point(&bindings, ¤t_binding_point);
00853 bindings = current_binding_point;
00854 }
00855 }
00856 if (!match_this_a) {
00857 match = FALSE;
00858 break;
00859 }
00860 }
00861 deallocate_action_list(rhs);
00862 if (match) {
00863 push(prod, (*current_pf_list));
00864 if (show_bindings) {
00865 print_with_symbols("%y, with bindings:\n", prod->name);
00866 print_binding_list(bindings);
00867 } else
00868 print_with_symbols("%y\n", prod->name);
00869 }
00870 }
00871 if (bindings)
00872 free_binding_list(bindings);
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900 extern Symbol *make_symbol_for_current_lexeme(void);
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 void print_current_watch_settings(void)
00919 {
00920
00921
00922
00923 print("Current watch settings:\n");
00924 print(" Decisions: %s\n", current_agent(sysparams)[TRACE_CONTEXT_DECISIONS_SYSPARAM] ? "on" : "off");
00925 print(" Phases: %s\n", current_agent(sysparams)[TRACE_PHASES_SYSPARAM] ? "on" : "off");
00926 print(" Production firings/retractions\n");
00927 print(" default productions: %s\n",
00928 current_agent(sysparams)[TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM] ? "on" : "off");
00929 print(" user productions: %s\n", current_agent(sysparams)[TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM] ? "on" : "off");
00930 print(" chunks: %s\n", current_agent(sysparams)[TRACE_FIRINGS_OF_CHUNKS_SYSPARAM] ? "on" : "off");
00931 print(" justifications: %s\n",
00932 current_agent(sysparams)[TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM] ? "on" : "off");
00933 print(" WME detail level: %d\n", current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM]);
00934 print(" Working memory changes: %s\n", current_agent(sysparams)[TRACE_WM_CHANGES_SYSPARAM] ? "on" : "off");
00935 print(" Preferences generated by firings/retractions: %s\n",
00936 current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM] ? "on" : "off");
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 print("\n");
00948 if (current_agent(sysparams)[TRACE_CHUNKS_SYSPARAM]) {
00949 print(" Learning: -fullprint (watch creation of chunks/just.)\n");
00950 } else {
00951 print(" Learning: %s (watch creation of chunks/just.)\n",
00952 current_agent(sysparams)[TRACE_CHUNK_NAMES_SYSPARAM] ? "-print" : "-noprint");
00953 }
00954 print(" Backtracing: %s\n", current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM] ? "on" : "off");
00955
00956 print(" Loading: %s\n", current_agent(sysparams)[TRACE_LOADING_SYSPARAM] ? "on" : "off");
00957
00958 print(" Indifferent-selection: %s\n", current_agent(sysparams)[TRACE_INDIFFERENT_SYSPARAM] ? "on" : "off");
00959
00960 print("\n");
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 int set_watch_setting(int dest_sysparam_number, const char *param, const char *arg, soarResult * res)
00981 {
00982 if (arg == NULL) {
00983 setSoarResultResult(res, "Missing setting for watch parameter %s", param);
00984 return SOAR_ERROR;
00985 }
00986
00987 if (!strcmp("-on", arg)) {
00988 set_sysparam(dest_sysparam_number, TRUE);
00989 } else if (!strcmp("-off", arg)) {
00990 set_sysparam(dest_sysparam_number, FALSE);
00991 } else if (!strncmp("-inclusive", arg, 3)) {
00992 soar_ecWatchLevel(dest_sysparam_number);
00993 } else {
00994 setSoarResultResult(res, "Unrecognized setting for watch parameter %s: %s", param, arg);
00995 return SOAR_ERROR;
00996 }
00997 return SOAR_OK;
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 int set_watch_prod_group_setting(int prodgroup, const char *prodtype, const char *arg, soarResult * res)
01018 {
01019 if (arg == NULL) {
01020 setSoarResultResult(res, "Missing setting for watch %s", prodtype);
01021 return SOAR_ERROR;
01022 }
01023
01024 if (!strcmp("-print", arg)) {
01025 switch (prodgroup) {
01026 case 0:
01027 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, TRUE);
01028 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, TRUE);
01029 set_sysparam(TRACE_FIRINGS_OF_CHUNKS_SYSPARAM, TRUE);
01030 set_sysparam(TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM, TRUE);
01031 break;
01032 case 1:
01033 set_sysparam(TRACE_FIRINGS_OF_CHUNKS_SYSPARAM, TRUE);
01034 break;
01035 case 2:
01036 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, TRUE);
01037 break;
01038 case 3:
01039 set_sysparam(TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM, TRUE);
01040 break;
01041 case 4:
01042 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, TRUE);
01043 break;
01044 }
01045 } else if (!strcmp("-noprint", arg)) {
01046 switch (prodgroup) {
01047 case 0:
01048 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, FALSE);
01049 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, FALSE);
01050 set_sysparam(TRACE_FIRINGS_OF_CHUNKS_SYSPARAM, FALSE);
01051 set_sysparam(TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM, FALSE);
01052 break;
01053 case 1:
01054 set_sysparam(TRACE_FIRINGS_OF_CHUNKS_SYSPARAM, FALSE);
01055 break;
01056 case 2:
01057 set_sysparam(TRACE_FIRINGS_OF_DEFAULT_PRODS_SYSPARAM, FALSE);
01058 break;
01059 case 3:
01060 set_sysparam(TRACE_FIRINGS_OF_JUSTIFICATIONS_SYSPARAM, FALSE);
01061 break;
01062 case 4:
01063 set_sysparam(TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM, FALSE);
01064 break;
01065 }
01066 } else if (!strcmp("-fullprint", arg)) {
01067 setSoarResultResult(res, "Sorry, -fullprint not yet implemented for watch productions");
01068 return SOAR_ERROR;
01069 } else {
01070 setSoarResultResult(res,
01071 "Unrecognized setting for watch %s: %s. Use -print|-noprint|-fullprint", prodtype, arg);
01072 return SOAR_ERROR;
01073 }
01074 return SOAR_OK;
01075 }
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 int parse_run_command(int argc, const char *argv[],
01116 long *go_number,
01117 enum go_type_enum *go_type,
01118 Symbol * *go_slot_attr, goal_stack_level * go_slot_level, bool * self_only, soarResult * res)
01119 {
01120 Symbol *g, *attr, *value;
01121 int i;
01122 bool no_number = TRUE;
01123
01124 for (i = 1; i < argc; i++) {
01125 get_lexeme_from_string(argv[i]);
01126
01127 if (current_agent(lexeme).type == INT_CONSTANT_LEXEME) {
01128 *go_number = current_agent(lexeme).int_val;
01129 no_number = FALSE;
01130 } else if (current_agent(lexeme).type == SYM_CONSTANT_LEXEME) {
01131 if (!strcmp("forever", argv[i])) {
01132 *go_number = -1;
01133 } else if (!strcmp("p", argv[i])) {
01134 *go_type = GO_PHASE;
01135 if (no_number) {
01136 *go_number = 1;
01137 no_number = FALSE;
01138 }
01139 } else if (!strcmp("e", argv[i])) {
01140 *go_type = GO_ELABORATION;
01141 if (no_number) {
01142 *go_number = 1;
01143 no_number = FALSE;
01144 }
01145 } else if (!strcmp("d", argv[i])) {
01146 *go_type = GO_DECISION;
01147 if (no_number) {
01148 *go_number = 1;
01149 no_number = FALSE;
01150 }
01151 } else if (!strcmp("s", argv[i])) {
01152 *go_type = GO_STATE;
01153 if (no_number) {
01154 *go_number = 1;
01155 no_number = FALSE;
01156 }
01157 } else if (!strcmp("o", argv[i])) {
01158 *go_type = GO_OPERATOR;
01159 if (no_number) {
01160 *go_number = 1;
01161 no_number = FALSE;
01162 }
01163 } else if (!strcmp("out", argv[i])) {
01164 *go_type = GO_OUTPUT;
01165 if (no_number) {
01166 *go_number = 1;
01167 no_number = FALSE;
01168 }
01169 } else if (!strcmp("-self", argv[i])) {
01170 *self_only = TRUE;
01171 } else {
01172 setSoarResultResult(res, "Unrecognized argument to run command: %s", argv[i]);
01173 return SOAR_ERROR;
01174 }
01175 } else if (current_agent(lexeme).type == VARIABLE_LEXEME) {
01176 get_context_var_info(&g, &attr, &value);
01177 if (!attr) {
01178 setSoarResultResult(res,
01179 "Expected <s>, <o>, <ss>, <so>, <sss>, or <sso> as variable in run command, not %s",
01180 argv[i]);
01181 return SOAR_ERROR;
01182 }
01183
01184 if (!g) {
01185 setSoarResultResult(res,
01186 "There is either no superstate, or no supersuperstate (whichever you specified, %s) of the current level",
01187 argv[i]);
01188 return SOAR_ERROR;
01189 }
01190 *go_type = GO_SLOT;
01191 *go_slot_level = g->id.level;
01192 *go_slot_attr = attr;
01193 if (no_number) {
01194 *go_number = 1;
01195 no_number = FALSE;
01196 }
01197 } else {
01198 setSoarResultResult(res, "Unrecognized argument to run command: %s", argv[i]);
01199 return SOAR_ERROR;
01200 }
01201 }
01202
01203
01204
01205
01206 if (no_number) {
01207 *go_number = -1;
01208 }
01209
01210 return SOAR_OK;
01211
01212 }
01213
01214 int parse_go_command(int argc, char *argv[],
01215 long *go_number,
01216 enum go_type_enum *go_type,
01217 Symbol * *go_slot_attr, goal_stack_level * go_slot_level, soarResult * res)
01218 {
01219 Symbol *g, *attr, *value;
01220 int i;
01221
01222 for (i = 1; i < argc; i++) {
01223 get_lexeme_from_string(argv[i]);
01224
01225 if (current_agent(lexeme).type == INT_CONSTANT_LEXEME) {
01226 *go_number = current_agent(lexeme).int_val;
01227 } else if (current_agent(lexeme).type == SYM_CONSTANT_LEXEME) {
01228 if (!strcmp("forever", argv[i])) {
01229 *go_number = -1;
01230 } else if (!strcmp("p", argv[i])) {
01231 *go_type = GO_PHASE;
01232 } else if (!strcmp("e", argv[i])) {
01233 *go_type = GO_ELABORATION;
01234 } else if (!strcmp("d", argv[i])) {
01235 *go_type = GO_DECISION;
01236 } else if (!strcmp("s", argv[i])) {
01237 *go_type = GO_STATE;
01238 } else if (!strcmp("o", argv[i])) {
01239 *go_type = GO_OPERATOR;
01240 } else {
01241 setSoarResultResult(res, "Unrecognized argument to go command: %s", argv[i]);
01242 return SOAR_ERROR;
01243 }
01244 } else if (current_agent(lexeme).type == VARIABLE_LEXEME) {
01245 get_context_var_info(&g, &attr, &value);
01246 if (!attr) {
01247 setSoarResultResult(res, "Expected a context variable in go command, not %s", argv[i]);
01248 return SOAR_ERROR;
01249 }
01250
01251 if (!g) {
01252 setSoarResultResult(res, "Goal stack level %s does not exist", argv[i]);
01253 return SOAR_ERROR;
01254 }
01255
01256 *go_type = GO_SLOT;
01257 *go_slot_level = g->id.level;
01258 *go_slot_attr = attr;
01259 } else {
01260 setSoarResultResult(res, "Unrecognized argument to go command: %s", argv[i]);
01261 return SOAR_ERROR;
01262 }
01263 }
01264
01265 return SOAR_OK;
01266 }
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301 int parse_memory_stats(int argc, const char *argv[], soarResult * res)
01302 {
01303 if (argc == 2) {
01304 soar_ecPrintMemoryStatistics();
01305 soar_ecPrintMemoryPoolStatistics();
01306
01307 return SOAR_OK;
01308 }
01309
01310 if (!strcmp("-total", argv[2])) {
01311 unsigned long total;
01312 int i;
01313
01314 total = 0;
01315 for (i = 0; i < NUM_MEM_USAGE_CODES; i++)
01316 total += current_agent(memory_for_usage)[i];
01317
01318 print("%lu", total);
01319
01320 } else if (!strcmp("-overhead", argv[2])) {
01321 print("%lu", current_agent(memory_for_usage)[STATS_OVERHEAD_MEM_USAGE]);
01322
01323 } else if (!strcmp("-strings", argv[2])) {
01324 print("%lu", current_agent(memory_for_usage)[STRING_MEM_USAGE]);
01325
01326 } else if (!strcmp("-hash-table", argv[2])) {
01327 print("%lu", current_agent(memory_for_usage)[HASH_TABLE_MEM_USAGE]);
01328
01329 } else if (!strcmp("-pool", argv[2])) {
01330 if (argc == 3) {
01331 soar_ecPrintMemoryPoolStatistics();
01332 } else if (!strcmp("-total", argv[3])) {
01333 print("%lu", current_agent(memory_for_usage)[POOL_MEM_USAGE]);
01334
01335 } else {
01336 memory_pool *p;
01337 memory_pool *pool_found = NIL;
01338
01339 for (p = current_agent(memory_pools_in_use); p != NIL; p = p->next) {
01340 if (!strcmp(argv[3], p->name)) {
01341 pool_found = p;
01342 break;
01343 }
01344 }
01345
01346 if (!pool_found) {
01347 setSoarResultResult(res, "Unrecognized pool name: stats -memory -pool %s", argv[4]);
01348 return SOAR_ERROR;
01349 }
01350
01351 if (argc == 4) {
01352 #ifdef MEMORY_POOL_STATS
01353 long total_items;
01354 #endif
01355 print("Memory pool statistics:\n\n");
01356 #ifdef MEMORY_POOL_STATS
01357 print("Pool Name Used Items Free Items Item Size Total Bytes\n");
01358 print("--------------- ---------- ---------- --------- -----------\n");
01359 #else
01360 print("Pool Name Item Size Total Bytes\n");
01361 print("--------------- --------- -----------\n");
01362 #endif
01363
01364 print_string(pool_found->name);
01365 print_spaces(MAX_POOL_NAME_LENGTH - strlen(pool_found->name));
01366 #ifdef MEMORY_POOL_STATS
01367 print(" %10lu", pool_found->used_count);
01368 total_items = pool_found->num_blocks * pool_found->items_per_block;
01369 print(" %10lu", total_items - pool_found->used_count);
01370 #endif
01371 print(" %9lu", pool_found->item_size);
01372 print(" %11lu\n", pool_found->num_blocks * pool_found->items_per_block * pool_found->item_size);
01373 } else if (argc == 5) {
01374 long total_items;
01375
01376 total_items = pool_found->num_blocks * pool_found->items_per_block;
01377
01378 if (!strcmp("-item-size", argv[4])) {
01379 print("%lu", pool_found->item_size);
01380
01381 }
01382 #ifdef MEMORY_POOL_STATS
01383 else if (!strcmp("-used", argv[4])) {
01384 print("%lu", pool_found->used_count);
01385
01386 } else if (!strcmp("-free", argv[4])) {
01387 print("%lu", total_items - pool_found->used_count);
01388
01389 }
01390 #endif
01391 else if (!strcmp("-total-bytes", argv[4])) {
01392 print("%lu",
01393 pool_found->num_blocks * pool_found->items_per_block * pool_found->item_size);
01394
01395
01396 } else {
01397 setSoarResultResult(res, "Unrecognized argument to stats: -memory -pool %s %s", argv[3], argv[4]);
01398 return SOAR_ERROR;
01399 }
01400 } else {
01401 setSoarResultResult(res,
01402 "Too many arguments, should be: stats -memory -pool [-total | pool-name [<aspect>]]");
01403 return SOAR_ERROR;
01404 }
01405 }
01406 } else if (!strcmp("-misc", argv[2])) {
01407 print("%lu", current_agent(memory_for_usage)[MISCELLANEOUS_MEM_USAGE]);
01408
01409 } else {
01410 setSoarResultResult(res, "Unrecognized argument to stats: -memory %s", argv[2]);
01411 return SOAR_ERROR;
01412 }
01413
01414 return SOAR_OK;
01415 }
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452 int parse_rete_stats(int argc, const char *argv[], soarResult * res)
01453 {
01454 unsigned long data;
01455
01456 if (argc == 2) {
01457 soar_ecPrintReteStatistics();
01458 return SOAR_OK;
01459 }
01460
01461 if (argc == 3) {
01462 setSoarResultResult(res, "Too few arguments, should be: stats -rete [type qualifier]");
01463 return SOAR_ERROR;
01464 }
01465
01466 if (argc > 4) {
01467 setSoarResultResult(res, "Too many arguments, should be: stats -rete [type qualifier]");
01468 return SOAR_ERROR;
01469 }
01470
01471 if (get_node_count_statistic(argv[2], (char *) argv[3] + 1, &data)) {
01472 print("%lu", data);
01473
01474 } else {
01475 setSoarResultResult(res, "Unrecognized argument to stats: -rete %s %s", argv[2], argv[3]);
01476 return SOAR_ERROR;
01477 }
01478 return SOAR_OK;
01479 }
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530 int parse_system_stats(int argc, const char *argv[], soarResult * res)
01531 {
01532 #ifndef NO_TIMING_STUFF
01533 double total_kernel_time, total_kernel_msec;
01534
01535 #ifdef DETAILED_TIMING_STATS
01536 double time;
01537 #endif
01538 #endif
01539
01540 if (argc > 3) {
01541 setSoarResultResult(res, "Too many arguments, should be: stats -system [<type>]");
01542 return SOAR_ERROR;
01543 }
01544
01545 total_kernel_time = timer_value(¤t_agent(total_kernel_time));
01546 total_kernel_msec = total_kernel_time * 1000.0;
01547
01548 if (argc <= 2) {
01549 soar_ecPrintSystemStatistics();
01550 } else {
01551 if (!strcmp("-default-production-count", argv[2])) {
01552 print("%lu", current_agent(num_productions_of_type)[DEFAULT_PRODUCTION_TYPE]);
01553
01554 } else if (!strcmp("-user-production-count", argv[2])) {
01555 print("%lu", current_agent(num_productions_of_type)[USER_PRODUCTION_TYPE]);
01556
01557
01558 } else if (!strcmp("-chunk-count", argv[2])) {
01559 print("%lu", current_agent(num_productions_of_type)[CHUNK_PRODUCTION_TYPE]);
01560
01561 } else if (!strcmp("-justification-count", argv[2])) {
01562 print("%lu", current_agent(num_productions_of_type)[JUSTIFICATION_PRODUCTION_TYPE]);
01563
01564 } else if (!strcmp("-all-productions-count", argv[2])) {
01565 print("%lu", current_agent(num_productions_of_type)[DEFAULT_PRODUCTION_TYPE]
01566 + current_agent(num_productions_of_type)[USER_PRODUCTION_TYPE]
01567 + current_agent(num_productions_of_type)[CHUNK_PRODUCTION_TYPE]);
01568
01569
01570
01571
01572
01573 } else if (!strcmp("-dc-count", argv[2])) {
01574 print("%lu", current_agent(d_cycle_count));
01575
01576 } else if (!strcmp("-ec-count", argv[2])) {
01577 print("%lu", current_agent(e_cycle_count));
01578
01579 } else if (!strcmp("-ecs/dc", argv[2])) {
01580 print("%.3f", (current_agent(d_cycle_count)
01581 ? ((double) current_agent(e_cycle_count)
01582 / current_agent(d_cycle_count))
01583 : 0.0));
01584
01585
01586
01587
01588 } else if (!strcmp("-firings-count", argv[2])) {
01589 print("%lu", current_agent(production_firing_count));
01590
01591 } else if (!strcmp("-firings/ec", argv[2])) {
01592 print("%.3f", (current_agent(e_cycle_count)
01593 ? ((double) current_agent(production_firing_count)
01594 / current_agent(e_cycle_count))
01595 : 0.0));
01596
01597
01598
01599
01600 } else if (!strcmp("-wme-change-count", argv[2])) {
01601 print("%lu", current_agent(wme_addition_count)
01602 + current_agent(wme_removal_count));
01603
01604
01605 } else if (!strcmp("-wme-addition-count", argv[2])) {
01606 print("%lu", current_agent(wme_addition_count));
01607
01608 } else if (!strcmp("-wme-removal-count", argv[2])) {
01609 print("%lu", current_agent(wme_removal_count));
01610
01611 } else if (!strcmp("-wme-count", argv[2])) {
01612 setSoarResultResult(res, "%lu", current_agent(num_wmes_in_rete));
01613 } else if (!strcmp("-wme-avg-count", argv[2])) {
01614 print("%.3f", (current_agent(num_wm_sizes_accumulated)
01615 ? (current_agent(cumulative_wm_size)
01616 / current_agent(num_wm_sizes_accumulated))
01617 : 0.0));
01618
01619
01620
01621
01622 } else if (!strcmp("-wme-max-count", argv[2])) {
01623 print("%lu", current_agent(max_wm_size));
01624
01625 }
01626 #ifndef NO_TIMING_STUFF
01627 else if (!strcmp("-total-time", argv[2])) {
01628 print("%.3f", total_kernel_time);
01629
01630 } else if (!strcmp("-ms/dc", argv[2])) {
01631 print("%.3f", (current_agent(d_cycle_count)
01632 ? total_kernel_msec / current_agent(d_cycle_count)
01633 : 0.0));
01634
01635
01636
01637 } else if (!strcmp("-ms/ec", argv[2])) {
01638 print("%.3f", (current_agent(e_cycle_count)
01639 ? total_kernel_msec / current_agent(e_cycle_count)
01640 : 0.0));
01641
01642
01643
01644 } else if (!strcmp("-ms/firing", argv[2])) {
01645 print("%.3f", (current_agent(production_firing_count)
01646 ? total_kernel_msec / current_agent(production_firing_count)
01647 : 0.0));
01648
01649
01650
01651 }
01652 #endif
01653 #ifdef DETAILED_TIMING_STATS
01654 else if (!strcmp("-ms/wme-change", argv[2])) {
01655 long wme_changes;
01656 time = timer_value(¤t_agent(match_cpu_time[INPUT_PHASE]))
01657 + timer_value(¤t_agent(match_cpu_time[DETERMINE_LEVEL_PHASE]))
01658 + timer_value(¤t_agent(match_cpu_time[PREFERENCE_PHASE]))
01659 + timer_value(¤t_agent(match_cpu_time[WM_PHASE]))
01660 + timer_value(¤t_agent(match_cpu_time[OUTPUT_PHASE]))
01661 + timer_value(¤t_agent(match_cpu_time[DECISION_PHASE]));
01662
01663 time *= 1000;
01664
01665 wme_changes = current_agent(wme_addition_count)
01666 + current_agent(wme_removal_count);
01667
01668 print("%.3f", (wme_changes ? time / wme_changes : 0.0));
01669
01670 } else if (!strcmp("-match-time", argv[2])) {
01671
01672 time = timer_value(¤t_agent(match_cpu_time[INPUT_PHASE]))
01673 + timer_value(¤t_agent(match_cpu_time[DETERMINE_LEVEL_PHASE]))
01674 + timer_value(¤t_agent(match_cpu_time[PREFERENCE_PHASE]))
01675 + timer_value(¤t_agent(match_cpu_time[WM_PHASE]))
01676 + timer_value(¤t_agent(match_cpu_time[OUTPUT_PHASE]))
01677 + timer_value(¤t_agent(match_cpu_time[DECISION_PHASE]));
01678
01679 print("%.3f", time);
01680
01681
01682 } else if (!strcmp("-ownership-time", argv[2])) {
01683 time = timer_value(¤t_agent(ownership_cpu_time[INPUT_PHASE]))
01684 + timer_value(¤t_agent(ownership_cpu_time[DETERMINE_LEVEL_PHASE]))
01685 + timer_value(¤t_agent(ownership_cpu_time[PREFERENCE_PHASE]))
01686 + timer_value(¤t_agent(ownership_cpu_time[WM_PHASE]))
01687 + timer_value(¤t_agent(ownership_cpu_time[OUTPUT_PHASE]))
01688 + timer_value(¤t_agent(ownership_cpu_time[DECISION_PHASE]));
01689
01690 print("%.3f", time);
01691
01692
01693 } else if (!strcmp("-chunking-time", argv[2])) {
01694 time = timer_value(¤t_agent(chunking_cpu_time[INPUT_PHASE]))
01695 + timer_value(¤t_agent(chunking_cpu_time[DETERMINE_LEVEL_PHASE]))
01696 + timer_value(¤t_agent(chunking_cpu_time[PREFERENCE_PHASE]))
01697 + timer_value(¤t_agent(chunking_cpu_time[WM_PHASE]))
01698 + timer_value(¤t_agent(chunking_cpu_time[OUTPUT_PHASE]))
01699 + timer_value(¤t_agent(chunking_cpu_time[DECISION_PHASE]));
01700
01701 print("%.3f", time);
01702
01703
01704 }
01705 #endif
01706 else {
01707 setSoarResultResult(res, "Unrecognized argument to stats: -system %s", argv[2]);
01708 }
01709 }
01710
01711 return SOAR_OK;
01712 }
01713
01714 int printTimingInfo()
01715 {
01716
01717 #ifdef PII_TIMERS
01718 unsigned long long int start, stop;
01719 #else
01720 struct timeval start, stop;
01721 #endif
01722
01723 double min, max, min_nz;
01724
01725 min_nz = soar_cDetermineTimerResolution(&min, &max);
01726
01727 #ifdef PII_TIMERS
01728 print("Using Pentium II Time Stamp -- Assuming %d MHZ Processor...\n", MHZ);
01729 #else
01730 print("Using system timers...\n");
01731 #endif
01732
01733 print("---------------------------------------------------------------\n");
01734 print("A timing loop is used to obtain the following values.\n");
01735 print("At least one additional instruction takes place between\n");
01736 print("starting and stopping the timers, thus a perfectly accurate\n");
01737 print("timer which costs nothing to invoke would still accumulate\n");
01738 print("non-zero value. The loop runs for a total of ~2 seconds as \n");
01739 print("a result, the Maximum timer value is likely to be relatively \n");
01740 print("large, but should be < 2 seconds\n");
01741 print("** NOTE: If the code was optimized, the timing loop may yield\n");
01742 print(" unanticipated results. If both minimum values are\n");
01743 print(" zero, it is unclear what the timer resolution is...\n");
01744 print("---------------------------------------------------------------\n");
01745 print("Minimum (Non-Zero) Timer Value: %11.5e sec\n", min_nz);
01746 print("Minimum Timer Value : %11.5e sec\n", min);
01747 print("Maximum Timer Value : %11.5e sec\n\n", max);
01748
01749 print("---------------------------------------------------------------\n");
01750 print("A short delay will be issued using the sleep() command, and \n");
01751 print("timed using Soar's timers....\n");
01752 reset_timer(&stop);
01753 start_timer(&start);
01754 sys_sleep(3);
01755 stop_timer(&start, &stop);
01756 print("Sleep interval --> 3 seconds\n");
01757 print("Timers report --> %8.5f seconds\n", timer_value(&stop));
01758 print("---------------------------------------------------------------\n");
01759
01760 return 1;
01761
01762 }