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
00044
00045
00046
00047
00048
00049
00050 #include "soarkernel.h"
00051 #include <stdio.h>
00052 #include <ctype.h>
00053
00054 #ifdef USE_STDARGS
00055 #include <stdarg.h>
00056 #else
00057 #include <varargs.h>
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 void start_log_file(char *filename, bool append)
00095 {
00096 if (current_agent(logging_to_file))
00097 stop_log_file();
00098
00099 sys_chdir(current_agent(top_dir_stack)->directory);
00100 current_agent(log_file) = fopen(filename, (append ? "a" : "w"));
00101
00102 if (current_agent(log_file)) {
00103 current_agent(logging_to_file) = TRUE;
00104 current_agent(log_file_name) = make_memory_block_for_string(filename);
00105 print("Logging to file %s\n", filename);
00106 } else {
00107
00108 print("Error: unable to open file %s\n", filename);
00109 }
00110 }
00111
00112 void stop_log_file(void)
00113 {
00114 if (!current_agent(logging_to_file))
00115 return;
00116 print("Closing log file %s\n", current_agent(log_file_name));
00117 if (fclose(current_agent(log_file)))
00118 print("Error: unable to close file %s\n", current_agent(log_file_name));
00119 free_memory_block_for_string(current_agent(log_file_name));
00120 current_agent(logging_to_file) = FALSE;
00121 }
00122
00123 void print_string_to_log_file_only(char *string)
00124 {
00125 fputs(string, current_agent(log_file));
00126 }
00127
00128 int get_printer_output_column(void)
00129 {
00130 return current_agent(printer_output_column);
00131 }
00132
00133 void tell_printer_that_output_column_has_been_reset(void)
00134 {
00135 current_agent(printer_output_column) = 1;
00136 }
00137
00138 void start_redirection_to_file(FILE * already_opened_file)
00139 {
00140 current_agent(saved_printer_output_column) = current_agent(printer_output_column);
00141 current_agent(printer_output_column) = 1;
00142 current_agent(redirecting_to_file) = TRUE;
00143 current_agent(redirection_file) = already_opened_file;
00144 }
00145
00146 void stop_redirection_to_file(void)
00147 {
00148 current_agent(redirecting_to_file) = FALSE;
00149 current_agent(printer_output_column) = current_agent(saved_printer_output_column);
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 void print_string(char *s)
00160 {
00161 char *ch;
00162
00163 for (ch = s; *ch != 0; ch++) {
00164 if (*ch == '\n') {
00165 current_agent(printer_output_column) = 1;
00166 } else {
00167 current_agent(printer_output_column)++;
00168 }
00169 }
00170
00171 if (current_agent(redirecting_to_file)) {
00172 fputs(s, current_agent(redirection_file));
00173 } else {
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 soar_invoke_first_callback(soar_agent, LOG_CALLBACK, s);
00191 soar_invoke_first_callback(soar_agent, PRINT_CALLBACK, s);
00192 }
00193 if (current_agent(logging_to_file)) {
00194 fputs(s, current_agent(log_file));
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 #define PRINT_BUFSIZE 4096
00209
00210 #ifdef USE_STDARGS
00211 void print(char *format, ...)
00212 {
00213 va_list args;
00214 char buf[PRINT_BUFSIZE];
00215
00216 va_start(args, format);
00217 #else
00218 void print(va_alist)
00219 va_dcl
00220 {
00221 va_list args;
00222 char *format;
00223 char buf[PRINT_BUFSIZE];
00224
00225 va_start(args);
00226 format = va_arg(args, char *);
00227 #endif
00228 vsnprintf(buf, PRINT_BUFSIZE, format, args);
00229 va_end(args);
00230 print_string(buf);
00231 }
00232
00233 #ifdef USE_STDARGS
00234 void print_with_symbols(char *format, ...)
00235 {
00236 va_list args;
00237 char buf[PRINT_BUFSIZE];
00238 char *ch;
00239
00240 va_start(args, format);
00241 #else
00242 void print_with_symbols(va_alist)
00243 va_dcl
00244 {
00245 va_list args;
00246 char buf[PRINT_BUFSIZE];
00247 char *ch, *format;
00248
00249 va_start(args);
00250 format = va_arg(args, char *);
00251 #endif
00252 ch = buf;
00253
00254 for (;;) {
00255
00256 while ((*format != '%') && (*format != 0))
00257 *(ch++) = *(format++);
00258
00259 if (*format == 0)
00260 break;
00261
00262
00263 if (*(format + 1) == 'y') {
00264
00265
00266
00267
00268 symbol_to_string(va_arg(args, Symbol *), TRUE, ch, PRINT_BUFSIZE - (ch - buf));
00269 while (*ch)
00270 ch++;
00271
00272 } else {
00273 *(ch++) = '%';
00274 }
00275
00276 format += 2;
00277 }
00278
00279 va_end(args);
00280
00281 *ch = 0;
00282 print_string(buf);
00283 }
00284
00285 void print_spaces(int n)
00286 {
00287
00288
00289
00290
00291
00292 char buf[PRINT_BUFSIZE];
00293
00294 if (n >= PRINT_BUFSIZE) {
00295 n = PRINT_BUFSIZE - 1;
00296 }
00297
00298 memset(buf, ' ', n);
00299
00300 buf[n] = 0;
00301
00302 print_string(buf);
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 char *string_to_escaped_string(char *s, char first_and_last_char, char *dest)
00334 {
00335 char *ch;
00336
00337 if (!dest)
00338 dest = current_agent(printed_output_string);
00339 ch = dest;
00340 *ch++ = first_and_last_char;
00341 while (*s) {
00342 if ((*s == first_and_last_char) || (*s == '\\'))
00343 *ch++ = '\\';
00344 *ch++ = *s++;
00345 }
00346 *ch++ = first_and_last_char;
00347 *ch = 0;
00348 return dest;
00349 }
00350
00351 char *symbol_to_string(Symbol * sym, bool rereadable, char *dest, size_t dest_size)
00352 {
00353 bool possible_id, possible_var, possible_sc, possible_ic, possible_fc;
00354 bool is_rereadable;
00355 bool has_angle_bracket;
00356
00357 if (!sym) {
00358 if (!dest) {
00359 dest = current_agent(printed_output_string);
00360 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00361 }
00362
00363 strncpy(dest, "(NULL)", dest_size);
00364 dest[dest_size - 1] = 0;
00365 return dest;
00366 }
00367
00368 switch (sym->common.symbol_type) {
00369 case VARIABLE_SYMBOL_TYPE:
00370 if (!dest) {
00371 return sym->var.name;
00372 }
00373
00374 strncpy(dest, sym->var.name, dest_size);
00375 dest[dest_size - 1] = 0;
00376 return dest;
00377
00378 case IDENTIFIER_SYMBOL_TYPE:
00379 if (!dest) {
00380 dest = current_agent(printed_output_string);
00381 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00382 }
00383 snprintf(dest, dest_size, "%c%lu", sym->id.name_letter, sym->id.name_number);
00384 dest[dest_size - 1] = 0;
00385 return dest;
00386
00387 case INT_CONSTANT_SYMBOL_TYPE:
00388 if (!dest) {
00389 dest = current_agent(printed_output_string);
00390 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00391 }
00392 snprintf(dest, dest_size, "%ld", sym->ic.value);
00393 dest[dest_size - 1] = 0;
00394 return dest;
00395
00396 case FLOAT_CONSTANT_SYMBOL_TYPE:
00397 if (!dest) {
00398 dest = current_agent(printed_output_string);
00399 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00400 }
00401 snprintf(dest, dest_size, "%#g", sym->fc.value);
00402 dest[dest_size - 1] = 0;
00403 {
00404 char *start_of_exponent;
00405 char *end_of_mantissa;
00406 start_of_exponent = dest;
00407 while ((*start_of_exponent != 0) && (*start_of_exponent != 'e'))
00408 start_of_exponent++;
00409 end_of_mantissa = start_of_exponent - 1;
00410 while (*end_of_mantissa == '0')
00411 end_of_mantissa--;
00412 end_of_mantissa++;
00413 while (*start_of_exponent)
00414 *end_of_mantissa++ = *start_of_exponent++;
00415 *end_of_mantissa = 0;
00416 }
00417 return dest;
00418
00419 case SYM_CONSTANT_SYMBOL_TYPE:
00420 if (!rereadable) {
00421 if (!dest)
00422 return sym->sc.name;
00423 strncpy(dest, sym->sc.name, dest_size);
00424 dest[dest_size - 1] = 0;
00425 return dest;
00426 }
00427 determine_possible_symbol_types_for_string(sym->sc.name,
00428 strlen(sym->sc.name),
00429 &possible_id,
00430 &possible_var,
00431 &possible_sc, &possible_ic, &possible_fc, &is_rereadable);
00432
00433 has_angle_bracket = (bool) (sym->sc.name[0] == '<' || sym->sc.name[strlen(sym->sc.name) - 1] == '>');
00434
00435 if ((!possible_sc) || possible_var || possible_ic || possible_fc || (!is_rereadable) || has_angle_bracket) {
00436
00437
00438 return string_to_escaped_string(sym->sc.name, '|', dest);
00439 }
00440 if (!dest)
00441 return sym->sc.name;
00442 strncpy(dest, sym->sc.name, dest_size);
00443 dest[dest_size - 1] = 0;
00444 return dest;
00445
00446 default:
00447 {
00448 char msg[MESSAGE_SIZE];
00449 strncpy(msg, "Internal Soar Error: symbol_to_string called on bad symbol\n", MESSAGE_SIZE);
00450 msg[MESSAGE_SIZE - 1] = 0;
00451
00452 abort_with_fatal_error(msg);
00453 }
00454 }
00455 return NIL;
00456 }
00457
00458 char *test_to_string(test t, char *dest, size_t dest_size)
00459 {
00460 cons *c;
00461 complex_test *ct;
00462 char *ch;
00463
00464 if (test_is_blank_test(t)) {
00465 if (!dest) {
00466 dest = current_agent(printed_output_string);
00467 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00468 }
00469 snprintf(dest, dest_size, "[BLANK TEST]");
00470 dest[dest_size - 1] = 0;
00471 return dest;
00472 }
00473
00474 if (test_is_blank_or_equality_test(t)) {
00475 return symbol_to_string(referent_of_equality_test(t), TRUE, dest, dest_size);
00476 }
00477
00478 if (!dest) {
00479 dest = current_agent(printed_output_string);
00480 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00481 }
00482
00483 ch = dest;
00484 ct = complex_test_from_test(t);
00485
00486 switch (ct->type) {
00487 case NOT_EQUAL_TEST:
00488 strncpy(ch, "<> ", dest_size - (ch - dest));
00489 ch[dest_size - (ch - dest) - 1] = 0;
00490 while (*ch)
00491 ch++;
00492 symbol_to_string(ct->data.referent, TRUE, ch, dest_size - (ch - dest));
00493 break;
00494 case LESS_TEST:
00495 strncpy(ch, "< ", dest_size - (ch - dest));
00496 ch[dest_size - (ch - dest) - 1] = 0;
00497 while (*ch)
00498 ch++;
00499 symbol_to_string(ct->data.referent, TRUE, ch, dest_size - (ch - dest));
00500 break;
00501 case GREATER_TEST:
00502 strncpy(ch, "> ", dest_size - (ch - dest));
00503 ch[dest_size - (ch - dest) - 1] = 0;
00504 while (*ch)
00505 ch++;
00506 symbol_to_string(ct->data.referent, TRUE, ch, dest_size - (ch - dest));
00507 break;
00508 case LESS_OR_EQUAL_TEST:
00509 strncpy(ch, "<= ", dest_size - (ch - dest));
00510 ch[dest_size - (ch - dest) - 1] = 0;
00511 while (*ch)
00512 ch++;
00513 symbol_to_string(ct->data.referent, TRUE, ch, dest_size - (ch - dest));
00514 break;
00515 case GREATER_OR_EQUAL_TEST:
00516 strncpy(ch, ">= ", dest_size - (ch - dest));
00517 ch[dest_size - (ch - dest) - 1] = 0;
00518 while (*ch)
00519 ch++;
00520 symbol_to_string(ct->data.referent, TRUE, ch, dest_size - (ch - dest));
00521 break;
00522 case SAME_TYPE_TEST:
00523 strncpy(ch, "<=> ", dest_size - (ch - dest));
00524 ch[dest_size - (ch - dest) - 1] = 0;
00525 while (*ch)
00526 ch++;
00527 symbol_to_string(ct->data.referent, TRUE, ch, dest_size - (ch - dest));
00528 break;
00529 case DISJUNCTION_TEST:
00530 strncpy(ch, "<< ", dest_size - (ch - dest));
00531 ch[dest_size - (ch - dest) - 1] = 0;
00532 while (*ch)
00533 ch++;
00534 for (c = ct->data.disjunction_list; c != NIL; c = c->rest) {
00535 symbol_to_string(c->first, TRUE, ch, dest_size - (ch - dest));
00536 while (*ch)
00537 ch++;
00538 *(ch++) = ' ';
00539 }
00540 strncpy(ch, ">>", dest_size - (ch - dest));
00541 ch[dest_size - (ch - dest) - 1] = 0;
00542 break;
00543 case CONJUNCTIVE_TEST:
00544 strncpy(ch, "{ ", dest_size - (ch - dest));
00545 ch[dest_size - (ch - dest) - 1] = 0;
00546 while (*ch)
00547 ch++;
00548 for (c = ct->data.conjunct_list; c != NIL; c = c->rest) {
00549 test_to_string(c->first, ch, dest_size - (ch - dest));
00550 while (*ch)
00551 ch++;
00552 *(ch++) = ' ';
00553 }
00554 strncpy(ch, "}", dest_size - (ch - dest));
00555 ch[dest_size - (ch - dest) - 1] = 0;
00556 break;
00557 case GOAL_ID_TEST:
00558 strncpy(dest, "[GOAL ID TEST]", dest_size);
00559 dest[dest_size - 1] = 0;
00560 break;
00561 case IMPASSE_ID_TEST:
00562 strncpy(dest, "[IMPASSE ID TEST]", dest_size);
00563 dest[dest_size - 1] = 0;
00564 break;
00565 }
00566 return dest;
00567 }
00568
00569 char *rhs_value_to_string(rhs_value rv, char *dest, size_t dest_size)
00570 {
00571 cons *c;
00572 list *fl;
00573 rhs_function *rf;
00574 char *ch;
00575
00576 if (rhs_value_is_reteloc(rv)) {
00577 char msg[MESSAGE_SIZE];
00578 strncpy(msg, "Internal error: rhs_value_to_string called on reteloc.\n", MESSAGE_SIZE);
00579 msg[MESSAGE_SIZE - 1] = 0;
00580 abort_with_fatal_error(msg);
00581 }
00582
00583 if (rhs_value_is_symbol(rv)) {
00584 return symbol_to_string(rhs_value_to_symbol(rv), TRUE, dest, dest_size);
00585 }
00586
00587 fl = rhs_value_to_funcall_list(rv);
00588 rf = fl->first;
00589
00590 if (!dest) {
00591 dest = current_agent(printed_output_string);
00592 dest_size = PRINTED_OUTPUT_STRING_SIZE;
00593 }
00594 ch = dest;
00595
00596 strncpy(ch, "(", dest_size - (ch - dest));
00597 ch[dest_size - (ch - dest) - 1] = 0;
00598 while (*ch)
00599 ch++;
00600
00601 if (!strcmp(rf->name->sc.name, "+")) {
00602 strncpy(ch, "(", dest_size - (ch - dest));
00603 ch[dest_size - (ch - dest) - 1] = 0;
00604 } else if (!strcmp(rf->name->sc.name, "-")) {
00605 strncpy(ch, "-", dest_size - (ch - dest));
00606 ch[dest_size - (ch - dest) - 1] = 0;
00607 } else {
00608 symbol_to_string(rf->name, TRUE, ch, dest_size - (ch - dest));
00609 }
00610
00611 while (*ch)
00612 ch++;
00613 for (c = fl->rest; c != NIL; c = c->rest) {
00614 strncpy(ch, " ", dest_size - (ch - dest));
00615 ch[dest_size - (ch - dest) - 1] = 0;
00616 while (*ch)
00617 ch++;
00618 rhs_value_to_string(c->first, ch, dest_size - (ch - dest));
00619 while (*ch)
00620 ch++;
00621 }
00622 strncpy(ch, ")", dest_size - (ch - dest));
00623 ch[dest_size - (ch - dest) - 1] = 0;
00624 return dest;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 test id_test_to_match;
00640
00641 bool pick_conds_with_matching_id_test(dl_cons * dc)
00642 {
00643 condition *cond;
00644 cond = dc->item;
00645 if (cond->type == CONJUNCTIVE_NEGATION_CONDITION)
00646 return FALSE;
00647 return tests_are_equal(id_test_to_match, cond->data.tests.id_test);
00648 }
00649
00650 #define PRINT_CONDITION_LIST_TEMP_SIZE 10000
00651 void print_condition_list(condition * conds, int indent, bool internal)
00652 {
00653 bool did_one_line_already;
00654 dl_list *conds_not_yet_printed, *tail_of_conds_not_yet_printed;
00655 dl_list *conds_for_this_id;
00656 dl_cons *dc;
00657 condition *c;
00658 bool removed_goal_test, removed_impasse_test;
00659 test id_test;
00660
00661 if (!conds)
00662 return;
00663
00664 did_one_line_already = FALSE;
00665
00666
00667 conds_not_yet_printed = NIL;
00668 tail_of_conds_not_yet_printed = NIL;
00669 for (c = conds; c != NIL; c = c->next) {
00670 allocate_with_pool(¤t_agent(dl_cons_pool), &dc);
00671 dc->item = c;
00672 if (conds_not_yet_printed)
00673 tail_of_conds_not_yet_printed->next = dc;
00674 else
00675 conds_not_yet_printed = dc;
00676 dc->prev = tail_of_conds_not_yet_printed;
00677 tail_of_conds_not_yet_printed = dc;
00678 }
00679 tail_of_conds_not_yet_printed->next = NIL;
00680
00681
00682 while (conds_not_yet_printed) {
00683 if (did_one_line_already) {
00684 print("\n");
00685 print_spaces(indent);
00686 } else {
00687 did_one_line_already = TRUE;
00688 }
00689 dc = conds_not_yet_printed;
00690 remove_from_dll(conds_not_yet_printed, dc, next, prev);
00691 c = dc->item;
00692
00693 if (c->type == CONJUNCTIVE_NEGATION_CONDITION) {
00694 free_with_pool(¤t_agent(dl_cons_pool), dc);
00695 print_string("-{");
00696 print_condition_list(c->data.ncc.top, indent + 2, internal);
00697 print_string("}");
00698 continue;
00699 }
00700
00701
00702 removed_goal_test = removed_impasse_test = FALSE;
00703 id_test = copy_test_removing_goal_impasse_tests
00704 (c->data.tests.id_test, &removed_goal_test, &removed_impasse_test);
00705 id_test_to_match = copy_of_equality_test_found_in_test(id_test);
00706
00707
00708 conds_for_this_id = dc;
00709 dc->prev = NIL;
00710 if (internal) {
00711 dc->next = NIL;
00712
00713 } else {
00714 dc->next = extract_dl_list_elements(&conds_not_yet_printed, pick_conds_with_matching_id_test);
00715 }
00716
00717
00718 print_string(" (");
00719 if (removed_goal_test)
00720 print_string("state ");
00721 if (removed_impasse_test)
00722 print_string("impasse ");
00723 print_string(test_to_string(id_test, NULL, 0));
00724 deallocate_test(id_test_to_match);
00725 deallocate_test(id_test);
00726 while (conds_for_this_id) {
00727 dc = conds_for_this_id;
00728 conds_for_this_id = conds_for_this_id->next;
00729 c = dc->item;
00730 free_with_pool(¤t_agent(dl_cons_pool), dc);
00731
00732 {
00733 char temp[PRINT_CONDITION_LIST_TEMP_SIZE], *ch;
00734
00735 ch = temp;
00736
00737 strncpy(ch, " ", PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp));
00738 ch[PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp) - 1] = 0;
00739 if (c->type == NEGATIVE_CONDITION) {
00740 strncat(ch, "-", PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp));
00741 ch[PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp) - 1] = 0;
00742 while (*ch)
00743 ch++;
00744 }
00745
00746 strncat(ch, "^", PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp));
00747 ch[PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp) - 1] = 0;
00748 while (*ch)
00749 ch++;
00750
00751 test_to_string(c->data.tests.attr_test, ch, PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp));
00752 while (*ch)
00753 ch++;
00754 if (!test_is_blank_test(c->data.tests.value_test)) {
00755 *(ch++) = ' ';
00756 test_to_string(c->data.tests.value_test, ch, PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp));
00757 while (*ch)
00758 ch++;
00759 if (c->test_for_acceptable_preference) {
00760 strncpy(ch, " +", PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp));
00761 ch[PRINT_CONDITION_LIST_TEMP_SIZE - (ch - temp) - 1] = 0;
00762 while (*ch)
00763 ch++;
00764 }
00765 }
00766 *ch = 0;
00767 if (current_agent(printer_output_column) + (ch - temp) >= COLUMNS_PER_LINE) {
00768 print_string("\n");
00769 print_spaces(indent + 6);
00770 }
00771 print_string(temp);
00772 }
00773 }
00774
00775 print_string(")");
00776 }
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 Symbol *action_id_to_match;
00793
00794 bool pick_actions_with_matching_id(dl_cons * dc)
00795 {
00796 action *a;
00797 a = dc->item;
00798 if (a->type != MAKE_ACTION)
00799 return FALSE;
00800 return (bool) (rhs_value_to_symbol(a->id) == action_id_to_match);
00801 }
00802
00803 #define PRINT_ACTION_LIST_TEMP_SIZE 10000
00804 void print_action_list(action * actions, int indent, bool internal)
00805 {
00806 bool did_one_line_already;
00807 dl_list *actions_not_yet_printed, *tail_of_actions_not_yet_printed;
00808 dl_list *actions_for_this_id;
00809 dl_cons *dc;
00810 action *a;
00811
00812 if (!actions)
00813 return;
00814
00815 did_one_line_already = FALSE;
00816
00817
00818 actions_not_yet_printed = NIL;
00819 tail_of_actions_not_yet_printed = NIL;
00820 for (a = actions; a != NIL; a = a->next) {
00821 allocate_with_pool(¤t_agent(dl_cons_pool), &dc);
00822 dc->item = a;
00823 if (actions_not_yet_printed)
00824 tail_of_actions_not_yet_printed->next = dc;
00825 else
00826 actions_not_yet_printed = dc;
00827 dc->prev = tail_of_actions_not_yet_printed;
00828 tail_of_actions_not_yet_printed = dc;
00829 }
00830 tail_of_actions_not_yet_printed->next = NIL;
00831
00832
00833 while (actions_not_yet_printed) {
00834 if (did_one_line_already) {
00835 print("\n");
00836 print_spaces(indent);
00837 } else {
00838 did_one_line_already = TRUE;
00839 }
00840 dc = actions_not_yet_printed;
00841 remove_from_dll(actions_not_yet_printed, dc, next, prev);
00842 a = dc->item;
00843 if (a->type == FUNCALL_ACTION) {
00844 free_with_pool(¤t_agent(dl_cons_pool), dc);
00845 print_string(rhs_value_to_string(a->value, NULL, 0));
00846 continue;
00847 }
00848
00849
00850
00851 actions_for_this_id = dc;
00852 action_id_to_match = rhs_value_to_symbol(a->id);
00853 dc->prev = NIL;
00854 if (internal) {
00855 dc->next = NIL;
00856 } else {
00857 dc->next = extract_dl_list_elements(&actions_not_yet_printed, pick_actions_with_matching_id);
00858 }
00859
00860
00861 print_with_symbols("(%y", action_id_to_match);
00862 while (actions_for_this_id) {
00863 dc = actions_for_this_id;
00864 actions_for_this_id = actions_for_this_id->next;
00865 a = dc->item;
00866 free_with_pool(¤t_agent(dl_cons_pool), dc);
00867
00868 {
00869 char temp[PRINT_ACTION_LIST_TEMP_SIZE], *ch;
00870
00871 ch = temp;
00872 strncpy(ch, " ^", PRINT_ACTION_LIST_TEMP_SIZE - (ch - temp));
00873 ch[PRINT_ACTION_LIST_TEMP_SIZE - (ch - temp) - 1] = 0;
00874 while (*ch)
00875 ch++;
00876 rhs_value_to_string(a->attr, ch, PRINT_ACTION_LIST_TEMP_SIZE - (ch - temp));
00877 while (*ch)
00878 ch++;
00879 *(ch++) = ' ';
00880 rhs_value_to_string(a->value, ch, PRINT_ACTION_LIST_TEMP_SIZE - (ch - temp));
00881 while (*ch)
00882 ch++;
00883 *(ch++) = ' ';
00884 *(ch++) = preference_type_indicator(a->preference_type);
00885 if (preference_is_binary(a->preference_type)) {
00886 *(ch++) = ' ';
00887 rhs_value_to_string(a->referent, ch, PRINT_ACTION_LIST_TEMP_SIZE - (ch - temp));
00888 while (*ch)
00889 ch++;
00890 }
00891 *ch = 0;
00892 if (current_agent(printer_output_column) + (ch - temp) >= COLUMNS_PER_LINE) {
00893 print_string("\n");
00894 print_spaces(indent + 6);
00895 }
00896 print_string(temp);
00897 }
00898 }
00899 print_string(")");
00900 }
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910 void print_production(production * p, bool internal)
00911 {
00912 condition *top, *bottom;
00913 action *rhs;
00914
00915
00916 print_with_symbols("sp {%y\n", p->name);
00917
00918 if (p->documentation) {
00919 char temp[MAX_LEXEME_LENGTH * 2 + 10];
00920 string_to_escaped_string(p->documentation, '"', temp);
00921 print(" %s\n", temp);
00922 }
00923
00924 switch (p->type) {
00925 case DEFAULT_PRODUCTION_TYPE:
00926 print_string(" :default\n");
00927 break;
00928 case USER_PRODUCTION_TYPE:
00929 break;
00930 case CHUNK_PRODUCTION_TYPE:
00931 print_string(" :chunk\n");
00932 break;
00933 case JUSTIFICATION_PRODUCTION_TYPE:
00934 print_string(" :justification ;# not reloadable\n");
00935 break;
00936 }
00937 if (p->declared_support == DECLARED_O_SUPPORT)
00938 print_string(" :o-support\n");
00939 else if (p->declared_support == DECLARED_I_SUPPORT)
00940 print_string(" :i-support\n");
00941 #ifdef MATCHTIME_INTERRUPT
00942 if (p->interrupt)
00943 print_string(" :interrupt\n");
00944 #endif
00945
00946
00947 p_node_to_conditions_and_nots(p->p_node, NIL, NIL, &top, &bottom, NIL, &rhs);
00948 print_string(" ");
00949 print_condition_list(top, 3, internal);
00950 deallocate_condition_list(top);
00951 print_string("\n -->\n ");
00952 print_string(" ");
00953 print_action_list(rhs, 4, internal);
00954 print_string("\n}\n");
00955 deallocate_action_list(rhs);
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 void print_condition(condition * cond)
00978 {
00979 condition *old_next, *old_prev;
00980
00981 old_next = cond->next;
00982 old_prev = cond->prev;
00983 cond->next = NIL;
00984 cond->prev = NIL;
00985 print_condition_list(cond, 0, TRUE);
00986 cond->next = old_next;
00987 cond->prev = old_prev;
00988 }
00989
00990 void print_action(action * a)
00991 {
00992 action *old_next;
00993
00994 old_next = a->next;
00995 a->next = NIL;
00996 print_action_list(a, 0, TRUE);
00997 a->next = old_next;
00998 }
00999
01000 char preference_type_indicator(byte type)
01001 {
01002 switch (type) {
01003 case ACCEPTABLE_PREFERENCE_TYPE:
01004 return '+';
01005 case REQUIRE_PREFERENCE_TYPE:
01006 return '!';
01007 case REJECT_PREFERENCE_TYPE:
01008 return '-';
01009 case PROHIBIT_PREFERENCE_TYPE:
01010 return '~';
01011 case RECONSIDER_PREFERENCE_TYPE:
01012 return '@';
01013 case UNARY_INDIFFERENT_PREFERENCE_TYPE:
01014 return '=';
01015 case BINARY_INDIFFERENT_PREFERENCE_TYPE:
01016 return '=';
01017 case UNARY_PARALLEL_PREFERENCE_TYPE:
01018 return '&';
01019 case BINARY_PARALLEL_PREFERENCE_TYPE:
01020 return '&';
01021 case BEST_PREFERENCE_TYPE:
01022 return '>';
01023 case BETTER_PREFERENCE_TYPE:
01024 return '>';
01025 case WORST_PREFERENCE_TYPE:
01026 return '<';
01027 case WORSE_PREFERENCE_TYPE:
01028 return '<';
01029 default:
01030 {
01031 char msg[MESSAGE_SIZE];
01032 strncpy(msg, "print.c: Error: bad type passed to preference_type_indicator\n", MESSAGE_SIZE);
01033 msg[MESSAGE_SIZE - 1] = 0;
01034 abort_with_fatal_error(msg);
01035 }
01036 }
01037 return 0;
01038 }
01039
01040 void print_preference(preference * pref)
01041 {
01042 print_with_symbols("(%y ^%y %y ", pref->id, pref->attr, pref->value);
01043 print("%c", preference_type_indicator(pref->type));
01044 if (preference_is_binary(pref->type)) {
01045 print_with_symbols(" %y", pref->referent);
01046 }
01047 if (pref->o_supported)
01048 print_string(" :O ");
01049 print_string(")");
01050 print("\n");
01051 }
01052
01053 void detailed_print_preference(preference * pref)
01054 {
01055 int i, end;
01056 char space[48];
01057
01058 print_with_symbols("(%y ^%y %y ", pref->id, pref->attr, pref->value);
01059 print("%c", preference_type_indicator(pref->type));
01060 if (preference_is_binary(pref->type)) {
01061 print_with_symbols(" %y", pref->referent);
01062 }
01063 if (pref->o_supported)
01064 print_string(" :O ");
01065
01066 end = 37 - get_printer_output_column();
01067 for (i = 0; i < end; i++) {
01068 space[i] = ' ';
01069
01070 }
01071 space[i] = '\0';
01072
01073 print(")%s", space);
01074 print(" (refs, in-tm, addr) (%lu, %d, %p)", pref->reference_count, pref->in_tm, pref);
01075 print("\n");
01076 }
01077
01078 void watchful_print_preference(preference * pref)
01079 {
01080 int i, end;
01081 char space[48];
01082
01083 print_with_symbols("(%y ^%y %y ", pref->id, pref->attr, pref->value);
01084 print("%c", preference_type_indicator(pref->type));
01085 if (preference_is_binary(pref->type)) {
01086 print_with_symbols(" %y", pref->referent);
01087 }
01088 if (pref->o_supported)
01089 print_string(" :O ");
01090
01091 end = 37 - get_printer_output_column();
01092 for (i = 0; i < end; i++) {
01093 space[i] = ' ';
01094
01095 }
01096 space[i] = '\0';
01097
01098 print(")%s", space);
01099 print(" (id->id.level) (%d)", pref->id->id.level);
01100 print("\n");
01101 }
01102
01103
01104 extern bool passes_wme_filtering(wme * w, bool isAdd);
01105 void filtered_print_wme_add(wme * w)
01106 {
01107 if (passes_wme_filtering(w, TRUE)) {
01108 print("=>WM: ");
01109 print_wme(w);
01110 }
01111 }
01112 void filtered_print_wme_remove(wme * w)
01113 {
01114 if (passes_wme_filtering(w, FALSE)) {
01115 print("<=WM: ");
01116 print_wme(w);
01117 }
01118 }
01119
01120
01121
01122 void print_wme(wme * w)
01123 {
01124 print("(%lu: ", w->timetag);
01125 print_with_symbols("%y ^%y %y", w->id, w->attr, w->value);
01126 if (w->acceptable)
01127 print_string(" +");
01128 print(")\n");
01129 }
01130
01131 void detailed_print_wme(wme * w)
01132 {
01133 int end, i;
01134 char space[48];
01135
01136 print("(%lu: ", w->timetag);
01137 print_with_symbols("%y ^%y %y", w->id, w->attr, w->value);
01138 if (w->acceptable)
01139 print_string(" +");
01140
01141 end = 37 - get_printer_output_column();
01142 for (i = 0; i < end; i++) {
01143 space[i] = ' ';
01144
01145 }
01146 space[i] = '\0';
01147
01148 print(")%s", space);
01149
01150 print("(refs, addr) (%lu, %p)", w->reference_count, w);
01151 print("\n");
01152
01153 }
01154
01155 void print_instantiation_with_wmes(instantiation * inst, wme_trace_type wtt)
01156 {
01157 condition *cond;
01158
01159 if (inst->prod)
01160 print_with_symbols("%y", inst->prod->name);
01161 else
01162 print("[dummy production]");
01163 print("\n");
01164
01165 if (wtt == NONE_WME_TRACE)
01166 return;
01167
01168 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next)
01169 if (cond->type == POSITIVE_CONDITION) {
01170 switch (wtt) {
01171 case TIMETAG_WME_TRACE:
01172 print(" %lu", cond->bt.wme->timetag);
01173 break;
01174 case FULL_WME_TRACE:
01175 print(" ");
01176 print_wme(cond->bt.wme);
01177 break;
01178 }
01179 }
01180 }
01181
01182
01183
01184
01185
01186 void print_list_of_conditions(condition * cond)
01187 {
01188
01189 while (cond != NULL) {
01190 if (get_printer_output_column() >= COLUMNS_PER_LINE - 20)
01191 print("\n ");
01192 print_condition(cond);
01193 print("\n");
01194
01195 cond = cond->next;
01196 }
01197 }