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 #include "soarkernel.h"
00054 #include <ctype.h>
00055
00056 #ifdef __hpux
00057 #ifndef _INCLUDE_POSIX_SOURCE
00058 #define _INCLUDE_POSIX_SOURCE
00059 #endif
00060 #define _INCLUDE_XOPEN_SOURCE
00061 #define _INCLUDE_HPUX_SOURCE
00062 #include <sys/types.h>
00063 #undef _INCLUDE_POSIX_SOURCE
00064 #undef _INCLUDE_XOPEN_SOURCE
00065 #endif
00066 #if !defined(__SC__) && !defined(THINK_C) && !defined(WIN32) && !defined(MACINTOSH)
00067 #include <sys/time.h>
00068 #endif
00069 #ifdef __hpux
00070 #undef _INCLUDE_HPUX_SOURCE
00071 #endif
00072
00073
00074
00075
00076 #ifdef NO_TOP_JUST
00077 void remove_top_level_justifications(instantiation * inst);
00078 #endif
00079
00080
00081
00082
00083
00084
00085 void build_prohibits_list(instantiation * inst)
00086 {
00087 condition *cond;
00088 preference *pref, *new_pref;
00089
00090 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next) {
00091 cond->bt.prohibits = NIL;
00092 if (cond->type == POSITIVE_CONDITION && cond->bt.trace) {
00093 if (cond->bt.trace->slot) {
00094 pref = cond->bt.trace->slot->preferences[PROHIBIT_PREFERENCE_TYPE];
00095 while (pref) {
00096 new_pref = NIL;
00097 if (pref->inst->match_goal_level == inst->match_goal_level && pref->in_tm) {
00098 push(pref, cond->bt.prohibits);
00099 preference_add_ref(pref);
00100 } else {
00101 new_pref = find_clone_for_level(pref, inst->match_goal_level);
00102 if (new_pref) {
00103 if (new_pref->in_tm) {
00104 push(new_pref, cond->bt.prohibits);
00105 preference_add_ref(new_pref);
00106 }
00107 }
00108 }
00109 pref = pref->next;
00110 }
00111 }
00112 }
00113 }
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 preference *find_clone_for_level(preference * p, goal_stack_level level)
00127 {
00128 preference *clone;
00129
00130 if (!p) {
00131
00132
00133 return NIL;
00134 }
00135
00136
00137
00138 #ifdef NO_TOP_JUST
00139 if (p->match_goal_level == level)
00140 return p;
00141
00142 for (clone = p->next_clone; clone != NIL; clone = clone->next_clone)
00143 if (clone->match_goal_level == level)
00144 return clone;
00145
00146 for (clone = p->prev_clone; clone != NIL; clone = clone->prev_clone)
00147 if (clone->match_goal_level == level)
00148 return clone;
00149 #else
00150
00151 if (p->inst->match_goal_level == level)
00152 return p;
00153
00154 for (clone = p->next_clone; clone != NIL; clone = clone->next_clone)
00155 if (clone->inst->match_goal_level == level)
00156 return clone;
00157
00158 for (clone = p->prev_clone; clone != NIL; clone = clone->prev_clone)
00159 if (clone->inst->match_goal_level == level)
00160 return clone;
00161
00162 #endif
00163
00164
00165 return NIL;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 void find_match_goal(instantiation * inst)
00185 {
00186 Symbol *lowest_goal_so_far;
00187 goal_stack_level lowest_level_so_far;
00188 condition *cond;
00189 Symbol *id;
00190
00191 lowest_goal_so_far = NIL;
00192 lowest_level_so_far = -1;
00193 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next)
00194 if (cond->type == POSITIVE_CONDITION) {
00195 id = cond->bt.wme->id;
00196 if (id->id.isa_goal)
00197 if (cond->bt.level > lowest_level_so_far) {
00198 lowest_goal_so_far = id;
00199 lowest_level_so_far = cond->bt.level;
00200 }
00201 }
00202
00203 inst->match_goal = lowest_goal_so_far;
00204 if (lowest_goal_so_far)
00205 inst->match_goal_level = lowest_level_so_far;
00206 else
00207 inst->match_goal_level = ATTRIBUTE_IMPASSE_LEVEL;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 long firer_highest_rhs_unboundvar_index;
00231
00232 Symbol *instantiate_rhs_value(rhs_value rv, goal_stack_level new_id_level,
00233 char new_id_letter, struct token_struct *tok, wme * w)
00234 {
00235 list *fl;
00236 list *arglist;
00237 cons *c, *prev_c, *arg_cons;
00238 rhs_function *rf;
00239 Symbol *result;
00240 bool nil_arg_found;
00241
00242 if (rhs_value_is_symbol(rv)) {
00243 result = rhs_value_to_symbol(rv);
00244 symbol_add_ref(result);
00245 return result;
00246 }
00247
00248 if (rhs_value_is_unboundvar(rv)) {
00249 long index;
00250 Symbol *sym;
00251
00252 index = rhs_value_to_unboundvar(rv);
00253 if (firer_highest_rhs_unboundvar_index < index)
00254 firer_highest_rhs_unboundvar_index = index;
00255 sym = *(current_agent(rhs_variable_bindings) + index);
00256
00257 if (!sym) {
00258 sym = make_new_identifier(new_id_letter, new_id_level);
00259 *(current_agent(rhs_variable_bindings) + index) = sym;
00260 return sym;
00261 } else if (sym->common.symbol_type == VARIABLE_SYMBOL_TYPE) {
00262 new_id_letter = *(sym->var.name + 1);
00263 sym = make_new_identifier(new_id_letter, new_id_level);
00264 *(current_agent(rhs_variable_bindings) + index) = sym;
00265 return sym;
00266 } else {
00267 symbol_add_ref(sym);
00268 return sym;
00269 }
00270 }
00271
00272 if (rhs_value_is_reteloc(rv)) {
00273 result = get_symbol_from_rete_loc((unsigned short) rhs_value_to_reteloc_levels_up(rv),
00274 (byte) rhs_value_to_reteloc_field_num(rv), tok, w);
00275 symbol_add_ref(result);
00276 return result;
00277 }
00278
00279 fl = rhs_value_to_funcall_list(rv);
00280 rf = fl->first;
00281
00282
00283 prev_c = NIL;
00284 nil_arg_found = FALSE;
00285 arglist = NIL;
00286 for (arg_cons = fl->rest; arg_cons != NIL; arg_cons = arg_cons->rest) {
00287 allocate_cons(&c);
00288 c->first = instantiate_rhs_value(arg_cons->first, new_id_level, new_id_letter, tok, w);
00289 if (!c->first)
00290 nil_arg_found = TRUE;
00291 if (prev_c)
00292 prev_c->rest = c;
00293 else
00294 arglist = c;
00295 prev_c = c;
00296 }
00297 if (prev_c)
00298 prev_c->rest = NIL;
00299 else
00300 arglist = NIL;
00301
00302
00303 if (!nil_arg_found)
00304 result = (*(rf->f)) (arglist);
00305 else
00306 result = NIL;
00307
00308
00309 for (c = arglist; c != NIL; c = c->rest)
00310 if (c->first)
00311 symbol_remove_ref((Symbol *) (c->first));
00312 free_list(arglist);
00313
00314 return result;
00315 }
00316
00317 preference *execute_action(action * a, struct token_struct * tok, wme * w)
00318 {
00319 Symbol *id, *attr, *value, *referent;
00320 char first_letter;
00321
00322 if (a->type == FUNCALL_ACTION) {
00323 value = instantiate_rhs_value(a->value, -1, 'v', tok, w);
00324 if (value)
00325 symbol_remove_ref(value);
00326 return NIL;
00327 }
00328
00329 attr = NIL;
00330 value = NIL;
00331 referent = NIL;
00332
00333 id = instantiate_rhs_value(a->id, -1, 's', tok, w);
00334 if (!id)
00335 goto abort_execute_action;
00336 if (id->common.symbol_type != IDENTIFIER_SYMBOL_TYPE) {
00337 print_with_symbols("Error: RHS makes a preference for %y (not an identifier)\n", id);
00338 goto abort_execute_action;
00339 }
00340
00341 attr = instantiate_rhs_value(a->attr, id->id.level, 'a', tok, w);
00342 if (!attr)
00343 goto abort_execute_action;
00344
00345 first_letter = first_letter_from_symbol(attr);
00346
00347 value = instantiate_rhs_value(a->value, id->id.level, first_letter, tok, w);
00348 if (!value)
00349 goto abort_execute_action;
00350
00351 if (preference_is_binary(a->preference_type)) {
00352 referent = instantiate_rhs_value(a->referent, id->id.level, first_letter, tok, w);
00353 if (!referent)
00354 goto abort_execute_action;
00355 }
00356
00357
00358 if (((a->preference_type != ACCEPTABLE_PREFERENCE_TYPE) &&
00359 (a->preference_type != REJECT_PREFERENCE_TYPE)) &&
00360 (!(id->id.isa_goal && (attr == current_agent(operator_symbol))))) {
00361
00362 #ifndef SOAR_8_ONLY
00363 if ((current_agent(attribute_preferences_mode) == 2) || (current_agent(operand2_mode) == TRUE)) {
00364 #endif
00365 print_with_symbols("\nError: attribute preference other than +/- for %y ^%y -- ignoring it.", id, attr);
00366 goto abort_execute_action;
00367
00368 #ifndef SOAR_8_ONLY
00369 } else if (current_agent(attribute_preferences_mode) == 1) {
00370 print_with_symbols("\nWarning: attribute preference other than +/- for %y ^%y.", id, attr);
00371 }
00372 #endif
00373
00374 }
00375
00376 return make_preference(a->preference_type, id, attr, value, referent);
00377
00378 abort_execute_action:
00379 if (id)
00380 symbol_remove_ref(id);
00381 if (attr)
00382 symbol_remove_ref(attr);
00383 if (value)
00384 symbol_remove_ref(value);
00385 if (referent)
00386 symbol_remove_ref(referent);
00387 return NIL;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 void fill_in_new_instantiation_stuff(instantiation * inst, bool need_to_do_support_calculations)
00415 {
00416 condition *cond;
00417 preference *p;
00418 goal_stack_level level;
00419
00420 #if defined(OPTIMIZE_TOP_LEVEL_RESULTS) || ( defined(THIN_JUSTIFICATIONS) && !defined(MAKE_PRODUCTION_FOR_THIN_JUSTS))
00421 if (inst->prod)
00422 #endif
00423 production_add_ref(inst->prod);
00424
00425 find_match_goal(inst);
00426
00427 level = inst->match_goal_level;
00428
00429 #ifdef NO_TOP_JUST
00430
00431
00432
00433
00434 for (p = inst->preferences_generated; p != NIL; p = p->inst_next) {
00435 p->match_goal = inst->match_goal;
00436 p->match_goal_level = inst->match_goal_level;
00437 }
00438
00439 #endif
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next)
00456 if (cond->type == POSITIVE_CONDITION) {
00457
00458
00459
00460 #ifdef NO_TOP_LEVEL_REFS
00461 if (level > 1) {
00462 wme_add_ref(cond->bt.wme);
00463 }
00464 #else
00465 wme_add_ref(cond->bt.wme);
00466 #endif
00467
00468
00469 if (cond->bt.trace) {
00470
00471 #ifdef NO_TOP_JUST
00472 if (cond->bt.trace->match_goal_level > level)
00473 cond->bt.trace = find_clone_for_level(cond->bt.trace, level);
00474 #else
00475
00476 if (cond->bt.trace->inst->match_goal_level > level)
00477 cond->bt.trace = find_clone_for_level(cond->bt.trace, level);
00478 #endif
00479
00480
00481 #ifdef NO_TOP_LEVEL_REFS
00482 if ((cond->bt.trace) && (level > 1)) {
00483 preference_add_ref(cond->bt.trace);
00484 }
00485 #else
00486 if (cond->bt.trace)
00487 preference_add_ref(cond->bt.trace);
00488 #endif
00489 }
00490
00491 }
00492
00493
00494
00495 if (inst->match_goal) {
00496 for (p = inst->preferences_generated; p != NIL; p = p->inst_next) {
00497 insert_at_head_of_dll(inst->match_goal->id.preferences_from_goal, p, all_of_goal_next, all_of_goal_prev);
00498 p->on_goal_list = TRUE;
00499 }
00500 }
00501 inst->backtrace_number = 0;
00502
00503 if (current_agent(o_support_calculation_type) == 0 ||
00504 current_agent(o_support_calculation_type) == 3 || current_agent(o_support_calculation_type) == 4) {
00505
00506 if (need_to_do_support_calculations)
00507 calculate_support_for_instantiation_preferences(inst);
00508 } else if (current_agent(o_support_calculation_type) == 1) {
00509 if (need_to_do_support_calculations)
00510 calculate_support_for_instantiation_preferences(inst);
00511
00512 if ((inst->prod->declared_support != DECLARED_O_SUPPORT) &&
00513 (inst->prod->declared_support != DECLARED_I_SUPPORT)) {
00514
00515
00516
00517 list *saved_flags;
00518 preference *pref;
00519 bool difference_found;
00520 saved_flags = NIL;
00521 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next)
00522 push((pref->o_supported ? pref : NIL), saved_flags);
00523 saved_flags = destructively_reverse_list(saved_flags);
00524 dougs_calculate_support_for_instantiation_preferences(inst);
00525 difference_found = FALSE;
00526 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
00527 cons *c;
00528 bool b;
00529 c = saved_flags;
00530 saved_flags = c->rest;
00531 b = (bool) (c->first ? TRUE : FALSE);
00532 free_cons(c);
00533 if (pref->o_supported != b)
00534 difference_found = TRUE;
00535 pref->o_supported = b;
00536 }
00537 if (difference_found) {
00538 print_with_symbols("\n*** O-support difference found in production %y", inst->prod->name);
00539 }
00540 }
00541 } else {
00542
00543 if ((inst->prod->declared_support != DECLARED_O_SUPPORT) &&
00544 (inst->prod->declared_support != DECLARED_I_SUPPORT)) {
00545 dougs_calculate_support_for_instantiation_preferences(inst);
00546 }
00547 }
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 void init_firer(void)
00577 {
00578 init_memory_pool(¤t_agent(instantiation_pool), sizeof(instantiation), "instantiation");
00579 }
00580
00581
00582
00583
00584 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00585
00586 #define trace_firings_of_inst(inst) \
00587 ((inst)->prod && \
00588 (current_agent(sysparams)[TRACE_FIRINGS_OF_USER_PRODS_SYSPARAM+(inst)->prod->type] || \
00589 ((inst)->prod->trace_firings)))
00590
00591 #endif
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 void create_instantiation(production * prod, struct token_struct *tok, wme * w)
00602 {
00603 instantiation *inst;
00604 condition *cond;
00605 preference *pref;
00606 action *a;
00607 cons *c;
00608 bool need_to_do_support_calculations;
00609 bool trace_it;
00610 long index;
00611 Symbol **cell;
00612
00613 #ifdef BUG_139_WORKAROUND
00614
00615 if (prod->type == JUSTIFICATION_PRODUCTION_TYPE) {
00616 return;
00617 }
00618 #endif
00619
00620 allocate_with_pool(¤t_agent(instantiation_pool), &inst);
00621 inst->next = current_agent(newly_created_instantiations);
00622 current_agent(newly_created_instantiations) = inst;
00623 inst->prod = prod;
00624 inst->rete_token = tok;
00625 inst->rete_wme = w;
00626 inst->okay_to_variablize = TRUE;
00627 inst->in_ms = TRUE;
00628
00629
00630
00631
00632
00633
00634 inst->GDS_evaluated_already = FALSE;
00635
00636 #ifndef SOAR_8_ONLY
00637 if (current_agent(operand2_mode) == TRUE) {
00638 #endif
00639 if (current_agent(soar_verbose_flag) == TRUE)
00640 print_with_symbols("\n in create_instantiation: %y", inst->prod->name);
00641 #ifndef SOAR_8_ONLY
00642 }
00643 #endif
00644
00645
00646 current_agent(production_being_fired) = inst->prod;
00647 prod->firing_count++;
00648 current_agent(production_firing_count)++;
00649
00650
00651 p_node_to_conditions_and_nots(prod->p_node, tok, w,
00652 &(inst->top_of_instantiated_conditions),
00653 &(inst->bottom_of_instantiated_conditions), &(inst->nots), NIL);
00654
00655
00656 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next) {
00657 if (cond->type == POSITIVE_CONDITION) {
00658 cond->bt.level = cond->bt.wme->id->id.level;
00659 cond->bt.trace = cond->bt.wme->preference;
00660
00661 }
00662 }
00663
00664 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00665
00666
00667 trace_it = (bool) trace_firings_of_inst(inst);
00668 if (trace_it) {
00669 if (get_printer_output_column() != 1)
00670 print("\n");
00671 print("Firing ");
00672 print_instantiation_with_wmes
00673 (inst, (wme_trace_type) current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM]);
00674 }
00675 #endif
00676
00677
00678
00679
00680 index = 0;
00681 cell = current_agent(rhs_variable_bindings);
00682 for (c = prod->rhs_unbound_variables; c != NIL; c = c->rest) {
00683 *(cell++) = c->first;
00684 index++;
00685 }
00686 firer_highest_rhs_unboundvar_index = index - 1;
00687
00688
00689
00690
00691
00692 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00693
00694 if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) {
00695 print(" -->\n");
00696 }
00697 #endif
00698
00699
00700 inst->preferences_generated = NIL;
00701 need_to_do_support_calculations = FALSE;
00702 for (a = prod->action_list; a != NIL; a = a->next) {
00703 pref = execute_action(a, tok, w);
00704 if (pref) {
00705 pref->inst = inst;
00706 insert_at_head_of_dll(inst->preferences_generated, pref, inst_next, inst_prev);
00707 if (inst->prod->declared_support == DECLARED_O_SUPPORT)
00708 pref->o_supported = TRUE;
00709 else if (inst->prod->declared_support == DECLARED_I_SUPPORT)
00710 pref->o_supported = FALSE;
00711
00712 else {
00713
00714 #ifndef SOAR_8_ONLY
00715 if (current_agent(operand2_mode) == TRUE) {
00716 #endif
00717 pref->o_supported = (bool) ((current_agent(FIRING_TYPE) == PE_PRODS) ? TRUE : FALSE);
00718
00719 #ifndef SOAR_8_ONLY
00720 }
00721
00722
00723
00724 else {
00725 if (a->support == O_SUPPORT)
00726 pref->o_supported = TRUE;
00727 else if (a->support == I_SUPPORT)
00728 pref->o_supported = FALSE;
00729 else {
00730 need_to_do_support_calculations = TRUE;
00731 if (current_agent(soar_verbose_flag) == TRUE)
00732 print("\n\nin create_instantiation(): need_to_do_support_calculations == TRUE!!!\n\n");
00733 }
00734
00735 }
00736 #endif
00737
00738 }
00739 }
00740 }
00741
00742
00743 index = 0;
00744 cell = current_agent(rhs_variable_bindings);
00745 while (index++ <= firer_highest_rhs_unboundvar_index)
00746 *(cell++) = NIL;
00747
00748
00749 fill_in_new_instantiation_stuff(inst, need_to_do_support_calculations);
00750
00751 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00752
00753
00754
00755
00756 if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) {
00757 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
00758 print(" ");
00759 print_preference(pref);
00760 }
00761 }
00762 #endif
00763
00764
00765 build_prohibits_list(inst);
00766
00767 current_agent(production_being_fired) = NIL;
00768
00769
00770 chunk_instantiation(inst, (bool) current_agent(sysparams)[LEARNING_ON_SYSPARAM]);
00771
00772
00773 if (!current_agent(system_halted)) {
00774
00775 #ifndef FEW_CALLBACKS
00776
00777 soar_invoke_callbacks(soar_agent, FIRING_CALLBACK, (soar_call_data) inst);
00778 #endif
00779 }
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789 void deallocate_instantiation(instantiation * inst)
00790 {
00791 condition *cond;
00792
00793
00794 list *c, *c_old;
00795 preference *pref;
00796 goal_stack_level level;
00797
00798 level = inst->match_goal_level;
00799
00800 #ifdef DEBUG_INSTANTIATIONS
00801 if (inst->prod)
00802 print_with_symbols("\nDeallocate instantiation of %y", inst->prod->name);
00803 #endif
00804
00805 #ifdef WATCH_SSCI_INSTS
00806 if (inst->isa_ssci_inst == TRUE) {
00807 if (inst->prod) {
00808 print_with_symbols("\nDeallocating an SSCI instantiation: %y", inst->prod->name);
00809 print("Production has %d references\n", inst->prod->reference_count);
00810 } else
00811 print_with_symbols("\nDeallocating an SSCI instantiation whose production has already been excised\n");
00812
00813 }
00814 #endif
00815
00816 for (cond = inst->top_of_instantiated_conditions; cond != NIL; cond = cond->next)
00817 if (cond->type == POSITIVE_CONDITION) {
00818
00819
00820 if (cond->bt.prohibits) {
00821 c_old = c = cond->bt.prohibits;
00822 cond->bt.prohibits = NIL;
00823 for (; c != NIL; c = c->rest) {
00824 pref = (preference *) c->first;
00825
00826 #ifdef NO_TOP_LEVEL_REFS
00827
00828 if (level > 1)
00829 #endif
00830 preference_remove_ref(pref);
00831 }
00832 free_list(c_old);
00833 }
00834
00835
00836 #ifdef NO_TOP_LEVEL_REFS
00837 if (level > 1) {
00838 wme_remove_ref(cond->bt.wme);
00839 if (cond->bt.trace)
00840 preference_remove_ref(cond->bt.trace);
00841 }
00842 #else
00843 wme_remove_ref(cond->bt.wme);
00844 if (cond->bt.trace)
00845 preference_remove_ref(cond->bt.trace);
00846
00847 #endif
00848
00849 }
00850
00851 deallocate_condition_list(inst->top_of_instantiated_conditions);
00852 deallocate_list_of_nots(inst->nots);
00853
00854 if (inst->prod)
00855 production_remove_ref(inst->prod);
00856
00857 free_with_pool(¤t_agent(instantiation_pool), inst);
00858 }
00859
00860
00861
00862
00863
00864
00865
00866 void retract_instantiation(instantiation * inst)
00867 {
00868 preference *pref, *next;
00869 bool retracted_a_preference;
00870
00871 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00872 bool trace_it;
00873 #endif
00874
00875 #ifndef FEW_CALLBACKS
00876
00877 soar_invoke_callbacks(soar_agent, RETRACTION_CALLBACK, (soar_call_data) inst);
00878 #endif
00879
00880 retracted_a_preference = FALSE;
00881
00882 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00883
00884 trace_it = (bool) trace_firings_of_inst(inst);
00885 #endif
00886
00887
00888 pref = inst->preferences_generated;
00889 while (pref != NIL) {
00890 next = pref->inst_next;
00891 if (pref->in_tm && (!pref->o_supported)) {
00892
00893 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00894
00895 if (trace_it) {
00896 if (!retracted_a_preference) {
00897 if (get_printer_output_column() != 1)
00898 print("\n");
00899 print("Retracting ");
00900 print_instantiation_with_wmes
00901 (inst, (wme_trace_type) current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM]);
00902 if (current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM])
00903 print(" -->");
00904 }
00905 if (current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) {
00906 print(" ");
00907 print_preference(pref);
00908 }
00909 }
00910 #endif
00911
00912 remove_preference_from_tm(pref);
00913 retracted_a_preference = TRUE;
00914 }
00915 pref = next;
00916 }
00917
00918
00919 #if defined(OPTIMIZE_TOP_LEVEL_RESULTS) || (defined(THIN_JUSTIFICATIONS) && !defined(MAKE_PRODUCTION_FOR_THIN_JUSTS))
00920 if (inst->prod)
00921 #endif
00922 remove_from_dll(inst->prod->instantiations, inst, next, prev);
00923
00924
00925
00926
00927
00928
00929
00930
00931 #ifdef WATCH_SSCI_INSTS
00932 if (inst->isa_ssci_inst) {
00933 print("Retracting SSCI instantiation...");
00934 if (inst->prod)
00935 print(" prod ref cound = %d\n", inst->prod->reference_count);
00936 else
00937 print("\n");
00938 }
00939 #endif
00940
00941 #if defined(OPTIMIZE_TOP_LEVEL_RESULTS) || (defined(THIN_JUSTIFICATIONS) && !defined(MAKE_PRODUCTION_FOR_THIN_JUSTS))
00942 if (inst->prod && inst->prod->type == JUSTIFICATION_PRODUCTION_TYPE && inst->prod->reference_count > 1) {
00943 #else
00944
00945 if (inst->prod->type == JUSTIFICATION_PRODUCTION_TYPE && inst->prod->reference_count > 1) {
00946 #endif
00947
00948 excise_production(inst->prod, FALSE);
00949
00950 }
00951
00952
00953 inst->in_ms = FALSE;
00954 possibly_deallocate_instantiation(inst);
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 void assert_new_preferences(void)
00977 {
00978 instantiation *inst, *next_inst;
00979 preference *pref, *next_pref;
00980 preference *o_rejects;
00981 #if defined(WATCH_INSTS_WITH_O_PREFS) || defined(REMOVE_INSTS_WITH_O_PREFS) || defined(OPTIMIZE_TOP_LEVEL_RESULTS) || defined(THIN_JUSTIFICATIONS)
00982 bool is_fully_o_supported;
00983
00984 #endif
00985
00986 o_rejects = NIL;
00987
00988
00989 #ifndef SOAR_8_ONLY
00990 if ((current_agent(operand2_mode) == TRUE) &&
00991 #else
00992 if (
00993 #endif
00994 (current_agent(soar_verbose_flag) == TRUE))
00995 print("\n in assert_new_preferences:");
00996
00997
00998 #ifdef O_REJECTS_FIRST
00999 {
01000
01001 slot *s;
01002 preference *p, *next_p;
01003
01004
01005
01006
01007 for (inst = current_agent(newly_created_instantiations); inst != NIL; inst = next_inst) {
01008 next_inst = inst->next;
01009
01010 for (pref = inst->preferences_generated; pref != NIL; pref = next_pref) {
01011 next_pref = pref->inst_next;
01012 if ((pref->type == REJECT_PREFERENCE_TYPE) && (pref->o_supported)) {
01013
01014
01015 s = find_slot(pref->id, pref->attr);
01016 if (s) {
01017
01018 p = s->all_preferences;
01019 while (p) {
01020 next_p = p->all_of_slot_next;
01021 if (p->value == pref->value)
01022 remove_preference_from_tm(p);
01023 p = next_p;
01024 }
01025 }
01026 }
01027 }
01028 }
01029 }
01030 #endif
01031
01032 for (inst = current_agent(newly_created_instantiations); inst != NIL; inst = next_inst) {
01033 next_inst = inst->next;
01034
01035 #if defined(OPTIMIZE_TOP_LEVEL_RESULTS) || (defined(THIN_JUSTIFICATIONS) && !defined(MAKE_PRODUCTION_FOR_THIN_JUSTS))
01036 if (inst->in_ms && inst->prod)
01037 #else
01038 if (inst->in_ms)
01039 #endif
01040 insert_at_head_of_dll(inst->prod->instantiations, inst, next, prev);
01041
01042
01043 #ifndef SOAR_8_ONLY
01044 if (current_agent(operand2_mode) == TRUE) {
01045 #endif
01046 if (current_agent(soar_verbose_flag) == TRUE) {
01047 if (inst->prod)
01048 print_with_symbols("\n asserting instantiation: %y\n", inst->prod->name);
01049 else
01050 print("\n asserting a Thin Instantiaion.\n");
01051 }
01052 #ifndef SOAR_8_ONLY
01053 }
01054 #endif
01055
01056
01057 for (pref = inst->preferences_generated; pref != NIL; pref = next_pref) {
01058 next_pref = pref->inst_next;
01059
01060 if ((pref->type == REJECT_PREFERENCE_TYPE) && (pref->o_supported)) {
01061
01062 #ifndef O_REJECTS_FIRST
01063 pref->next = o_rejects;
01064 o_rejects = pref;
01065 #endif
01066
01067
01068
01069
01070
01071 } else if (inst->in_ms || pref->o_supported) {
01072
01073 add_preference_to_tm(pref);
01074
01075
01076
01077
01078
01079 } else {
01080
01081
01082
01083
01084
01085 if (pref->next_clone)
01086 pref->next_clone->prev_clone = pref->prev_clone;
01087 if (pref->prev_clone)
01088 pref->prev_clone->next_clone = pref->next_clone;
01089 pref->next_clone = pref->prev_clone = NIL;
01090
01091 preference_add_ref(pref);
01092 preference_remove_ref(pref);
01093 }
01094 }
01095
01096 #if defined(WATCH_INSTS_WITH_O_PREFS) || defined(REMOVE_INSTS_WITH_O_PREFS) || defined(THIN_JUSTIFICATIONS) || defined(WATCH_SSCI_INSTS) || defined(OPTIMIZE_TOP_LEVEL_RESULTS)
01097 is_fully_o_supported = TRUE;
01098
01099
01100
01101
01102
01103
01104 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
01105 if (pref->o_supported == FALSE) {
01106
01107
01108
01109
01110
01111
01112
01113
01114 is_fully_o_supported = FALSE;
01115 break;
01116 }
01117 }
01118
01119 #ifdef WATCH_SSCI_INSTS
01120 if (inst->isa_ssci_inst == TRUE) {
01121 if (inst->prod) {
01122 print_with_symbols("\nThe SSCI instantiation of %y\n", inst->prod->name);
01123 print_instantiation_with_wmes(inst, FULL_WME_TRACE);
01124
01125 } else {
01126 print("\nAn SSCI inst with a nil production\n");
01127 }
01128 if (is_fully_o_supported) {
01129 print("at %p has FULLY o-supported results\n", inst);
01130 } else {
01131 print("at %p has i-supported results\n", inst);
01132 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next) {
01133 watchful_print_preference(pref);
01134 }
01135 }
01136 }
01137 #endif
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 #ifdef REMOVE_INSTS_WITH_O_PREFS
01153 if (is_fully_o_supported)
01154 retract_instantiation(inst);
01155
01156 #else
01157 #if defined(OPTIMIZE_TOP_LEVEL_RESULTS)
01158
01159
01160
01161
01162
01163
01164
01165 if (is_fully_o_supported && !inst->prod)
01166 retract_instantiation(inst);
01167
01168 #if defined(THIN_JUSTIFICATIONS) && defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01169
01170
01171
01172
01173
01174
01175 if (is_fully_o_supported && inst->isa_ssci_inst == TRUE)
01176 retract_instantiation(inst);
01177 #endif
01178
01179 #else
01180
01181
01182
01183
01184
01185 #if defined(THIN_JUSTIFICATIONS) && defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01186 if (is_fully_o_supported && inst->isa_ssci_inst == TRUE)
01187 retract_instantiation(inst);
01188
01189 #elif defined(THIN_JUSTIFICATIONS) && !defined(MAKE_PRODUCTION_FOR_THIN_JUSTS)
01190 if (is_fully_o_supported && !inst->prod) {
01191 retract_instantiation(inst);
01192 }
01193 #endif
01194
01195 #endif
01196
01197 #endif
01198
01199 #endif
01200
01201 #ifdef NO_TOP_JUST
01202
01203 #ifdef REMOVE_INSTS_WITH_O_PREFS
01204 if (inst && inst->prod)
01205 #else
01206 if (inst->prod)
01207 #endif
01208 if (inst->prod->type == JUSTIFICATION_PRODUCTION_TYPE)
01209 remove_top_level_justifications(inst);
01210
01211 #endif
01212
01213 }
01214 #ifndef O_REJECTS_FIRST
01215 if (o_rejects)
01216 process_o_rejects_and_deallocate_them(o_rejects);
01217 #endif
01218 }
01219
01220
01221
01222
01223
01224
01225
01226 void do_preference_phase(void)
01227 {
01228 production *prod;
01229 struct token_struct *tok;
01230 wme *w;
01231 instantiation *inst;
01232
01233 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
01234
01235
01236
01237
01238
01239
01240
01241 if (current_agent(sysparams)[TRACE_PHASES_SYSPARAM]) {
01242 #ifndef SOAR_8_ONLY
01243 if (current_agent(operand2_mode) == TRUE) {
01244 #endif
01245 switch (current_agent(FIRING_TYPE)) {
01246 case PE_PRODS:
01247 print("\t--- Firing Productions (PE) ---\n");
01248 break;
01249 case IE_PRODS:
01250 print("\t--- Firing Productions (IE) ---\n");
01251 break;
01252 }
01253 #ifndef SOAR_8_ONLY
01254 }
01255
01256 else
01257 print("\n--- Preference Phase ---\n");
01258 #endif
01259 }
01260
01261 #endif
01262
01263 current_agent(newly_created_instantiations) = NIL;
01264
01265
01266 while (get_next_assertion(&prod, &tok, &w)) {
01267 if (current_agent(max_chunks_reached)) {
01268 current_agent(system_halted) = TRUE;
01269 return;
01270 }
01271
01272 create_instantiation(prod, tok, w);
01273 }
01274
01275 assert_new_preferences();
01276
01277 while (get_next_retraction(&inst))
01278 retract_instantiation(inst);
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292 #ifndef SOAR_8_ONLY
01293 if (current_agent(operand2_mode) && current_agent(nil_goal_retractions)) {
01294 #else
01295 if (current_agent(nil_goal_retractions)) {
01296 #endif
01297 while (get_next_nil_goal_retraction(&inst))
01298 retract_instantiation(inst);
01299 }
01300
01301
01302
01303 }
01304
01305 #ifdef NO_TOP_JUST
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 void remove_top_level_justifications(instantiation * inst)
01335 {
01336 preference *pref;
01337 bool all_o_supported, remove_just;
01338 #ifdef NO_JUSTS_BELOW_OSUPPORT
01339 bool masked;
01340 slot *s;
01341 preference *p2;
01342 #endif
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357 if (!inst->prod->name->sc.production)
01358 return;
01359
01360
01361
01362
01363
01364 remove_just = FALSE;
01365 if (inst->match_goal_level <= TOP_GOAL_LEVEL) {
01366 all_o_supported = TRUE;
01367 for (pref = inst->preferences_generated; (pref != NIL && all_o_supported); pref = pref->inst_next)
01368 if (!pref->o_supported)
01369 all_o_supported = FALSE;
01370 if (all_o_supported)
01371 remove_just = TRUE;
01372 }
01373
01374
01375
01376
01377
01378 #ifdef NO_JUSTS_BELOW_OSUPPORT
01379 if (inst->match_goal_level > TOP_GOAL_LEVEL) {
01380 remove_just = TRUE;
01381 for (pref = inst->preferences_generated; (pref != NIL && remove_just); pref = pref->inst_next) {
01382 s = pref->slot;
01383 masked = FALSE;
01384 if (s) {
01385
01386 for (p2 = s->preferences[pref->type]; (p2 != NIL && !masked); p2 = p2->next)
01387 if (p2->match_goal_level < pref->match_goal_level && p2->o_supported == TRUE && p2->value == pref->value)
01388 masked = TRUE;
01389 if (!masked)
01390 remove_just = FALSE;
01391 }
01392 }
01393 }
01394 #endif
01395
01396 if (remove_just) {
01397
01398 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
01399 if (current_agent(sysparams)[TRACE_JUSTIFICATIONS_SYSPARAM])
01400 print_with_symbols("\nRemoving %y", inst->prod->name);
01401 #endif
01402
01403 excise_production(inst->prod, FALSE);
01404
01405
01406
01407
01408
01409
01410
01411
01412 for (pref = inst->preferences_generated; pref != NIL; pref = pref->inst_next)
01413 pref->inst = NIL;
01414
01415
01416
01417
01418 inst->preferences_generated = NIL;
01419 inst->in_ms = FALSE;
01420 }
01421 }
01422
01423 #endif