void add_all_variables_in_action(agent* thisAgent, action* a, tc_number tc, cons** var_list) { Symbol* id; if (a->type == MAKE_ACTION) { /*- ordinary make actions -*/ id = rhs_value_to_symbol(a->id); if (id->is_variable()) { id->mark_if_unmarked(thisAgent, tc, var_list); } add_all_variables_in_rhs_value(thisAgent, a->attr, tc, var_list); add_all_variables_in_rhs_value(thisAgent, a->value, tc, var_list); if (preference_is_binary(a->preference_type)) { add_all_variables_in_rhs_value(thisAgent, a->referent, tc, var_list); } } else { /*- function call actions -*/ add_all_variables_in_rhs_value(thisAgent, a->value, tc, var_list); } }
void deallocate_preference_contents(agent* thisAgent, preference* pref, bool dont_cache) { /* dereference component symbols */ thisAgent->symbolManager->symbol_remove_ref(&pref->id); thisAgent->symbolManager->symbol_remove_ref(&pref->attr); thisAgent->symbolManager->symbol_remove_ref(&pref->value); if (preference_is_binary(pref->type)) { thisAgent->symbolManager->symbol_remove_ref(&pref->referent); } if (pref->wma_o_set) { wma_remove_pref_o_set(thisAgent, pref); } if (pref->identities.id) IdentitySet_remove_ref(thisAgent, pref->identities.id); if (pref->identities.attr) IdentitySet_remove_ref(thisAgent, pref->identities.attr); if (pref->identities.value) IdentitySet_remove_ref(thisAgent, pref->identities.value); if (pref->identities.referent) IdentitySet_remove_ref(thisAgent, pref->identities.referent); if (pref->rhs_func_inst_identities.id) deallocate_rhs_value(thisAgent, pref->rhs_func_inst_identities.id); if (pref->rhs_func_inst_identities.attr) deallocate_rhs_value(thisAgent, pref->rhs_func_inst_identities.attr); if (pref->rhs_func_inst_identities.value) deallocate_rhs_value(thisAgent, pref->rhs_func_inst_identities.value); if (pref->rhs_func_inst_identities.referent) deallocate_rhs_value(thisAgent, pref->rhs_func_inst_identities.referent); if (pref->rhs_func_chunk_inst_identities.id) deallocate_rhs_value(thisAgent, pref->rhs_func_chunk_inst_identities.id); if (pref->rhs_func_chunk_inst_identities.attr) deallocate_rhs_value(thisAgent, pref->rhs_func_chunk_inst_identities.attr); if (pref->rhs_func_chunk_inst_identities.value) deallocate_rhs_value(thisAgent, pref->rhs_func_chunk_inst_identities.value); if (pref->rhs_func_chunk_inst_identities.referent) deallocate_rhs_value(thisAgent, pref->rhs_func_chunk_inst_identities.referent); thisAgent->memoryManager->free_with_pool(MP_preference, pref); }
void deallocate_action_list(agent* thisAgent, action* actions) { action* a; while (actions) { a = actions; actions = actions->next; if (a->type == FUNCALL_ACTION) { deallocate_rhs_value(thisAgent, a->value); } else { /*- make actions -*/ deallocate_rhs_value(thisAgent, a->id); deallocate_rhs_value(thisAgent, a->attr); deallocate_rhs_value(thisAgent, a->value); if (preference_is_binary(a->preference_type)) { deallocate_rhs_value(thisAgent, a->referent); } } thisAgent->memoryManager->free_with_pool(MP_action, a); } }
preference *execute_action (action *a, struct token_struct *tok, wme *w) { Symbol *id, *attr, *value, *referent; char first_letter; if (a->type==FUNCALL_ACTION) { value = instantiate_rhs_value (a->value, -1, 'v', tok, w); if (value) symbol_remove_ref (value); return NIL; } attr = NIL; value = NIL; referent = NIL; id = instantiate_rhs_value (a->id, -1, 's', tok, w); if (!id) goto abort_execute_action; if (id->common.symbol_type!=IDENTIFIER_SYMBOL_TYPE) { print_with_symbols ("Error: RHS makes a preference for %y (not an identifier)\n", id); goto abort_execute_action; } attr = instantiate_rhs_value (a->attr, id->id.level, 'a', tok, w); if (!attr) goto abort_execute_action; first_letter = first_letter_from_symbol (attr); value = instantiate_rhs_value (a->value, id->id.level, first_letter, tok, w); if (!value) goto abort_execute_action; if (preference_is_binary(a->preference_type)) { referent = instantiate_rhs_value (a->referent, id->id.level, first_letter, tok, w); if (!referent) goto abort_execute_action; } /* --- RBD 4/17/95 added stuff to handle attribute_preferences_mode --- */ if (((a->preference_type != ACCEPTABLE_PREFERENCE_TYPE) && (a->preference_type != REJECT_PREFERENCE_TYPE)) && (! (id->id.isa_goal && (attr==current_agent(operator_symbol))) )) { if ((current_agent(attribute_preferences_mode)==2) || (current_agent(operand2_mode) ==TRUE) ) { print_with_symbols ("\nError: attribute preference other than +/- for %y ^%y -- ignoring it.", id, attr); goto abort_execute_action; } else if (current_agent(attribute_preferences_mode)==1) { print_with_symbols ("\nWarning: attribute preference other than +/- for %y ^%y.", id, attr); } } return make_preference (a->preference_type, id, attr, value, referent); abort_execute_action: /* control comes here when some error occurred */ if (id) symbol_remove_ref (id); if (attr) symbol_remove_ref (attr); if (value) symbol_remove_ref (value); if (referent) symbol_remove_ref (referent); return NIL; }
action* create_RHS_action_list(agent* thisAgent, action* actions, condition* cond, ExplainTraceType ebcTraceType) { action* old, *New, *prev, *first; char first_letter; prev = NIL; first = NIL; old = actions; while (old) { New = make_action(thisAgent); if (prev) { prev->next = New; } else { first = New; } prev = New; New->type = old->type; New->preference_type = old->preference_type; New->support = old->support; if (old->type == FUNCALL_ACTION) { New->value = create_RHS_value(thisAgent, old->value, cond, 'v', ebcTraceType); } else { New->id = create_RHS_value(thisAgent, old->id, cond, 's', ebcTraceType); New->attr = create_RHS_value(thisAgent, old->attr, cond, 'a', ebcTraceType); first_letter = first_letter_from_rhs_value(New->attr); New->value = create_RHS_value(thisAgent, old->value, cond, first_letter, ebcTraceType); if (preference_is_binary(old->preference_type)) { New->referent = create_RHS_value(thisAgent, old->referent, cond, first_letter, ebcTraceType); } } old = old->next; } if (prev) { prev->next = NIL; } else { first = NIL; } return first; }
Bool legal_to_execute_action (action *a, tc_number tc) { if (a->type==MAKE_ACTION) { if (! all_variables_in_rhs_value_bound (a->id, tc)) return FALSE; if (rhs_value_is_funcall(a->attr) && (! all_variables_in_rhs_value_bound (a->attr, tc))) return FALSE; if (rhs_value_is_funcall(a->value) && (! all_variables_in_rhs_value_bound (a->value, tc))) return FALSE; if (preference_is_binary(a->preference_type) && rhs_value_is_funcall(a->referent) && (! all_variables_in_rhs_value_bound (a->referent, tc))) return FALSE; return TRUE; } /* --- otherwise it's a function call; make sure args are all bound --- */ return all_variables_in_rhs_value_bound (a->value, tc); }
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); }
action* copy_action(agent* thisAgent, action* pAction) { action* new_action = make_action(thisAgent); new_action->type = pAction->type; new_action->preference_type = pAction->preference_type; new_action->support = pAction->support; if (pAction->type == FUNCALL_ACTION) { new_action->value = copy_rhs_value(thisAgent, pAction->value); } else { new_action->id = copy_rhs_value(thisAgent, pAction->id); new_action->attr = copy_rhs_value(thisAgent, pAction->attr); new_action->value = copy_rhs_value(thisAgent, pAction->value); if (preference_is_binary(pAction->preference_type)) new_action->referent = copy_rhs_value(thisAgent, pAction->referent); } return new_action; }
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; }