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 #include "soarkernel.h"
00050 #include <ctype.h>
00051
00052 extern list *collect_root_variables(condition *, tc_number, bool);
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #define add_to_os_tc_if_needed(sym) \
00070 { if ((sym)->common.symbol_type==IDENTIFIER_SYMBOL_TYPE) \
00071 add_to_os_tc (sym,FALSE); }
00072
00073 #define add_to_os_tc_if_id(sym,flag) \
00074 { if ((sym)->common.symbol_type==IDENTIFIER_SYMBOL_TYPE) \
00075 add_to_os_tc (sym,flag); }
00076
00077
00078
00079
00080
00081
00082
00083 void add_to_os_tc(Symbol * id, bool isa_state)
00084 {
00085 slot *s;
00086 preference *pref;
00087 wme *w;
00088
00089
00090 if (id->id.tc_num == current_agent(o_support_tc))
00091 return;
00092 id->id.tc_num = current_agent(o_support_tc);
00093
00094
00095 for (w = id->id.input_wmes; w != NIL; w = w->next)
00096 add_to_os_tc_if_needed(w->value);
00097 for (s = id->id.slots; s != NIL; s = s->next) {
00098 if ((!isa_state) || (s->attr != current_agent(operator_symbol))) {
00099 for (pref = s->all_preferences; pref != NIL; pref = pref->all_of_slot_next) {
00100 add_to_os_tc_if_needed(pref->value);
00101 if (preference_is_binary(pref->type))
00102 add_to_os_tc_if_needed(pref->referent);
00103 }
00104 for (w = s->wmes; w != NIL; w = w->next)
00105 add_to_os_tc_if_needed(w->value);
00106 }
00107 }
00108
00109 for (pref = current_agent(rhs_prefs_from_instantiation); pref != NIL; pref = pref->inst_next) {
00110 if (pref->id == id) {
00111 if ((!isa_state) || (pref->attr != current_agent(operator_symbol))) {
00112 add_to_os_tc_if_needed(pref->value);
00113 if (preference_is_binary(pref->type))
00114 add_to_os_tc_if_needed(pref->referent);
00115 }
00116 }
00117 }
00118
00119
00120
00121 }
00122
00123 void begin_os_tc(preference * rhs_prefs_or_nil)
00124 {
00125 current_agent(o_support_tc) = get_new_tc_number();
00126 current_agent(rhs_prefs_from_instantiation) = rhs_prefs_or_nil;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 bool test_has_id_in_os_tc(test t, Symbol * excluded_sym)
00143 {
00144 cons *c;
00145 Symbol *referent;
00146 complex_test *ct;
00147
00148 if (test_is_blank_test(t))
00149 return FALSE;
00150 if (test_is_blank_or_equality_test(t)) {
00151 referent = referent_of_equality_test(t);
00152 if (referent->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00153 if (referent->id.tc_num == current_agent(o_support_tc))
00154 if (referent != excluded_sym)
00155 return TRUE;
00156 return FALSE;
00157 }
00158 ct = complex_test_from_test(t);
00159 if (ct->type == CONJUNCTIVE_TEST) {
00160 for (c = ct->data.conjunct_list; c != NIL; c = c->rest)
00161 if (test_has_id_in_os_tc(c->first, excluded_sym))
00162 return TRUE;
00163 return FALSE;
00164 }
00165 return FALSE;
00166 }
00167
00168 bool id_or_value_of_condition_list_is_in_os_tc(condition * conds,
00169 Symbol * sym_excluded_from_value,
00170 Symbol * match_state_to_exclude_test_of_the_operator_off_of)
00171 {
00172
00173
00174 for (; conds != NIL; conds = conds->next) {
00175 switch (conds->type) {
00176 case POSITIVE_CONDITION:
00177 case NEGATIVE_CONDITION:
00178 if (test_includes_equality_test_for_symbol(conds->data.tests.id_test,
00179 match_state_to_exclude_test_of_the_operator_off_of) &&
00180 test_includes_equality_test_for_symbol(conds->data.tests.attr_test, current_agent(operator_symbol)))
00181 break;
00182 if (test_has_id_in_os_tc(conds->data.tests.id_test, NIL))
00183 return TRUE;
00184 if (test_has_id_in_os_tc(conds->data.tests.value_test, sym_excluded_from_value))
00185 return TRUE;
00186 break;
00187 case CONJUNCTIVE_NEGATION_CONDITION:
00188 if (id_or_value_of_condition_list_is_in_os_tc(conds->data.ncc.top,
00189 sym_excluded_from_value,
00190 match_state_to_exclude_test_of_the_operator_off_of))
00191 return TRUE;
00192 break;
00193 }
00194 }
00195 return FALSE;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 bool is_state_id(Symbol * sym, Symbol * match_state)
00211 {
00212 Symbol *c;
00213
00214 for (c = current_agent(top_goal); c != match_state; c = c->id.lower_goal) {
00215 if (sym == c)
00216 return TRUE;
00217 }
00218
00219 if (sym == match_state)
00220 return TRUE;
00221 else
00222 return FALSE;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 void calculate_support_for_instantiation_preferences(instantiation * inst)
00271 {
00272 Symbol *match_goal, *match_state, *match_operator;
00273 wme *match_operator_wme;
00274 bool lhs_tests_operator_installed;
00275 bool lhs_tests_operator_acceptable_or_installed;
00276 bool lhs_is_known_to_test_something_off_match_state;
00277 bool lhs_is_known_to_test_something_off_match_operator;
00278 bool rhs_does_an_operator_creation;
00279 bool oc_support_possible;
00280 bool om_support_possible;
00281 bool oa_support_possible;
00282 preference *rhs, *pref;
00283 wme *w;
00284 condition *lhs, *c;
00285
00286
00287
00288 action *act;
00289 bool o_support, op_elab;
00290 bool operator_proposal;
00291 char action_attr[ACTION_ATTR_SIZE];
00292 int pass;
00293 wme *lowest_goal_wme;
00294
00295
00296
00297
00298
00299 #ifndef SOAR_8_ONLY
00300 if (current_agent(operand2_mode) == TRUE) {
00301 #endif
00302
00303 if (current_agent(soar_verbose_flag) == TRUE)
00304 print("\n in calculate_support_for_instantiation_preferences:");
00305 o_support = FALSE;
00306 op_elab = FALSE;
00307
00308 #if defined(OPTIMIZE_TOP_LEVEL_RESULTS) || defined(THIN_JUSTIFICATIONS)
00309 if (!inst->prod) {
00310 o_support = TRUE;
00311 } else if
00312 #else
00313 if
00314 #endif
00315 (inst->prod->declared_support == DECLARED_O_SUPPORT)
00316 o_support = TRUE;
00317 else if (inst->prod->declared_support == DECLARED_I_SUPPORT)
00318 o_support = FALSE;
00319 else if (inst->prod->declared_support == UNDECLARED_SUPPORT) {
00320
00321
00322
00323
00324
00325
00326 operator_proposal = FALSE;
00327 for (act = inst->prod->action_list; act != NIL; act = act->next) {
00328 if ((act->type == MAKE_ACTION) && (rhs_value_is_symbol(act->attr))) {
00329 if ((strcmp(rhs_value_to_string(act->attr, action_attr, ACTION_ATTR_SIZE),
00330 "operator") == NIL) && (act->preference_type == ACCEPTABLE_PREFERENCE_TYPE)) {
00331
00332
00333 operator_proposal = TRUE;
00334 o_support = FALSE;
00335 break;
00336 }
00337 }
00338 }
00339
00340 if (operator_proposal == FALSE) {
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 lowest_goal_wme = NIL;
00364
00365 for (pass = 0; pass != 2; pass++) {
00366
00367 for (c = inst->top_of_instantiated_conditions; c != NIL; c = c->next) {
00368 if (c->type == POSITIVE_CONDITION) {
00369 w = c->bt.wme;
00370
00371 if (pass == 0) {
00372
00373 if (w->id->id.isa_goal == TRUE) {
00374
00375 if (lowest_goal_wme == NIL)
00376 lowest_goal_wme = w;
00377
00378 else {
00379 if (w->id->id.level > lowest_goal_wme->id->id.level)
00380 lowest_goal_wme = w;
00381 }
00382 }
00383
00384 }
00385
00386 else {
00387 if ((w->attr == current_agent(operator_symbol)) &&
00388 (w->acceptable == FALSE) && (w->id == lowest_goal_wme->id)) {
00389
00390 if (current_agent(o_support_calculation_type) == 3 ||
00391 current_agent(o_support_calculation_type) == 4) {
00392
00393
00394
00395
00396
00397 for (act = inst->prod->action_list; act != NIL; act = act->next) {
00398 if (act->type == MAKE_ACTION) {
00399 if ((rhs_value_is_symbol(act->id)) &&
00400 (rhs_value_to_symbol(act->id) == w->value)) {
00401 op_elab = TRUE;
00402 } else if (current_agent(o_support_calculation_type) == 4 &&
00403 (rhs_value_is_reteloc(act->id)) &&
00404 w->value ==
00405 get_symbol_from_rete_loc((byte)
00406 rhs_value_to_reteloc_levels_up(act->
00407 id),
00408 (byte)
00409 rhs_value_to_reteloc_field_num(act->
00410 id),
00411 inst->rete_token, w)) {
00412 op_elab = TRUE;
00413
00414 } else {
00415
00416 o_support = TRUE;
00417 }
00418 }
00419 }
00420 } else {
00421 o_support = TRUE;
00422 break;
00423 }
00424 }
00425 }
00426 }
00427 }
00428 }
00429 }
00430 }
00431
00432
00433 if ((current_agent(o_support_calculation_type) == 3 ||
00434 current_agent(o_support_calculation_type) == 4) && (o_support == TRUE)) {
00435
00436 if (op_elab == TRUE) {
00437
00438
00439 if (current_agent(o_support_calculation_type) == 3 && current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM]) {
00440
00441 print_with_symbols
00442 ("\nWARNING: operator elaborations mixed with operator applications\nget o_support in prod %y",
00443 inst->prod->name);
00444 o_support = TRUE;
00445 } else if (current_agent(o_support_calculation_type) == 4 &&
00446 current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM]) {
00447
00448 print_with_symbols
00449 ("\nWARNING: operator elaborations mixed with operator applications\nget i_support in prod %y",
00450 inst->prod->name);
00451 o_support = FALSE;
00452 }
00453 }
00454
00455 }
00456
00457
00458
00459
00460 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next)
00461 pref->o_supported = o_support;
00462
00463 goto o_support_done;
00464 #ifndef SOAR_8_ONLY
00465 }
00466 #endif
00467
00468
00469
00470
00471 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next)
00472 pref->o_supported = FALSE;
00473
00474
00475 match_goal = inst->match_goal;
00476 if (!match_goal)
00477 goto o_support_done;
00478
00479 match_state = match_goal;
00480
00481 match_operator_wme = match_goal->id.operator_slot->wmes;
00482 if (match_operator_wme)
00483 match_operator = match_operator_wme->value;
00484 else
00485 match_operator = NIL;
00486
00487 lhs = inst->top_of_instantiated_conditions;
00488 rhs = inst->preferences_generated;
00489
00490
00491 rhs_does_an_operator_creation = FALSE;
00492
00493 for (pref = rhs; pref != NIL; pref = pref->inst_next) {
00494 if ((pref->id == match_goal) &&
00495 (pref->attr == current_agent(operator_symbol)) &&
00496 ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE)))
00497 rhs_does_an_operator_creation = TRUE;
00498 }
00499
00500
00501 lhs_tests_operator_acceptable_or_installed = FALSE;
00502 lhs_tests_operator_installed = FALSE;
00503 lhs_is_known_to_test_something_off_match_state = FALSE;
00504 lhs_is_known_to_test_something_off_match_operator = FALSE;
00505
00506 for (c = lhs; c != NIL; c = c->next) {
00507 if (c->type != POSITIVE_CONDITION)
00508 continue;
00509 w = c->bt.wme;
00510
00511
00512 if ((w->id == match_state) && (w->attr != current_agent(operator_symbol)))
00513 lhs_is_known_to_test_something_off_match_state = TRUE;
00514 if (w->id == match_operator)
00515 lhs_is_known_to_test_something_off_match_operator = TRUE;
00516 if (w == match_operator_wme)
00517 lhs_tests_operator_installed = TRUE;
00518 if ((w->id == match_goal) && (w->attr == current_agent(operator_symbol)))
00519 lhs_tests_operator_acceptable_or_installed = TRUE;
00520 }
00521
00522
00523 oa_support_possible = lhs_tests_operator_installed;
00524 oc_support_possible = rhs_does_an_operator_creation;
00525 om_support_possible = lhs_tests_operator_acceptable_or_installed;
00526
00527 if ((!oa_support_possible) && (!oc_support_possible) && (!om_support_possible))
00528 goto o_support_done;
00529
00530 if (!lhs_is_known_to_test_something_off_match_state) {
00531 begin_os_tc(NIL);
00532 add_to_os_tc_if_id(match_state, TRUE);
00533 if (!id_or_value_of_condition_list_is_in_os_tc(lhs, match_state, match_state)) {
00534 oc_support_possible = FALSE;
00535 om_support_possible = FALSE;
00536 }
00537 }
00538
00539 if (oa_support_possible) {
00540 if (!lhs_is_known_to_test_something_off_match_operator) {
00541 begin_os_tc(NIL);
00542 add_to_os_tc_if_id(match_operator, FALSE);
00543 if (!id_or_value_of_condition_list_is_in_os_tc(lhs, match_operator, NIL))
00544 oa_support_possible = FALSE;
00545 }
00546 }
00547
00548
00549 if (oa_support_possible) {
00550 begin_os_tc(rhs);
00551 add_to_os_tc_if_id(match_state, TRUE);
00552 for (pref = rhs; pref != NIL; pref = pref->inst_next) {
00553 if (pref->id->id.tc_num == current_agent(o_support_tc))
00554
00555
00556
00557
00558
00559
00560 if (!((pref->attr == current_agent(operator_symbol)) && (is_state_id(pref->id, match_state))))
00561
00562 pref->o_supported = TRUE;
00563 }
00564 }
00565
00566
00567 if (oc_support_possible) {
00568 begin_os_tc(rhs);
00569 for (pref = rhs; pref != NIL; pref = pref->inst_next) {
00570 if ((pref->id == match_goal) &&
00571 (pref->attr == current_agent(operator_symbol)) &&
00572 ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE))) {
00573 add_to_os_tc_if_id(pref->value, FALSE);
00574 }
00575 }
00576 for (pref = rhs; pref != NIL; pref = pref->inst_next) {
00577
00578 if ((pref->id->id.tc_num == current_agent(o_support_tc)) && (pref->id != match_state))
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 pref->o_supported = TRUE;
00600 }
00601 }
00602
00603
00604 if (om_support_possible) {
00605 begin_os_tc(rhs);
00606 for (c = inst->top_of_instantiated_conditions; c != NIL; c = c->next)
00607 if (c->type == POSITIVE_CONDITION) {
00608 w = c->bt.wme;
00609 if ((w->id == match_goal) && (w->attr == current_agent(operator_symbol)))
00610 add_to_os_tc_if_id(w->value, FALSE);
00611 }
00612 for (pref = rhs; pref != NIL; pref = pref->inst_next)
00613 if (pref->id->id.tc_num == current_agent(o_support_tc))
00614 pref->o_supported = TRUE;
00615 }
00616
00617 o_support_done:{
00618 }
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 void dougs_calculate_support_for_instantiation_preferences(instantiation * inst)
00662 {
00663 Symbol *match_state;
00664 bool rule_2_or_3, anything_added;
00665 preference *rhs, *pref;
00666 wme *w;
00667 condition *lhs, *c;
00668
00669 lhs = inst->top_of_instantiated_conditions;
00670 rhs = inst->preferences_generated;
00671 match_state = inst->match_goal;
00672
00673
00674 rule_2_or_3 = FALSE;
00675 for (c = lhs; c != NIL; c = c->next) {
00676 if (c->type != POSITIVE_CONDITION)
00677 continue;
00678 w = c->bt.wme;
00679 if ((w->id == match_state) && (w->attr == current_agent(operator_symbol))) {
00680 rule_2_or_3 = TRUE;
00681 break;
00682 }
00683 }
00684
00685
00686 for (pref = rhs; pref != NIL; pref = pref->inst_next)
00687 pref->o_supported = rule_2_or_3;
00688
00689
00690 if (!rule_2_or_3) {
00691 current_agent(o_support_tc) = get_new_tc_number();
00692
00693
00694 anything_added = FALSE;
00695
00696 for (pref = rhs; pref != NIL; pref = pref->inst_next) {
00697 if ((pref->id == match_state) &&
00698 (pref->attr == current_agent(operator_symbol)) &&
00699 ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) ||
00700 (pref->type == REQUIRE_PREFERENCE_TYPE)) &&
00701 (pref->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)) {
00702 pref->value->id.tc_num = current_agent(o_support_tc);
00703 anything_added = TRUE;
00704 }
00705 }
00706
00707 while (anything_added) {
00708 anything_added = FALSE;
00709 for (pref = rhs; pref != NIL; pref = pref->inst_next) {
00710 if (pref->id->id.tc_num != current_agent(o_support_tc))
00711 continue;
00712 if (pref->o_supported)
00713 continue;
00714 pref->o_supported = TRUE;
00715 anything_added = TRUE;
00716 if (pref->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00717 pref->value->id.tc_num = current_agent(o_support_tc);
00718 if ((preference_is_binary(pref->type)) &&
00719 (pref->referent->common.symbol_type == IDENTIFIER_SYMBOL_TYPE))
00720 pref->referent->id.tc_num = current_agent(o_support_tc);
00721 }
00722 }
00723 }
00724
00725
00726 for (pref = rhs; pref != NIL; pref = pref->inst_next)
00727 if ((pref->id == match_state) && (pref->attr == current_agent(operator_symbol)))
00728 pref->o_supported = FALSE;
00729 }
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 typedef enum yes_no_maybe_enum { YES, NO, MAYBE } yes_no_maybe;
00749
00750 yes_no_maybe test_is_for_symbol(test t, Symbol * sym)
00751 {
00752 cons *c;
00753 yes_no_maybe temp;
00754 bool maybe_found;
00755 complex_test *ct;
00756 Symbol *referent;
00757
00758 if (test_is_blank_test(t))
00759 return MAYBE;
00760
00761 if (test_is_blank_or_equality_test(t)) {
00762 referent = referent_of_equality_test(t);
00763 if (referent == sym)
00764 return YES;
00765 if (referent->common.symbol_type == VARIABLE_SYMBOL_TYPE)
00766 return MAYBE;
00767 if (sym->common.symbol_type == VARIABLE_SYMBOL_TYPE)
00768 return MAYBE;
00769 return NO;
00770 }
00771
00772 ct = complex_test_from_test(t);
00773
00774 switch (ct->type) {
00775 case DISJUNCTION_TEST:
00776 if (sym->common.symbol_type == VARIABLE_SYMBOL_TYPE)
00777 return MAYBE;
00778 if (member_of_list(sym, ct->data.disjunction_list))
00779 return MAYBE;
00780 return NO;
00781 case CONJUNCTIVE_TEST:
00782 maybe_found = FALSE;
00783 for (c = ct->data.conjunct_list; c != NIL; c = c->rest) {
00784 temp = test_is_for_symbol(c->first, sym);
00785 if (temp == YES)
00786 return YES;
00787 if (temp == MAYBE)
00788 maybe_found = TRUE;
00789 }
00790 if (maybe_found)
00791 return MAYBE;
00792 return NO;
00793 default:
00794 return MAYBE;
00795 }
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 list *find_known_goals(condition * lhs)
00810 {
00811 tc_number tc;
00812 list *vars;
00813 condition *c;
00814
00815 tc = get_new_tc_number();
00816 vars = NIL;
00817 for (c = lhs; c != NIL; c = c->next) {
00818 if (c->type != POSITIVE_CONDITION)
00819 continue;
00820 if (test_includes_goal_or_impasse_id_test(c->data.tests.id_test, TRUE, FALSE))
00821 add_bound_variables_in_test(c->data.tests.id_test, tc, &vars);
00822 }
00823 return vars;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 Symbol *find_compile_time_match_goal(condition * lhs, list * known_goals)
00839 {
00840 tc_number tc;
00841 list *roots;
00842 list *root_goals;
00843 int num_root_goals;
00844 cons *c, *prev_c, *next_c;
00845 Symbol *result;
00846 condition *cond;
00847
00848
00849 tc = get_new_tc_number();
00850 roots = collect_root_variables(lhs, tc, FALSE);
00851
00852
00853 root_goals = NIL;
00854 num_root_goals = 0;
00855 for (c = roots; c != NIL; c = c->rest)
00856 if (member_of_list(c->first, known_goals)) {
00857 push(c->first, root_goals);
00858 num_root_goals++;
00859 }
00860 free_list(roots);
00861
00862
00863 if (num_root_goals > 1) {
00864 for (cond = lhs; cond != NIL; cond = cond->next) {
00865 if ((cond->type == POSITIVE_CONDITION) &&
00866 (test_is_for_symbol(cond->data.tests.attr_test, current_agent(superstate_symbol)) == YES) &&
00867 (test_is_for_symbol(cond->data.tests.value_test, current_agent(nil_symbol)) == YES)) {
00868 prev_c = NIL;
00869 for (c = root_goals; c != NIL; c = next_c) {
00870 next_c = c->rest;
00871 if (test_is_for_symbol(cond->data.tests.id_test, c->first) == YES) {
00872
00873 if (prev_c)
00874 prev_c->rest = next_c;
00875 else
00876 root_goals = next_c;
00877 free_cons(c);
00878 num_root_goals--;
00879 if (num_root_goals == 1)
00880 break;
00881 } else {
00882 prev_c = c;
00883 }
00884 }
00885 if (num_root_goals == 1)
00886 break;
00887 }
00888 }
00889 }
00890
00891
00892 if (num_root_goals == 1)
00893 result = root_goals->first;
00894 else
00895 result = NIL;
00896
00897
00898 free_list(root_goals);
00899 return result;
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 Symbol *find_thing_off_goal(condition * lhs, Symbol * goal, Symbol * attr)
00916 {
00917 condition *c;
00918 list *vars;
00919 tc_number tc;
00920 Symbol *result;
00921
00922 for (c = lhs; c != NIL; c = c->next) {
00923 if (c->type != POSITIVE_CONDITION)
00924 continue;
00925 if (test_is_for_symbol(c->data.tests.id_test, goal) != YES)
00926 continue;
00927 if (test_is_for_symbol(c->data.tests.attr_test, attr) != YES)
00928 continue;
00929 if (c->test_for_acceptable_preference)
00930 continue;
00931 tc = get_new_tc_number();
00932 vars = NIL;
00933 add_bound_variables_in_test(c->data.tests.value_test, tc, &vars);
00934 if (vars) {
00935 result = vars->first;
00936 free_list(vars);
00937 return result;
00938 }
00939 }
00940 return NIL;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 bool condition_list_has_id_test_for_sym(condition * conds, Symbol * sym)
00952 {
00953 for (; conds != NIL; conds = conds->next) {
00954 switch (conds->type) {
00955 case POSITIVE_CONDITION:
00956 case NEGATIVE_CONDITION:
00957 if (test_includes_equality_test_for_symbol(conds->data.tests.id_test, sym))
00958 return TRUE;
00959 break;
00960 case CONJUNCTIVE_NEGATION_CONDITION:
00961 if (condition_list_has_id_test_for_sym(conds->data.ncc.top, sym))
00962 return TRUE;
00963 break;
00964 }
00965 }
00966 return FALSE;
00967 }
00968
00969
00970
00971
00972
00973
00974
00975 bool match_state_tests_non_operator_slot(condition * conds, Symbol * match_state)
00976 {
00977 yes_no_maybe ynm;
00978
00979 for (; conds != NIL; conds = conds->next) {
00980 switch (conds->type) {
00981 case POSITIVE_CONDITION:
00982 case NEGATIVE_CONDITION:
00983 if (test_includes_equality_test_for_symbol(conds->data.tests.id_test, match_state)) {
00984 ynm = test_is_for_symbol(conds->data.tests.attr_test, current_agent(operator_symbol));
00985 if (ynm == NO)
00986 return TRUE;
00987 }
00988 break;
00989 case CONJUNCTIVE_NEGATION_CONDITION:
00990 if (match_state_tests_non_operator_slot(conds->data.ncc.top, match_state))
00991 return TRUE;
00992 break;
00993 }
00994 }
00995 return FALSE;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 void add_tc_through_lhs_and_rhs(condition * lhs, action * rhs, tc_number tc, list ** id_list, list ** var_list)
01008 {
01009 condition *c;
01010 action *a;
01011 bool anything_changed;
01012
01013 for (c = lhs; c != NIL; c = c->next)
01014 c->already_in_tc = FALSE;
01015 for (a = rhs; a != NIL; a = a->next)
01016 a->already_in_tc = FALSE;
01017
01018
01019 for (;;) {
01020 anything_changed = FALSE;
01021 for (c = lhs; c != NIL; c = c->next)
01022 if (!c->already_in_tc)
01023 if (cond_is_in_tc(c, tc)) {
01024 add_cond_to_tc(c, tc, id_list, var_list);
01025 c->already_in_tc = TRUE;
01026 anything_changed = TRUE;
01027 }
01028 for (a = rhs; a != NIL; a = a->next)
01029 if (!a->already_in_tc)
01030 if (action_is_in_tc(a, tc)) {
01031 add_action_to_tc(a, tc, id_list, var_list);
01032 a->already_in_tc = TRUE;
01033 anything_changed = TRUE;
01034 }
01035 if (!anything_changed)
01036 break;
01037 }
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 void calculate_compile_time_o_support(condition * lhs, action * rhs)
01050 {
01051 list *known_goals;
01052 cons *c;
01053 Symbol *match_state, *match_operator;
01054 yes_no_maybe lhs_oa_support, lhs_oc_support, lhs_om_support;
01055 action *a;
01056 condition *cond;
01057 yes_no_maybe ynm;
01058 bool operator_found, possible_operator_found;
01059 tc_number tc;
01060
01061
01062 for (a = rhs; a != NIL; a = a->next)
01063 if (a->type == MAKE_ACTION)
01064 a->support = UNKNOWN_SUPPORT;
01065
01066
01067
01068 operator_found = FALSE;
01069 possible_operator_found = FALSE;
01070 for (cond = lhs; cond != NIL; cond = cond->next) {
01071 if (cond->type != POSITIVE_CONDITION)
01072 continue;
01073 ynm = test_is_for_symbol(cond->data.tests.attr_test, current_agent(operator_symbol));
01074 if (ynm == YES) {
01075 operator_found = possible_operator_found = TRUE;
01076 break;
01077 }
01078 if (ynm == MAYBE)
01079 possible_operator_found = TRUE;
01080 }
01081 if (!operator_found)
01082 for (a = rhs; a != NIL; a = a->next) {
01083 if (a->type != MAKE_ACTION)
01084 continue;
01085 if (rhs_value_is_symbol(a->attr)) {
01086 Symbol *attr;
01087 attr = rhs_value_to_symbol(a->attr);
01088 if (attr == current_agent(operator_symbol)) {
01089 operator_found = possible_operator_found = TRUE;
01090 break;
01091 }
01092 if (attr->common.symbol_type == VARIABLE_SYMBOL_TYPE)
01093 possible_operator_found = TRUE;
01094 } else {
01095 possible_operator_found = TRUE;
01096 }
01097 }
01098 if (!possible_operator_found) {
01099 for (a = rhs; a != NIL; a = a->next) {
01100 if (a->type == MAKE_ACTION)
01101 a->support = I_SUPPORT;
01102 }
01103 return;
01104 }
01105
01106
01107 known_goals = find_known_goals(lhs);
01108
01109
01110 for (c = known_goals; c != NIL; c = c->rest)
01111 for (a = rhs; a != NIL; a = a->next) {
01112 if (a->type != MAKE_ACTION)
01113 continue;
01114 if (rhs_value_is_symbol(a->attr) &&
01115 rhs_value_to_symbol(a->attr) == current_agent(operator_symbol) &&
01116 (rhs_value_to_symbol(a->id) == c->first))
01117 a->support = I_SUPPORT;
01118 }
01119
01120
01121 match_state = find_compile_time_match_goal(lhs, known_goals);
01122 free_list(known_goals);
01123 if (!match_state)
01124 return;
01125 match_operator = find_thing_off_goal(lhs, match_state, current_agent(operator_symbol));
01126
01127
01128
01129
01130
01131
01132 if (possible_operator_found && !operator_found) {
01133 possible_operator_found = FALSE;
01134 for (cond = lhs; cond != NIL; cond = cond->next) {
01135 if (cond->type != POSITIVE_CONDITION)
01136 continue;
01137 ynm = test_is_for_symbol(cond->data.tests.attr_test, current_agent(operator_symbol));
01138 if ((ynm != NO) && (test_is_for_symbol(cond->data.tests.attr_test, match_state) != YES)) {
01139 possible_operator_found = TRUE;
01140 break;
01141 }
01142 }
01143 if (!possible_operator_found) {
01144 for (a = rhs; a != NIL; a = a->next) {
01145 if (a->type != MAKE_ACTION)
01146 continue;
01147
01148
01149 if (rhs_value_to_symbol(a->id) == match_state)
01150 continue;
01151 if (rhs_value_is_symbol(a->attr)) {
01152 Symbol *attr;
01153 attr = rhs_value_to_symbol(a->attr);
01154 if ((attr->common.symbol_type == VARIABLE_SYMBOL_TYPE) && (attr != match_state)) {
01155 possible_operator_found = TRUE;
01156 break;
01157 }
01158 } else {
01159 possible_operator_found = TRUE;
01160 break;
01161 }
01162 }
01163 }
01164 if (!possible_operator_found) {
01165 for (a = rhs; a != NIL; a = a->next)
01166 if (a->type == MAKE_ACTION)
01167 a->support = I_SUPPORT;
01168 return;
01169 }
01170 }
01171
01172
01173 lhs_oa_support = MAYBE;
01174 if (match_operator)
01175
01176
01177 if ((condition_list_has_id_test_for_sym(lhs, match_operator)) &&
01178 (match_state_tests_non_operator_slot(lhs, match_state)))
01179
01180
01181 lhs_oa_support = YES;
01182
01183 lhs_oc_support = MAYBE;
01184 lhs_om_support = MAYBE;
01185
01186
01187
01188
01189 if (match_state_tests_non_operator_slot(lhs, match_state)) {
01190
01191
01192 lhs_oc_support = YES;
01193 for (cond = lhs; cond != NIL; cond = cond->next) {
01194 if (cond->type != POSITIVE_CONDITION)
01195 continue;
01196 if (test_is_for_symbol(cond->data.tests.id_test, match_state) != YES)
01197 continue;
01198 if (test_is_for_symbol(cond->data.tests.attr_test, current_agent(operator_symbol))
01199 != YES)
01200 continue;
01201 lhs_om_support = YES;
01202 break;
01203 }
01204 }
01205
01206 if (lhs_oa_support == YES) {
01207
01208 tc = get_new_tc_number();
01209 add_symbol_to_tc(match_state, tc, NIL, NIL);
01210 add_tc_through_lhs_and_rhs(lhs, rhs, tc, NIL, NIL);
01211
01212
01213 for (a = rhs; a != NIL; a = a->next) {
01214
01215 if (action_is_in_tc(a, tc)) {
01216
01217
01218
01219
01220
01221 if (rhs_value_is_symbol(a->attr) && (rhs_value_to_symbol(a->attr) == current_agent(operator_symbol))) {
01222 if (a->support != I_SUPPORT)
01223 a->support = UNKNOWN_SUPPORT;
01224 } else {
01225 if (a->support != I_SUPPORT)
01226 a->support = O_SUPPORT;
01227 }
01228
01229 }
01230 }
01231 }
01232
01233 if (lhs_oc_support == YES) {
01234
01235 tc = get_new_tc_number();
01236 for (a = rhs; a != NIL; a = a->next) {
01237 if (a->type != MAKE_ACTION)
01238 continue;
01239 if ((rhs_value_to_symbol(a->id) == match_state) &&
01240 (rhs_value_is_symbol(a->attr)) &&
01241 (rhs_value_to_symbol(a->attr) == current_agent(operator_symbol)) &&
01242 ((a->preference_type == ACCEPTABLE_PREFERENCE_TYPE) ||
01243 (a->preference_type == REQUIRE_PREFERENCE_TYPE))) {
01244 if (rhs_value_is_symbol(a->value)) {
01245 add_symbol_to_tc(rhs_value_to_symbol(a->value), tc, NIL, NIL);
01246 }
01247 }
01248 }
01249 add_tc_through_lhs_and_rhs(lhs, rhs, tc, NIL, NIL);
01250
01251
01252 for (a = rhs; a != NIL; a = a->next)
01253
01254 if (action_is_in_tc(a, tc)) {
01255
01256
01257
01258
01259
01260
01261
01262
01263 if (a->support != I_SUPPORT)
01264 a->support = O_SUPPORT;
01265
01266
01267
01268
01269
01270
01271
01272 #ifndef SOAR_8_ONLY
01273 if (current_agent(operand2_mode) == TRUE) {
01274 #endif
01275 if (current_agent(soar_verbose_flag) == TRUE)
01276 print("\n operator creation: setting a->support to I_SUPPORT");
01277
01278 a->support = I_SUPPORT;
01279 #ifndef SOAR_8_ONLY
01280 }
01281 #endif
01282
01283
01284 }
01285 }
01286
01287 if (lhs_om_support == YES) {
01288
01289 tc = get_new_tc_number();
01290 for (cond = lhs; cond != NIL; cond = cond->next) {
01291 if (cond->type != POSITIVE_CONDITION)
01292 continue;
01293 if (test_is_for_symbol(cond->data.tests.id_test, match_state) == YES)
01294 if (test_is_for_symbol(cond->data.tests.attr_test, current_agent(operator_symbol))
01295 == YES)
01296 add_bound_variables_in_test(cond->data.tests.value_test, tc, NIL);
01297 }
01298 add_tc_through_lhs_and_rhs(lhs, rhs, tc, NIL, NIL);
01299
01300
01301 for (a = rhs; a != NIL; a = a->next)
01302
01303 if (action_is_in_tc(a, tc)) {
01304
01305 if (a->support != I_SUPPORT)
01306 a->support = O_SUPPORT;
01307
01308 }
01309 }
01310 }