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 SMem_Manager::install_buffered_triple_list(Symbol* state, wme_set& cue_wmes, symbol_triple_list& my_list, bool meta, bool stripLTILinks) { if (my_list.empty()) { return; } dprint(DT_SMEM_INSTANCE, "install_buffered_triple_list called in state %y. Creating architectural instantiation.\n", state); instantiation* inst = make_architectural_instantiation_for_memory_system(thisAgent, state, &cue_wmes, &my_list, true); for (preference* pref = inst->preferences_generated; pref;) { if (add_preference_to_tm(thisAgent, pref)) { // and add it to the list of preferences to be removed // when the goal is removed dprint(DT_SMEM_INSTANCE, "...adding preference %p to WM\n", pref); insert_at_head_of_dll(state->id->preferences_from_goal, pref, all_of_goal_next, all_of_goal_prev); pref->on_goal_list = true; if (meta) { // if this is a meta wme, then it is completely local // to the state and thus we will manually remove it // (via preference removal) when the time comes state->id->smem_info->smem_wmes->push_back(pref); } } else { dprint(DT_SMEM_INSTANCE, "...could not add preference %p to WM. Deallocating.\n", pref); if (pref->reference_count == 0) { preference* previous = pref; pref = pref->inst_next; possibly_deallocate_preference_and_clones(thisAgent, previous, true); continue; } } if (stripLTILinks) { pref->id->id->LTI_ID = 0; pref->id->update_cached_lti_print_str(); if (pref->value->is_sti()) { pref->value->id->LTI_ID = 0; pref->value->update_cached_lti_print_str(); } } pref = pref->inst_next; } if (!meta) { // Create an architectural instantiation to allow backtracing // for chunks, justifications and the GDS. instantiation* my_justification_list = NIL; dprint(DT_MILESTONES, "Asserting preferences of new architectural instantiation in _smem_process_buffered_wme_list...\n"); // if any justifications are created, assert their preferences manually // (copied mainly from assert_new_preferences with respect to our circumstances) if (my_justification_list != NIL) { preference* just_pref = NIL; instantiation* next_justification = NIL; for (instantiation* my_justification = my_justification_list; my_justification != NIL; my_justification = next_justification) { next_justification = my_justification->next; if (my_justification->in_ms) { insert_at_head_of_dll(my_justification->prod->instantiations, my_justification, next, prev); } for (just_pref = my_justification->preferences_generated; just_pref != NIL;) { if (add_preference_to_tm(thisAgent, just_pref)) { if (wma_enabled(thisAgent)) { wma_activate_wmes_in_pref(thisAgent, just_pref); } } else { if (just_pref->reference_count == 0) { preference* previous = just_pref; just_pref = just_pref->inst_next; possibly_deallocate_preference_and_clones(thisAgent, previous, true); continue; } } just_pref = just_pref->inst_next; } } } } }
bool wma_activation_predicate<T>::operator() ( T /*val*/ ) { return wma_enabled( this->my_agent ); };