void remove_garbage_slots(agent* thisAgent) { cons* c; slot* s; while (thisAgent->slots_for_possible_removal) { c = thisAgent->slots_for_possible_removal; thisAgent->slots_for_possible_removal = thisAgent->slots_for_possible_removal->rest; s = static_cast<slot_struct*>(c->first); free_cons(thisAgent, c); if (s->wmes || s->all_preferences) { /* --- don't deallocate it if it still has any wmes or preferences --- */ s->marked_for_possible_removal = false; continue; } /* --- deallocate the slot --- */ #ifdef DEBUG_SLOTS print_with_symbols(thisAgent, "\nDeallocate slot %y ^%y", s->id, s->attr); #endif /* MMA 9-2012 */ if (s->CDPS && thisAgent->sysparams[CHUNK_THROUGH_EVALUATION_RULES_SYSPARAM]) { clear_CDPS(thisAgent, s); } /* MMA 9-2012 end */ if (s->changed && (!s->isa_context_slot)) { remove_from_dll(thisAgent->changed_slots, s->changed, next, prev); free_with_pool(&thisAgent->dl_cons_pool, s->changed); } remove_from_dll(s->id->id->slots, s, next, prev); symbol_remove_ref(thisAgent, s->id); symbol_remove_ref(thisAgent, s->attr); if (s->wma_val_references != NIL) { s->wma_val_references->~wma_sym_reference_map(); free_with_pool(&(thisAgent->wma_slot_refs_pool), s->wma_val_references); s->wma_val_references = NIL; } free_with_pool(&thisAgent->slot_pool, s); } }
void wma_deinit( agent *my_agent ) { if ( !my_agent->wma_initialized ) { return; } // release power array memory delete[] my_agent->wma_power_array; // release approximation array memory (if applicable) if ( my_agent->wma_params->forgetting->get_value() == wma_param_container::approx ) { delete[] my_agent->wma_approx_array; } // clear touched my_agent->wma_touched_elements->clear(); my_agent->wma_touched_sets->clear(); // clear forgetting priority queue for ( wma_forget_p_queue::iterator pq_p=my_agent->wma_forget_pq->begin(); pq_p!=my_agent->wma_forget_pq->end(); pq_p++ ) { pq_p->second->~wma_decay_set(); free_with_pool( &( my_agent->wma_decay_set_pool ), pq_p->second ); } my_agent->wma_forget_pq->clear(); my_agent->wma_initialized = false; }
void deallocate_instantiation (instantiation *inst) { condition *cond; /* mvp 5-17-94 */ list *c, *c_old; preference *pref; goal_stack_level level; level = inst->match_goal_level; #ifdef DEBUG_INSTANTIATIONS if (inst->prod) print_with_symbols ("\nDeallocate instantiation of %y",inst->prod->name); #endif for (cond=inst->top_of_instantiated_conditions; cond!=NIL; cond=cond->next) if (cond->type==POSITIVE_CONDITION) { /* mvp 6-22-94, modified 94.01.17 by AGR with lotsa help from GAP */ if (cond->bt.prohibits) { c_old = c = cond->bt.prohibits; cond->bt.prohibits = NIL; for (; c!=NIL; c=c->rest) { pref = (preference *) c->first; #ifdef DO_TOP_LEVEL_REF_CTS preference_remove_ref (pref); #else if (level > TOP_GOAL_LEVEL) preference_remove_ref (pref); #endif } free_list (c_old); } /* mvp done */ #ifdef DO_TOP_LEVEL_REF_CTS wme_remove_ref (cond->bt.wme); if (cond->bt.trace) preference_remove_ref (cond->bt.trace); #else if (level > TOP_GOAL_LEVEL) { wme_remove_ref (cond->bt.wme); if (cond->bt.trace) preference_remove_ref (cond->bt.trace); } #endif } deallocate_condition_list (inst->top_of_instantiated_conditions); deallocate_list_of_nots (inst->nots); if (inst->prod) production_remove_ref (inst->prod); free_with_pool (¤t_agent(instantiation_pool), inst); }
void wma_remove_pref_o_set( agent* my_agent, preference* pref ) { if ( pref && pref->wma_o_set ) { wma_pooled_wme_set* victim = pref->wma_o_set; pref->wma_o_set = NULL; for ( wma_pooled_wme_set::iterator p=victim->begin(); p!=victim->end(); p++ ) { wme_remove_ref( my_agent, (*p) ); } victim->~wma_pooled_wme_set(); free_with_pool( &( my_agent->wma_wme_oset_pool ), victim ); } }
void wma_remove_decay_element( agent* my_agent, wme* w ) { wma_decay_element* temp_el = w->wma_decay_el; if ( temp_el ) { // Deactivate the wme first if ( !temp_el->just_removed ) { wma_deactivate_element( my_agent, w ); } // log if ( my_agent->sysparams[ TRACE_WMA_SYSPARAM ] ) { std::string msg( "WMA @" ); std::string temp; to_string( my_agent->d_cycle_count, temp ); msg.append( temp ); msg.append( ": " ); msg.append( "remove " ); to_string( w->timetag, temp ); msg.append( temp ); msg.append( "\n" ); print( my_agent, msg.c_str() ); xml_generate_warning( my_agent, msg.c_str() ); } free_with_pool( &( my_agent->wma_decay_element_pool ), temp_el ); w->wma_decay_el = NULL; } }
saved_test *simplify_condition_list (agent* thisAgent, condition *conds_list) { condition *c; saved_test *sts; sts = NIL; for (c=conds_list; c!=NIL; c=c->next) { //#define CONSIDER_NEGATIVE 1 #ifdef CONSIDER_NEGATIVE if (c->type!=CONJUNCTIVE_NEGATION_CONDITION) { #else if (c->type==POSITIVE_CONDITION) { #endif sts = simplify_test (thisAgent, &(c->data.tests.id_test), sts); sts = simplify_test (thisAgent, &(c->data.tests.attr_test), sts); sts = simplify_test (thisAgent, &(c->data.tests.value_test), sts); } } return sts; } byte reverse_direction_of_relational_test (agent* thisAgent, byte type) { switch (type) { case NOT_EQUAL_TEST: return NOT_EQUAL_TEST; case LESS_TEST: return GREATER_TEST; case GREATER_TEST: return LESS_TEST; case LESS_OR_EQUAL_TEST: return GREATER_OR_EQUAL_TEST; case GREATER_OR_EQUAL_TEST: return LESS_OR_EQUAL_TEST; case SAME_TYPE_TEST: return SAME_TYPE_TEST; default: { char msg[BUFFER_MSG_SIZE]; strncpy (msg, "Internal error: arg to reverse_direction_of_relational_test\n", BUFFER_MSG_SIZE); msg[BUFFER_MSG_SIZE - 1] = 0; /* ensure null termination */ abort_with_fatal_error(thisAgent, msg); } } return 0; /* unreachable, but without it, gcc -Wall warns here */ } saved_test *restore_saved_tests_to_test (agent* thisAgent, test *t, Bool is_id_field, tc_number bound_vars_tc_number, saved_test *tests_to_restore, bool neg) { saved_test *st, *prev_st, *next_st; Bool added_it; Symbol *referent; complex_test *ct; prev_st = NIL; st = tests_to_restore; while (st) { next_st = st->next; added_it = FALSE; ct = complex_test_from_test(st->the_test); switch (ct->type) { case GOAL_ID_TEST: case IMPASSE_ID_TEST: if (! is_id_field) break; /* goal/impasse tests only go in id fields */ /* ... otherwise fall through to the next case below ... */ case DISJUNCTION_TEST: if (test_includes_equality_test_for_symbol (*t, st->var)) { add_new_test_to_test_if_not_already_there (thisAgent, t, st->the_test, neg); added_it = TRUE; } break; default: /* --- st->test is a relational test other than equality --- */ referent = ct->data.referent; if (test_includes_equality_test_for_symbol (*t, st->var)) { if (symbol_is_constant_or_marked_variable (referent, bound_vars_tc_number) || (st->var == referent)) { add_new_test_to_test_if_not_already_there (thisAgent, t, st->the_test, neg); added_it = TRUE; } } else if (test_includes_equality_test_for_symbol (*t, referent)) { if (symbol_is_constant_or_marked_variable (st->var, bound_vars_tc_number) || (st->var == referent)) { ct->type = reverse_direction_of_relational_test (thisAgent, ct->type); ct->data.referent = st->var; st->var = referent; add_new_test_to_test_if_not_already_there (thisAgent, t, st->the_test, neg); added_it = TRUE; } } break; } /* end of switch statement */ if (added_it) { if (prev_st) prev_st->next = next_st; else tests_to_restore = next_st; symbol_remove_ref (thisAgent, st->var); free_with_pool (&thisAgent->saved_test_pool, st); } else { prev_st = st; } st = next_st; } /* end of while (st) */ return tests_to_restore; }
inline bool wma_forgetting_update_p_queue( agent* my_agent ) { bool return_val = false; bool do_forget = false; slot* s; wme* w; if ( !my_agent->wma_forget_pq->empty() ) { wma_forget_p_queue::iterator pq_p = my_agent->wma_forget_pq->begin(); wma_d_cycle current_cycle = my_agent->wma_d_cycle_count; double decay_thresh = my_agent->wma_thresh_exp; bool forget_only_lti = ( my_agent->wma_params->forget_wme->get_value() == wma_param_container::lti ); if ( pq_p->first == current_cycle ) { wma_decay_set::iterator d_p=pq_p->second->begin(); wma_decay_set::iterator current_p; while ( d_p != pq_p->second->end() ) { current_p = d_p++; if ( wma_calculate_decay_activation( my_agent, (*current_p), current_cycle, false ) < decay_thresh ) { (*current_p)->forget_cycle = WMA_FORGOTTEN_CYCLE; if ( !forget_only_lti || ( (*current_p)->this_wme->id->id.smem_lti != NIL ) ) { do_forget = true; // implements all-or-nothing check for lti mode if ( forget_only_lti ) { for ( s=(*current_p)->this_wme->id->id.slots; (s && do_forget); s=s->next ) { for ( w=s->wmes; (w && do_forget); w=w->next ) { if ( w->preference->o_supported && ( !w->wma_decay_el || ( w->wma_decay_el->forget_cycle != WMA_FORGOTTEN_CYCLE ) ) ) { do_forget = false; } } } } if ( do_forget ) { if ( forget_only_lti ) { // implements all-or-nothing forget for lti mode for ( s=(*current_p)->this_wme->id->id.slots; (s && do_forget); s=s->next ) { for ( w=s->wmes; (w && do_forget); w=w->next ) { if ( wma_forgetting_forget_wme( my_agent, w ) ) { return_val = true; } } } } else { if ( wma_forgetting_forget_wme( my_agent, (*current_p)->this_wme ) ) { return_val = true; } } } } } else { wma_forgetting_move_in_p_queue( my_agent, (*current_p), wma_forgetting_estimate_cycle( my_agent, (*current_p), false ) ); } } // clean up decay set my_agent->wma_touched_sets->insert( pq_p->first ); pq_p->second->clear(); } // clean up touched sets for ( wma_decay_cycle_set::iterator touched_it=my_agent->wma_touched_sets->begin(); touched_it!=my_agent->wma_touched_sets->end(); touched_it++ ) { pq_p = my_agent->wma_forget_pq->find( *touched_it ); if ( ( pq_p != my_agent->wma_forget_pq->end() ) && ( pq_p->second->empty() ) ) { pq_p->second->~wma_decay_set(); free_with_pool( &( my_agent->wma_decay_set_pool ), pq_p->second ); my_agent->wma_forget_pq->erase( pq_p ); } } my_agent->wma_touched_sets->clear(); } return return_val; }
/* =============================== =============================== */ void destroy_soar_agent (agent * delete_agent) { //print(delete_agent, "\nDestroying agent %s.\n", delete_agent->name); /* AGR 532 */ ///////////////////////////////////////////////////////// // Soar Modules - could potentially rely on hash tables ///////////////////////////////////////////////////////// // cleanup exploration for ( int i=0; i<EXPLORATION_PARAMS; i++ ) delete delete_agent->exploration_params[ i ]; // cleanup Soar-RL delete_agent->rl_params->apoptosis->set_value( rl_param_container::apoptosis_none ); delete delete_agent->rl_prods; delete delete_agent->rl_params; delete delete_agent->rl_stats; delete_agent->rl_params = NULL; // apoptosis needs to know this for excise_all_productions below // cleanup select select_init( delete_agent ); delete delete_agent->select; // cleanup predict delete delete_agent->prediction; // cleanup wma delete_agent->wma_params->activation->set_value( off ); delete delete_agent->wma_forget_pq; delete delete_agent->wma_touched_elements; delete delete_agent->wma_touched_sets; delete delete_agent->wma_params; delete delete_agent->wma_stats; delete delete_agent->wma_timers; // cleanup epmem epmem_close( delete_agent ); delete delete_agent->epmem_params; delete delete_agent->epmem_stats; delete delete_agent->epmem_timers; delete delete_agent->epmem_node_removals; delete delete_agent->epmem_node_mins; delete delete_agent->epmem_node_maxes; delete delete_agent->epmem_edge_removals; delete delete_agent->epmem_edge_mins; delete delete_agent->epmem_edge_maxes; delete delete_agent->epmem_id_repository; delete delete_agent->epmem_id_replacement; delete delete_agent->epmem_id_ref_counts; delete delete_agent->epmem_id_removes; delete delete_agent->epmem_wme_adds; delete delete_agent->epmem_promotions; delete delete_agent->epmem_db; // cleanup smem smem_close( delete_agent ); delete delete_agent->smem_changed_ids; delete delete_agent->smem_params; delete delete_agent->smem_stats; delete delete_agent->smem_timers; delete delete_agent->smem_db; // cleanup statistics db stats_close( delete_agent ); delete delete_agent->stats_db; delete_agent->stats_db = 0; delete delete_agent->debug_params; ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// remove_built_in_rhs_functions(delete_agent); getSoarInstance()->Delete_Agent(delete_agent->name); /* Free structures stored in agent structure */ free(delete_agent->name); free(delete_agent->top_dir_stack->directory); free(delete_agent->top_dir_stack); /* Freeing the agent's multi attributes structure */ multi_attribute* lastmattr = 0; for ( multi_attribute* curmattr = delete_agent->multi_attributes; curmattr != 0; curmattr = curmattr->next ) { symbol_remove_ref(delete_agent, curmattr->symbol); free_memory(delete_agent, lastmattr, MISCELLANEOUS_MEM_USAGE); lastmattr = curmattr; } free_memory(delete_agent, lastmattr, MISCELLANEOUS_MEM_USAGE); /* Freeing all the productions owned by this agent */ excise_all_productions(delete_agent, false); /* Releasing all the predefined symbols */ release_predefined_symbols(delete_agent); /* Releasing rete stuff RPM 11/06 */ free_with_pool(&delete_agent->rete_node_pool, delete_agent->dummy_top_node); free_with_pool(&delete_agent->token_pool, delete_agent->dummy_top_token); /* Cleaning up the various callbacks TODO: Not clear why callbacks need to take the agent pointer essentially twice. */ soar_remove_all_monitorable_callbacks(delete_agent); /* RPM 9/06 begin */ free_memory(delete_agent, delete_agent->left_ht, HASH_TABLE_MEM_USAGE); free_memory(delete_agent, delete_agent->right_ht, HASH_TABLE_MEM_USAGE); free_memory(delete_agent, delete_agent->rhs_variable_bindings, MISCELLANEOUS_MEM_USAGE); /* Releasing memory allocated in inital call to start_lex_from_file from init_lexer */ free_memory_block_for_string(delete_agent, delete_agent->current_file->filename); free_memory (delete_agent, delete_agent->current_file, MISCELLANEOUS_MEM_USAGE); /* Releasing trace formats (needs to happen before tracing hashtables are released) */ remove_trace_format (delete_agent, FALSE, FOR_ANYTHING_TF, NIL); remove_trace_format (delete_agent, FALSE, FOR_STATES_TF, NIL); Symbol *evaluate_object_sym = find_sym_constant (delete_agent, "evaluate-object"); remove_trace_format (delete_agent, FALSE, FOR_OPERATORS_TF, evaluate_object_sym); remove_trace_format (delete_agent, TRUE, FOR_STATES_TF, NIL); remove_trace_format (delete_agent, TRUE, FOR_OPERATORS_TF, NIL); /* Releasing hashtables allocated in init_tracing */ for (int i=0; i<3; i++) { free_hash_table(delete_agent, delete_agent->object_tr_ht[i]); free_hash_table(delete_agent, delete_agent->stack_tr_ht[i]); } /* Releasing memory allocated in init_rete */ for (int i=0; i<16; i++) { free_hash_table(delete_agent, delete_agent->alpha_hash_tables[i]); } /* Releasing other hashtables */ free_hash_table(delete_agent, delete_agent->variable_hash_table); free_hash_table(delete_agent, delete_agent->identifier_hash_table); free_hash_table(delete_agent, delete_agent->sym_constant_hash_table); free_hash_table(delete_agent, delete_agent->int_constant_hash_table); free_hash_table(delete_agent, delete_agent->float_constant_hash_table); /* Releasing memory pools */ memory_pool* cur_pool = delete_agent->memory_pools_in_use; memory_pool* next_pool; while(cur_pool != NIL) { next_pool = cur_pool->next; free_memory_pool(delete_agent, cur_pool); cur_pool = next_pool; } /* RPM 9/06 end */ // dynamic memory pools (cleared in the last step) for ( std::map< size_t, memory_pool* >::iterator it=delete_agent->dyn_memory_pools->begin(); it!=delete_agent->dyn_memory_pools->end(); it++ ) { delete it->second; } delete delete_agent->dyn_memory_pools; delete delete_agent->dyn_counters; // JRV: Frees data used by XML generation xml_destroy( delete_agent ); /* Free soar agent structure */ delete delete_agent; }