void retract_instantiation (instantiation *inst) { preference *pref, *next; bool retracted_a_preference; bool trace_it; /* --- invoke callback function --- */ #ifndef NO_CALLBACKS soar_invoke_callbacks(soar_agent, RETRACTION_CALLBACK, (soar_call_data) inst); #endif retracted_a_preference = FALSE; trace_it = trace_firings_of_inst (inst); /* --- retract any preferences that are in TM and aren't o-supported --- */ pref = inst->preferences_generated; while (pref!=NIL) { next = pref->inst_next; if (pref->in_tm && (! pref->o_supported)) { if (trace_it) { if (!retracted_a_preference) { if (get_printer_output_column()!=1) print ("\n"); /* AGR 617/634 */ print ("Retracting "); print_instantiation_with_wmes (inst, (wme_trace_type)current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM]); if (current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) print (" -->"); } if (current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { print (" "); print_preference (pref); } } remove_preference_from_tm (pref); retracted_a_preference = TRUE; } pref = next; } /* --- remove inst from list of instantiations of this production --- */ remove_from_dll (inst->prod->instantiations, inst, next, prev); /* --- if retracting a justification, excise it --- */ /* * if the reference_count on the production is 1 (or less) then the * only thing supporting this justification is the instantiation, hence * it has already been excised, and doing it again is wrong. */ if (inst->prod->type==JUSTIFICATION_PRODUCTION_TYPE && inst->prod->reference_count > 1) excise_production (inst->prod, FALSE); /* --- mark as no longer in MS, and possibly deallocate --- */ inst->in_ms = FALSE; possibly_deallocate_instantiation (inst); }
void remove_preference_from_tm(agent* thisAgent, preference* pref) { slot* s; s = pref->slot; /* remove preference from the list for the slot */ remove_from_dll(s->all_preferences, pref, all_of_slot_next, all_of_slot_prev); remove_from_dll(s->preferences[pref->type], pref, next, prev); /* other miscellaneous stuff */ pref->in_tm = false; pref->slot = NIL; /* BUG shouldn't we use pref->slot in place of pref->in_tm? */ mark_slot_as_changed(thisAgent, s); /* if acceptable/require pref for context slot, we may need to remove a wme later */ if ((s->isa_context_slot) && ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE))) { mark_context_slot_as_acceptable_preference_changed(thisAgent, s); } /* update identifier levels */ if (pref->value->symbol_type == IDENTIFIER_SYMBOL_TYPE) { post_link_removal(thisAgent, pref->id, pref->value); } if (preference_is_binary(pref->type)) if (pref->referent->symbol_type == IDENTIFIER_SYMBOL_TYPE) { post_link_removal(thisAgent, pref->id, pref->referent); } if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { thisAgent->outputManager->printa_sf(thisAgent, "%e- "); print_preference(thisAgent, pref, false); thisAgent->outputManager->printa_sf(thisAgent, " (%y)\n", pref->inst->prod_name); } /* deallocate it and clones if possible */ preference_remove_ref(thisAgent, pref); }
bool add_preference_to_tm(agent* thisAgent, preference* pref) { slot* s = make_slot(thisAgent, pref->id, pref->attr); preference* p2; if (!thisAgent->Decider->settings[DECIDER_KEEP_TOP_OPREFS] && (pref->inst->match_goal == thisAgent->top_state) && pref->o_supported && !s->isa_context_slot && (pref->type == ACCEPTABLE_PREFERENCE_TYPE) ) { /* We could potentially cache a list of all o-supported values in the slot so that we don't have to iterate * through all of the preferences. We would need to maintain the list as we decide non-context slots */ bool already_top_o_supported = false; for (p2 = s->all_preferences; (p2 && !already_top_o_supported); p2 = p2->all_of_slot_next) { if ((p2->value == pref->value) && p2->o_supported && (p2->inst->match_goal == thisAgent->top_state)) { already_top_o_supported = true; } } if (already_top_o_supported) { if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { thisAgent->outputManager->printa_sf(thisAgent, "%e+ "); print_preference(thisAgent, pref, false); thisAgent->outputManager->printa_sf(thisAgent, " (%y) ALREADY SUPPORTED ON TOP LEVEL. IGNORING.\n", pref->inst->prod_name); } return false; } } pref->slot = s; insert_at_head_of_dll(s->all_preferences, pref, all_of_slot_next, all_of_slot_prev); /* add to preference list of slot (according to match goal level of the instantiations) */ if (!s->preferences[pref->type]) { /* this is the only pref. of its type, just put it at the head */ insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev); } else if (s->preferences[pref->type]->inst->match_goal_level >= pref->inst->match_goal_level) { /* it belongs at the head of the list, so put it there */ insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev); } else { /* scan through the pref. list, find the one to insert after */ for (p2 = s->preferences[pref->type]; p2->next != NIL; p2 = p2->next) { if (p2->next->inst->match_goal_level >= pref->inst->match_goal_level) { break; } } /* insert pref after p2 */ pref->next = p2->next; pref->prev = p2; p2->next = pref; if (pref->next) { pref->next->prev = pref; } } pref->in_tm = true; preference_add_ref(pref); /* If the slot is unchanged but has some references laying around, we clear them * This does not lead to immediate memory deallocate/allocate but once the WMEs are * resolved, this should free the memory. */ if (wma_enabled(thisAgent) && !s->isa_context_slot) { if (!s->changed) { if (s->wma_val_references != NIL) { s->wma_val_references->clear(); } } } mark_slot_as_changed(thisAgent, s); if (wma_enabled(thisAgent) && !s->isa_context_slot) { bool exists = false; wme* w = pref->slot->wmes; while (!exists && w) { if (w->value == pref->value) { exists = true; } w = w->next; } /* If wme exists, it should already have been updated during assertion of new preferences */ if (!exists) { if (s->wma_val_references == NIL) { thisAgent->memoryManager->allocate_with_pool(MP_wma_slot_refs, &(s->wma_val_references)); #ifdef USE_MEM_POOL_ALLOCATORS s->wma_val_references = new(s->wma_val_references) wma_sym_reference_map(std::less< Symbol* >(), soar_module::soar_memory_pool_allocator< std::pair< Symbol*, uint64_t > >()); #else s->wma_val_references = new(s->wma_val_references) wma_sym_reference_map(); #endif } (*s->wma_val_references)[ pref->value ]++; } } /* update identifier levels */ if (pref->value->symbol_type == IDENTIFIER_SYMBOL_TYPE) { post_link_addition(thisAgent, pref->id, pref->value); } if (preference_is_binary(pref->type)) { if (pref->referent->symbol_type == IDENTIFIER_SYMBOL_TYPE) { post_link_addition(thisAgent, pref->id, pref->referent); } } /* if acceptable/require pref for context slot, we may need to add a wme later */ if ((s->isa_context_slot) && ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE))) { mark_context_slot_as_acceptable_preference_changed(thisAgent, s); } if (thisAgent->trace_settings[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { thisAgent->outputManager->printa_sf(thisAgent, "%e+ "); print_preference(thisAgent, pref, false); thisAgent->outputManager->printa_sf(thisAgent, " (%y)\n", pref->inst->prod_name); } return true; }
void create_instantiation (production *prod, struct token_struct *tok, wme *w) { instantiation *inst; condition *cond; preference *pref; action *a; cons *c; bool need_to_do_support_calculations; bool trace_it; long index; Symbol **cell; allocate_with_pool (¤t_agent(instantiation_pool), &inst); inst->next = current_agent(newly_created_instantiations); current_agent(newly_created_instantiations) = inst; inst->prod = prod; inst->rete_token = tok; inst->rete_wme = w; inst->okay_to_variablize = TRUE; inst->in_ms = TRUE; /* REW: begin 09.15.96 */ /* We want to initialize the GDS_evaluated_already flag * when a new instantiation is created. */ inst->GDS_evaluated_already = FALSE; if (current_agent(operand2_mode) == TRUE) { if (current_agent(soar_verbose_flag) == TRUE) print_with_symbols("\n in create_instantiation: %y", inst->prod->name); } /* REW: end 09.15.96 */ current_agent(production_being_fired) = inst->prod; prod->firing_count++; current_agent(production_firing_count)++; /* --- build the instantiated conditions, and bind LHS variables --- */ p_node_to_conditions_and_nots (prod->p_node, tok, w, &(inst->top_of_instantiated_conditions), &(inst->bottom_of_instantiated_conditions), &(inst->nots), NIL); /* --- record the level of each of the wmes that was positively tested --- */ for (cond=inst->top_of_instantiated_conditions; cond!=NIL; cond=cond->next) { if (cond->type==POSITIVE_CONDITION) { cond->bt.level = cond->bt.wme->id->id.level; cond->bt.trace = cond->bt.wme->preference; } } /* --- print trace info --- */ trace_it = trace_firings_of_inst (inst); if (trace_it) { if (get_printer_output_column()!=1) print ("\n"); /* AGR 617/634 */ print ("Firing "); print_instantiation_with_wmes (inst, (wme_trace_type)(current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM])); } /* --- initialize rhs_variable_bindings array with names of variables (if there are any stored on the production -- for chunks there won't be any) --- */ index = 0; cell = current_agent(rhs_variable_bindings); for (c=prod->rhs_unbound_variables; c!=NIL; c=c->rest) { *(cell++) = c->first; index++; } firer_highest_rhs_unboundvar_index = index-1; /* 7.1/8 merge: Not sure about this. This code in 704, but not in either 7.1 or 703/soar8 */ /* --- Before executing the RHS actions, tell the user that the -- */ /* --- phase has changed to output by printing the arrow --- */ if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { print (" -->\n");} /* --- execute the RHS actions, collect the results --- */ inst->preferences_generated = NIL; need_to_do_support_calculations = FALSE; for (a=prod->action_list; a!=NIL; a=a->next) { pref = execute_action (a, tok, w); if (pref) { pref->inst = inst; insert_at_head_of_dll (inst->preferences_generated, pref, inst_next, inst_prev); if (inst->prod->declared_support==DECLARED_O_SUPPORT) pref->o_supported = TRUE; else if (inst->prod->declared_support==DECLARED_I_SUPPORT) pref->o_supported = FALSE; else { if (current_agent(operand2_mode) == TRUE) { pref->o_supported = (current_agent(FIRING_TYPE) == PE_PRODS) ? TRUE : FALSE; } /* REW: end 09.15.96 */ else { if (a->support==O_SUPPORT) pref->o_supported = TRUE; else if (a->support==I_SUPPORT) pref->o_supported = FALSE; else { need_to_do_support_calculations = TRUE; if (current_agent(soar_verbose_flag) == TRUE) printf("\n\nin create_instantiation(): need_to_do_support_calculations == TRUE!!!\n\n"); } } } } } /* --- reset rhs_variable_bindings array to all zeros --- */ index = 0; cell = current_agent(rhs_variable_bindings); while (index++ <= firer_highest_rhs_unboundvar_index) *(cell++) = NIL; /* --- fill in lots of other stuff --- */ fill_in_new_instantiation_stuff (inst, need_to_do_support_calculations); /* --- print trace info: printing preferences --- */ /* Note: can't move this up, since fill_in_new_instantiation_stuff gives the o-support info for the preferences we're about to print */ if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { for (pref=inst->preferences_generated; pref!=NIL; pref=pref->inst_next) { print (" "); print_preference (pref); } } /* mvp 5-17-94 */ build_prohibits_list (inst); current_agent(production_being_fired) = NIL; /* --- build chunks/justifications if necessary --- */ chunk_instantiation (inst, (bool)current_agent(sysparams)[LEARNING_ON_SYSPARAM]); #ifndef NO_CALLBACKS /* kjc 1/00 */ /* MVP 6-8-94 */ if (!current_agent(system_halted)) { /* --- invoke callback function --- */ soar_invoke_callbacks(soar_agent, FIRING_CALLBACK, (soar_call_data) inst); } #endif }
bool trace_ungrounded_potentials(goal_stack_level grounds_level) { /* mvp 5-17-94 */ cons *c, *next_c, *prev_c, *prohibits; cons *pots_to_bt; condition *potential; preference *bt_pref, *p; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) print_string("\n\n*** Tracing Ungrounded Potentials ***\n"); #endif /* --- scan through positive potentials, pick out the ones that have a preference we can backtrace through --- */ pots_to_bt = NIL; prev_c = NIL; for (c = current_agent(positive_potentials); c != NIL; c = next_c) { next_c = c->rest; potential = c->first; bt_pref = find_clone_for_level(potential->bt.trace, (goal_stack_level) (grounds_level + 1)); if (bt_pref) { if (prev_c) prev_c->rest = next_c; else current_agent(positive_potentials) = next_c; c->rest = pots_to_bt; pots_to_bt = c; } else { prev_c = c; } } /* --- if none to BT, exit --- */ if (!pots_to_bt) return FALSE; /* --- backtrace through each one --- */ while (pots_to_bt) { c = pots_to_bt; pots_to_bt = pots_to_bt->rest; potential = c->first; free_cons(c); #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) { print_string("\nFor ungrounded potential "); print_wme(potential->bt.wme); print_string(" "); } #endif bt_pref = find_clone_for_level(potential->bt.trace, (goal_stack_level) (grounds_level + 1)); #ifdef NO_TOP_JUST if (bt_pref->inst) backtrace_through_instantiation(bt_pref->inst, grounds_level, potential, 0); #else /* mvp 5-17-94 */ backtrace_through_instantiation(bt_pref->inst, grounds_level, potential, 0); #endif if (potential->bt.prohibits) { for (prohibits = potential->bt.prohibits; prohibits != NIL; prohibits = prohibits->rest) { p = prohibits->first; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) { print_string(" For prohibit preference: "); print_preference(p); } #endif #ifdef NO_TOP_JUST if (p->inst) backtrace_through_instantiation(p->inst, grounds_level, potential, 6); #else backtrace_through_instantiation(p->inst, grounds_level, potential, 6); #endif } } /* mvp done */ } return TRUE; }
void trace_locals(goal_stack_level grounds_level) { /* mvp 5-17-94 */ cons *c, *prohibits; condition *cond; preference *bt_pref, *p; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) print_string("\n\n*** Tracing Locals ***\n"); #endif while (current_agent(locals)) { c = current_agent(locals); current_agent(locals) = current_agent(locals)->rest; cond = c->first; free_cons(c); #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) { print_string("\nFor local "); print_wme(cond->bt.wme); print_string(" "); } #endif bt_pref = find_clone_for_level(cond->bt.trace, (goal_stack_level) (grounds_level + 1)); /* --- if it has a trace at this level, backtrace through it --- */ if (bt_pref) { #ifdef NO_TOP_JUST if (bt_pref->inst) { /* mvp 5-17-94 */ backtrace_through_instantiation(bt_pref->inst, grounds_level, cond, 0); /* check if any prohibit preferences */ if (cond->bt.prohibits) { for (prohibits = cond->bt.prohibits; prohibits != NIL; prohibits = prohibits->rest) { p = prohibits->first; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) { print_string(" For prohibit preference: "); print_preference(p); } #endif if (p->inst) backtrace_through_instantiation(p->inst, grounds_level, cond, 6); } } /* mvp done */ } #else /* mvp 5-17-94 */ backtrace_through_instantiation(bt_pref->inst, grounds_level, cond, 0); /* check if any prohibit preferences */ if (cond->bt.prohibits) { for (prohibits = cond->bt.prohibits; prohibits != NIL; prohibits = prohibits->rest) { p = prohibits->first; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) { print_string(" For prohibit preference: "); print_preference(p); } #endif backtrace_through_instantiation(p->inst, grounds_level, cond, 6); } } /* mvp done */ #endif continue; } #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) print_string("...no trace, can't BT"); #endif /* --- for augmentations of the local goal id, either handle the "^quiescence t" test or discard it --- */ if (referent_of_equality_test(cond->data.tests.id_test)->id.isa_goal) { if ((referent_of_equality_test(cond->data.tests.attr_test) == current_agent(quiescence_symbol)) && (referent_of_equality_test(cond->data.tests.value_test) == current_agent(t_symbol)) && (!cond->test_for_acceptable_preference)) { current_agent(variablize_this_chunk) = FALSE; current_agent(quiescence_t_flag) = TRUE; } continue; } /* --- otherwise add it to the potential set --- */ #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) print_string(" --> make it a potential."); #endif add_to_potentials(cond); } /* end of while locals loop */ }