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
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "soarkernel.h"
00063
00064 #include <time.h>
00065 #include "rhsfun_math.h"
00066 #include "rhsfun.h"
00067
00068 rhs_function *available_rhs_functions = NIL;
00069
00070 void add_rhs_function(Symbol * name,
00071 rhs_function_routine f,
00072 int num_args_expected, bool can_be_rhs_value, bool can_be_stand_alone_action)
00073 {
00074 rhs_function *rf;
00075
00076 if ((!can_be_rhs_value) && (!can_be_stand_alone_action)) {
00077 print("Internal error: attempt to add_rhs_function that can't appear anywhere\n");
00078 return;
00079 }
00080 for (rf = available_rhs_functions; rf != NIL; rf = rf->next)
00081 if (rf->name == name)
00082 break;
00083 if (rf) {
00084 print_with_symbols("Internal error: attempt to add_rhs_function that already exists: %y\n", name);
00085 return;
00086 }
00087 rf = allocate_memory(sizeof(rhs_function), MISCELLANEOUS_MEM_USAGE);
00088 rf->next = available_rhs_functions;
00089 available_rhs_functions = rf;
00090 rf->name = name;
00091 rf->f = f;
00092 rf->num_args_expected = num_args_expected;
00093 rf->can_be_rhs_value = can_be_rhs_value;
00094 rf->can_be_stand_alone_action = can_be_stand_alone_action;
00095 }
00096
00097 rhs_function *lookup_rhs_function(Symbol * name)
00098 {
00099 rhs_function *rf;
00100
00101 for (rf = available_rhs_functions; rf != NIL; rf = rf->next)
00102 if (rf->name == name)
00103 return rf;
00104 return NIL;
00105 }
00106
00107 void remove_rhs_function(Symbol * name)
00108 {
00109
00110 rhs_function *rf = NIL, *prev;
00111
00112
00113 for (prev = NIL, rf = available_rhs_functions; rf != NIL; prev = rf, rf = rf->next)
00114 if (rf->name == name)
00115 break;
00116
00117
00118 if (rf == NIL) {
00119 fprintf(stderr, "Internal error: attempt to remove_rhs_function that does not exist.\n");
00120 print_with_symbols("Internal error: attempt to remove_rhs_function that does not exist: %y\n", name);
00121 }
00122
00123
00124 else {
00125
00126
00127 if (prev == NIL)
00128 available_rhs_functions = rf->next;
00129 else
00130 prev->next = rf->next;
00131
00132 free_memory(rf, MISCELLANEOUS_MEM_USAGE);
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 Symbol *user_select_rhsfun(list * args)
00147 {
00148 Symbol *uselect;
00149
00150 uselect = args->first;
00151
00152 if (!strcmp(uselect->sc.name, "first")) {
00153 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_FIRST);
00154 return NIL;
00155 }
00156
00157 if (!strcmp(uselect->sc.name, "last")) {
00158 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_LAST);
00159 return NIL;
00160 }
00161
00162 if ((!strcmp(uselect->sc.name, "ask")) || (!strcmp(uselect->sc.name, "t"))) {
00163 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_ASK);
00164 return NIL;
00165 }
00166 if ((!strcmp(uselect->sc.name, "random")) || (!strcmp(uselect->sc.name, "nil"))) {
00167 set_sysparam(USER_SELECT_MODE_SYSPARAM, USER_SELECT_RANDOM);
00168 return NIL;
00169 }
00170 print("Expected first, ask, or random for new value of user-select.\n");
00171
00172 return NIL;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181 Symbol *write_rhs_function_code(list * args)
00182 {
00183 Symbol *arg;
00184 char *string;
00185
00186 for (; args != NIL; args = args->rest) {
00187 arg = args->first;
00188
00189
00190 string = symbol_to_string(arg, FALSE, NIL, 0);
00191 print_string(string);
00192 }
00193 return NIL;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 Symbol *crlf_rhs_function_code(list * args)
00203 {
00204 args = args;
00205 return make_sym_constant("\n");
00206 }
00207
00208
00209
00210
00211
00212
00213
00214 Symbol *halt_rhs_function_code(list * args)
00215 {
00216 args = args;
00217 current_agent(system_halted) = TRUE;
00218 return NIL;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 char *RHS_interrupt_msg = "*** RHS Function Interrupt ***";
00232
00233 Symbol *interrupt_rhs_function_code(list * args)
00234 {
00235 char *ch;
00236
00237 cons *c;
00238 agent *the_agent;
00239
00240 args = args;
00241
00242 for (c = all_soar_agents; c != NIL; c = c->rest) {
00243 the_agent = ((agent *) c->first);
00244 the_agent->stop_soar = TRUE;
00245 the_agent->reason_for_stopping = RHS_interrupt_msg;
00246 }
00247
00248 strncpy(current_agent(interrupt_source), "*** Interrupt from production ", INTERRUPT_SOURCE_SIZE);
00249 current_agent(interrupt_source)[INTERRUPT_SOURCE_SIZE - 1] = 0;
00250 ch = current_agent(interrupt_source);
00251 while (*ch)
00252 ch++;
00253 symbol_to_string(current_agent(production_being_fired)->name, TRUE, ch,
00254 INTERRUPT_SOURCE_SIZE - (ch - current_agent(interrupt_source)));
00255 while (*ch)
00256 ch++;
00257 strncpy(ch, " ***", INTERRUPT_SOURCE_SIZE - (ch - current_agent(interrupt_source)));
00258 ch[INTERRUPT_SOURCE_SIZE - (ch - current_agent(interrupt_source)) - 1] = 0;
00259 current_agent(reason_for_stopping) = current_agent(interrupt_source);
00260 return NIL;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 #define MAKE_CONSTANT_SYMBOL_BUF_SIZE 1024
00273 Symbol *make_constant_symbol_rhs_function_code(list * args)
00274 {
00275 char buf[MAKE_CONSTANT_SYMBOL_BUF_SIZE];
00276 char *string;
00277 cons *c;
00278
00279 if (!args) {
00280 strncpy(buf, "constant", MAKE_CONSTANT_SYMBOL_BUF_SIZE);
00281 buf[MAKE_CONSTANT_SYMBOL_BUF_SIZE - 1] = 0;
00282 } else {
00283 buf[0] = 0;
00284 for (c = args; c != NIL; c = c->rest) {
00285 string = symbol_to_string(c->first, FALSE, NIL, 0);
00286 strncat(buf, string, MAKE_CONSTANT_SYMBOL_BUF_SIZE);
00287 buf[MAKE_CONSTANT_SYMBOL_BUF_SIZE - 1] = 0;
00288 }
00289 }
00290 if ((!args) && (!find_sym_constant(buf)))
00291 return make_sym_constant(buf);
00292 return generate_new_sym_constant(buf, ¤t_agent(mcs_counter));
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302 #define TIMESTAMP_RHS_FUNCTION_CODE_BUF_SIZE 100
00303 Symbol *timestamp_rhs_function_code(list * args)
00304 {
00305 long now;
00306 struct tm *temp;
00307 char buf[TIMESTAMP_RHS_FUNCTION_CODE_BUF_SIZE];
00308
00309 args = args;
00310
00311 now = time(NULL);
00312 #ifdef THINK_C
00313 temp = localtime((const time_t *) &now);
00314 #else
00315 #ifdef __SC__
00316 temp = localtime((const time_t *) &now);
00317 #else
00318 #ifdef __ultrix
00319 temp = localtime((const time_t *) &now);
00320 #else
00321 #ifdef MACINTOSH
00322 temp = localtime((const time_t *) &now);
00323 #else
00324 temp = localtime(&now);
00325 #endif
00326 #endif
00327 #endif
00328 #endif
00329 snprintf(buf, TIMESTAMP_RHS_FUNCTION_CODE_BUF_SIZE, "%d/%d/%d-%02d:%02d:%02d",
00330 temp->tm_mon + 1, temp->tm_mday, temp->tm_year, temp->tm_hour, temp->tm_min, temp->tm_sec);
00331 buf[TIMESTAMP_RHS_FUNCTION_CODE_BUF_SIZE - 1] = 0;
00332 return make_sym_constant(buf);
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342 Symbol *accept_rhs_function_code(list * args)
00343 {
00344 char buf[2000], *s;
00345 Symbol *sym;
00346
00347 args = args;
00348
00349 for (;;) {
00350 s = fgets(buf, 2000, stdin);
00351
00352 if (!s) {
00353
00354 return NIL;
00355 }
00356 s = buf;
00357 sym = get_next_io_symbol_from_text_input_line(&s);
00358 if (sym)
00359 break;
00360 }
00361 symbol_add_ref(sym);
00362 release_io_symbol(sym);
00363 return sym;
00364 }
00365
00366
00367
00368
00369
00370 #include <ctype.h>
00371
00372 Symbol *capitalize_symbol_rhs_function_code(list * args)
00373 {
00374 char *symbol_to_capitalize;
00375 Symbol *sym;
00376
00377 if (!args) {
00378 print("Error: 'capitalize-symbol' function called with no arguments.\n");
00379 return NIL;
00380 }
00381
00382 sym = (Symbol *) args->first;
00383 if (sym->common.symbol_type != SYM_CONSTANT_SYMBOL_TYPE) {
00384 print_with_symbols("Error: non-symbol (%y) passed to capitalize-symbol function.\n", sym);
00385 return NIL;
00386 }
00387
00388 if (args->rest) {
00389 print("Error: 'capitalize-symbol' takes exactly 1 argument.\n");
00390 return NIL;
00391 }
00392
00393 symbol_to_capitalize = symbol_to_string(sym, FALSE, NIL, 0);
00394 symbol_to_capitalize = savestring(symbol_to_capitalize);
00395 *symbol_to_capitalize = (char) toupper(*symbol_to_capitalize);
00396 return make_sym_constant(symbol_to_capitalize);
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 Symbol *ifeq_rhs_function_code(list * args)
00466 {
00467 Symbol *arg1, *arg2;
00468 cons *c;
00469
00470 if (!args) {
00471 print("Error: 'ifeq' function called with no arguments\n");
00472 return NIL;
00473 }
00474
00475
00476 arg1 = args->first;
00477 c = args->rest;
00478 arg2 = c->first;
00479 c = c->rest;
00480
00481 if (arg1 == arg2) {
00482 symbol_add_ref((Symbol *) (c->first));
00483 return c->first;
00484 } else if (c->rest) {
00485 symbol_add_ref((Symbol *) (c->rest->first));
00486 return c->rest->first;
00487 } else
00488 return NIL;
00489 }
00490
00491 Symbol *strlen_rhs_function_code(list * args)
00492 {
00493 Symbol *arg;
00494 char *string;
00495
00496 arg = args->first;
00497
00498
00499
00500 string = symbol_to_string(arg, FALSE, NIL, 0);
00501
00502 return make_int_constant(strlen(string));
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 Symbol *dont_learn_rhs_function_code(list * args)
00515 {
00516 Symbol *state;
00517
00518 if (!args) {
00519 print("Error: 'dont-learn' function called with no arg.\n");
00520 return NIL;
00521 }
00522
00523 state = (Symbol *) args->first;
00524 if (state->common.symbol_type != IDENTIFIER_SYMBOL_TYPE) {
00525 print_with_symbols("Error: non-identifier (%y) passed to dont-learn function.\n", state);
00526 return NIL;
00527 } else if (!state->id.isa_goal) {
00528 print_with_symbols("Error: identifier passed to dont-learn is not a state: %y.\n", state);
00529 }
00530
00531 if (args->rest) {
00532 print("Error: 'dont-learn' takes exactly 1 argument.\n");
00533 return NIL;
00534 }
00535
00536 if (!member_of_list(state, current_agent(chunk_free_problem_spaces))) {
00537 push(state, current_agent(chunk_free_problem_spaces));
00538
00539 }
00540 return NIL;
00541
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551 Symbol *force_learn_rhs_function_code(list * args)
00552 {
00553 Symbol *state;
00554
00555 if (!args) {
00556 print("Error: 'force-learn' function called with no arg.\n");
00557 return NIL;
00558 }
00559
00560 state = (Symbol *) args->first;
00561 if (state->common.symbol_type != IDENTIFIER_SYMBOL_TYPE) {
00562 print_with_symbols("Error: non-identifier (%y) passed to force-learn function.\n", state);
00563 return NIL;
00564 } else if (!state->id.isa_goal) {
00565 print_with_symbols("Error: identifier passed to force-learn is not a state: %y.\n", state);
00566 }
00567
00568 if (args->rest) {
00569 print("Error: 'force-learn' takes exactly 1 argument.\n");
00570 return NIL;
00571 }
00572
00573 if (!member_of_list(state, current_agent(chunky_problem_spaces))) {
00574 push(state, current_agent(chunky_problem_spaces));
00575
00576 }
00577 return NIL;
00578
00579 }
00580
00581
00582
00583
00584
00585
00586
00587 void init_built_in_rhs_functions(void)
00588 {
00589 add_rhs_function(make_sym_constant("write"), write_rhs_function_code, -1, FALSE, TRUE);
00590 add_rhs_function(make_sym_constant("crlf"), crlf_rhs_function_code, 0, TRUE, FALSE);
00591 add_rhs_function(make_sym_constant("halt"), halt_rhs_function_code, 0, FALSE, TRUE);
00592 add_rhs_function(make_sym_constant("interrupt"), interrupt_rhs_function_code, 0, FALSE, TRUE);
00593 add_rhs_function(make_sym_constant("make-constant-symbol"),
00594 make_constant_symbol_rhs_function_code, -1, TRUE, FALSE);
00595 add_rhs_function(make_sym_constant("timestamp"), timestamp_rhs_function_code, 0, TRUE, FALSE);
00596 add_rhs_function(make_sym_constant("accept"), accept_rhs_function_code, 0, TRUE, FALSE);
00597 add_rhs_function(make_sym_constant("capitalize-symbol"), capitalize_symbol_rhs_function_code, 1, TRUE, FALSE);
00598
00599 add_rhs_function(make_sym_constant("ifeq"), ifeq_rhs_function_code, 4, TRUE, FALSE);
00600 add_rhs_function(make_sym_constant("strlen"), strlen_rhs_function_code, 1, TRUE, FALSE);
00601
00602
00603 add_rhs_function(make_sym_constant("dont-learn"), dont_learn_rhs_function_code, 1, FALSE, TRUE);
00604 add_rhs_function(make_sym_constant("force-learn"), force_learn_rhs_function_code, 1, FALSE, TRUE);
00605
00606 init_built_in_rhs_math_functions();
00607 }
00608
00609 void remove_built_in_rhs_functions(void)
00610 {
00611
00612 remove_rhs_function(make_sym_constant("write"));
00613 remove_rhs_function(make_sym_constant("crlf"));
00614 remove_rhs_function(make_sym_constant("halt"));
00615 remove_rhs_function(make_sym_constant("interrupt"));
00616 remove_rhs_function(make_sym_constant("make-constant-symbol"));
00617 remove_rhs_function(make_sym_constant("timestamp"));
00618 remove_rhs_function(make_sym_constant("accept"));
00619 remove_rhs_function(make_sym_constant("capitalize-symbol"));
00620 remove_rhs_function(make_sym_constant("ifeq"));
00621 remove_rhs_function(make_sym_constant("strlen"));
00622 remove_rhs_function(make_sym_constant("dont-learn"));
00623 remove_rhs_function(make_sym_constant("force-learn"));
00624
00625 remove_built_in_rhs_math_functions();
00626 }