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; }
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 remove_output_link_tc_info(output_link * ol) { cons *c, *prev_c; Symbol *id; while (ol->ids_in_tc) { /* for each id in the old TC... */ c = ol->ids_in_tc; ol->ids_in_tc = c->rest; id = c->first; free_cons(c); /* --- remove "ol" from the list of associated_output_links(id) --- */ prev_c = NIL; for (c = id->id.associated_output_links; c != NIL; prev_c = c, c = c->rest) if (c->first == ol) break; if (!c) { char msg[MESSAGE_SIZE]; strncpy(msg, "io.c: Internal error: can't find output link in id's list\n", MESSAGE_SIZE); msg[MESSAGE_SIZE - 1] = 0; abort_with_fatal_error(msg); } if (prev_c) prev_c->rest = c->rest; else id->id.associated_output_links = c->rest; free_cons(c); symbol_remove_ref(id); } }
void release_io_symbol(Symbol * sym) { symbol_remove_ref(sym); }
// performs the rl update at a state void rl_perform_update( agent *my_agent, double op_value, bool op_rl, Symbol *goal, bool update_efr ) { bool using_gaps = ( my_agent->rl_params->temporal_extension->get_value() == soar_module::on ); if ( !using_gaps || op_rl ) { rl_data *data = goal->id.rl_info; if ( !data->prev_op_rl_rules->empty() ) { rl_et_map::iterator iter; double alpha = my_agent->rl_params->learning_rate->get_value(); double lambda = my_agent->rl_params->et_decay_rate->get_value(); double gamma = my_agent->rl_params->discount_rate->get_value(); double tolerance = my_agent->rl_params->et_tolerance->get_value(); double theta = my_agent->rl_params->meta_learning_rate->get_value(); // if temporal_discount is off, don't discount for gaps unsigned int effective_age = data->hrl_age + 1; if (my_agent->rl_params->temporal_discount->get_value() == soar_module::on) { effective_age += data->gap_age; } double discount = pow( gamma, static_cast< double >( effective_age ) ); // notify of gap closure if ( data->gap_age && using_gaps && my_agent->sysparams[ TRACE_RL_SYSPARAM ] ) { char buf[256]; SNPRINTF( buf, 254, "gap ended (%c%llu)", goal->id.name_letter, static_cast<long long unsigned>(goal->id.name_number) ); print( my_agent, buf ); xml_generate_warning( my_agent, buf ); } // Iterate through eligibility_traces, decay traces. If less than TOLERANCE, remove from map. if ( lambda == 0 ) { if ( !data->eligibility_traces->empty() ) { data->eligibility_traces->clear(); } } else { for ( iter = data->eligibility_traces->begin(); iter != data->eligibility_traces->end(); ) { iter->second *= lambda; iter->second *= discount; if ( iter->second < tolerance ) { data->eligibility_traces->erase( iter++ ); } else { ++iter; } } } // Update trace for just fired prods double sum_old_ecr = 0.0; double sum_old_efr = 0.0; if ( !data->prev_op_rl_rules->empty() ) { double trace_increment = ( 1.0 / static_cast<double>( data->prev_op_rl_rules->size() ) ); rl_rule_list::iterator p; for ( p=data->prev_op_rl_rules->begin(); p!=data->prev_op_rl_rules->end(); p++ ) { sum_old_ecr += (*p)->rl_ecr; sum_old_efr += (*p)->rl_efr; iter = data->eligibility_traces->find( (*p) ); if ( iter != data->eligibility_traces->end() ) { iter->second += trace_increment; } else { (*data->eligibility_traces)[ (*p) ] = trace_increment; } } } // For each prod with a trace, perform update { double old_ecr, old_efr; double delta_ecr, delta_efr; double new_combined, new_ecr, new_efr; double delta_t = (data->reward + discount * op_value) - (sum_old_ecr + sum_old_efr); for ( iter = data->eligibility_traces->begin(); iter != data->eligibility_traces->end(); iter++ ) { production *prod = iter->first; // get old vals old_ecr = prod->rl_ecr; old_efr = prod->rl_efr; // Adjust alpha based on decay policy // Miller 11/14/2011 double adjusted_alpha; switch (my_agent->rl_params->decay_mode->get_value()) { case rl_param_container::exponential_decay: adjusted_alpha = 1.0 / (prod->rl_update_count + 1.0); break; case rl_param_container::logarithmic_decay: adjusted_alpha = 1.0 / (log(prod->rl_update_count + 1.0) + 1.0); break; case rl_param_container::delta_bar_delta_decay: { // Note that in this case, x_i = 1.0 for all productions that are being updated. // Those values have been included here for consistency with the algorithm as described in the delta bar delta paper. prod->rl_delta_bar_delta_beta = prod->rl_delta_bar_delta_beta + theta * delta_t * 1.0 * prod->rl_delta_bar_delta_h; adjusted_alpha = exp(prod->rl_delta_bar_delta_beta); double decay_term = 1.0 - adjusted_alpha * 1.0 * 1.0; if (decay_term < 0.0) decay_term = 0.0; prod->rl_delta_bar_delta_h = prod->rl_delta_bar_delta_h * decay_term + adjusted_alpha * delta_t * 1.0; break; } case rl_param_container::normal_decay: default: adjusted_alpha = alpha; break; } // calculate updates delta_ecr = ( adjusted_alpha * iter->second * ( data->reward - sum_old_ecr ) ); if ( update_efr ) { delta_efr = ( adjusted_alpha * iter->second * ( ( discount * op_value ) - sum_old_efr ) ); } else { delta_efr = 0.0; } // calculate new vals new_ecr = ( old_ecr + delta_ecr ); new_efr = ( old_efr + delta_efr ); new_combined = ( new_ecr + new_efr ); // print as necessary if ( my_agent->sysparams[ TRACE_RL_SYSPARAM ] ) { std::ostringstream ss; ss << "RL update " << prod->name->sc.name << " " << old_ecr << " " << old_efr << " " << old_ecr + old_efr << " -> " << new_ecr << " " << new_efr << " " << new_combined ; std::string temp_str( ss.str() ); print( my_agent, "%s\n", temp_str.c_str() ); xml_generate_message( my_agent, temp_str.c_str() ); // Log update to file if the log file has been set std::string log_path = my_agent->rl_params->update_log_path->get_value(); if (!log_path.empty()) { std::ofstream file(log_path.c_str(), std::ios_base::app); file << ss.str() << std::endl; file.close(); } } // Change value of rule symbol_remove_ref( my_agent, rhs_value_to_symbol( prod->action_list->referent ) ); prod->action_list->referent = symbol_to_rhs_value( make_float_constant( my_agent, new_combined ) ); prod->rl_update_count += 1; prod->rl_ecr = new_ecr; prod->rl_efr = new_efr; // change documentation if ( my_agent->rl_params->meta->get_value() == soar_module::on ) { if ( prod->documentation ) { free_memory_block_for_string( my_agent, prod->documentation ); } std::stringstream doc_ss; const std::vector<std::pair<std::string, param_accessor<double> *> > &documentation_params = my_agent->rl_params->get_documentation_params(); for (std::vector<std::pair<std::string, param_accessor<double> *> >::const_iterator doc_params_it = documentation_params.begin(); doc_params_it != documentation_params.end(); ++doc_params_it) { doc_ss << doc_params_it->first << "=" << doc_params_it->second->get_param(prod) << ";"; } prod->documentation = make_memory_block_for_string(my_agent, doc_ss.str().c_str()); /* std::string rlupdates( "rlupdates=" ); std::string val; to_string( static_cast< uint64_t >( prod->rl_update_count ), val ); rlupdates.append( val ); prod->documentation = make_memory_block_for_string( my_agent, rlupdates.c_str() ); */ } // Change value of preferences generated by current instantiations of this rule if ( prod->instantiations ) { for ( instantiation *inst = prod->instantiations; inst; inst = inst->next ) { for ( preference *pref = inst->preferences_generated; pref; pref = pref->inst_next ) { symbol_remove_ref( my_agent, pref->referent ); pref->referent = make_float_constant( my_agent, new_combined ); } } } } } } data->gap_age = 0; data->hrl_age = 0; data->reward = 0.0; } }
// builds a template instantiation Symbol *rl_build_template_instantiation( agent *my_agent, instantiation *my_template_instance, struct token_struct *tok, wme *w ) { Symbol* return_val = NULL; // initialize production conditions if ( my_template_instance->prod->rl_template_conds == NIL ) { not_struct* nots; condition* c_top; condition* c_bottom; p_node_to_conditions_and_nots( my_agent, my_template_instance->prod->p_node, NIL, NIL, &( c_top ), &( c_bottom ), &( nots ), NIL ); my_template_instance->prod->rl_template_conds = c_top; } // initialize production instantiation set if ( my_template_instance->prod->rl_template_instantiations == NIL ) { my_template_instance->prod->rl_template_instantiations = new rl_symbol_map_set; } // get constants rl_symbol_map constant_map; { rl_get_template_constants( my_template_instance->prod->rl_template_conds, my_template_instance->top_of_instantiated_conditions, &( constant_map ) ); } // try to insert into instantiation set //if ( !constant_map.empty() ) { std::pair< rl_symbol_map_set::iterator, bool > ins_result = my_template_instance->prod->rl_template_instantiations->insert( constant_map ); if ( ins_result.second ) { Symbol *id, *attr, *value, *referent; production *my_template = my_template_instance->prod; action *my_action = my_template->action_list; char first_letter; double init_value = 0; condition *cond_top, *cond_bottom; // make unique production name Symbol *new_name_symbol; std::string new_name = ""; std::string empty_string = ""; std::string temp_id; int new_id; do { new_id = rl_next_template_id( my_agent ); to_string( new_id, temp_id ); new_name = ( "rl*" + empty_string + my_template->name->sc.name + "*" + temp_id ); } while ( find_sym_constant( my_agent, new_name.c_str() ) != NIL ); new_name_symbol = make_sym_constant( my_agent, new_name.c_str() ); // prep conditions copy_condition_list( my_agent, my_template_instance->top_of_instantiated_conditions, &cond_top, &cond_bottom ); rl_add_goal_or_impasse_tests_to_conds( my_agent, cond_top ); reset_variable_generator( my_agent, cond_top, NIL ); my_agent->variablization_tc = get_new_tc_number( my_agent ); variablize_condition_list( my_agent, cond_top ); variablize_nots_and_insert_into_conditions( my_agent, my_template_instance->nots, cond_top ); // get the preference value id = instantiate_rhs_value( my_agent, my_action->id, -1, 's', tok, w ); attr = instantiate_rhs_value( my_agent, my_action->attr, id->id.level, 'a', tok, w ); first_letter = first_letter_from_symbol( attr ); value = instantiate_rhs_value( my_agent, my_action->value, id->id.level, first_letter, tok, w ); referent = instantiate_rhs_value( my_agent, my_action->referent, id->id.level, first_letter, tok, w ); // clean up after yourself :) symbol_remove_ref( my_agent, id ); symbol_remove_ref( my_agent, attr ); symbol_remove_ref( my_agent, value ); symbol_remove_ref( my_agent, referent ); // make new action list action *new_action = rl_make_simple_action( my_agent, id, attr, value, referent ); new_action->preference_type = NUMERIC_INDIFFERENT_PREFERENCE_TYPE; // make new production production *new_production = make_production( my_agent, USER_PRODUCTION_TYPE, new_name_symbol, &cond_top, &cond_bottom, &new_action, false ); // set initial expected reward values { if ( referent->common.symbol_type == INT_CONSTANT_SYMBOL_TYPE ) { init_value = static_cast< double >( referent->ic.value ); } else if ( referent->common.symbol_type == FLOAT_CONSTANT_SYMBOL_TYPE ) { init_value = referent->fc.value; } new_production->rl_ecr = 0.0; new_production->rl_efr = init_value; } // attempt to add to rete, remove if duplicate if ( add_production_to_rete( my_agent, new_production, cond_top, NULL, FALSE, TRUE ) == DUPLICATE_PRODUCTION ) { excise_production( my_agent, new_production, false ); rl_revert_template_id( my_agent ); new_name_symbol = NULL; } deallocate_condition_list( my_agent, cond_top ); return_val = new_name_symbol; } } return return_val; }
Symbol *instantiate_rhs_value (rhs_value rv, goal_stack_level new_id_level, char new_id_letter, struct token_struct *tok, wme *w) { list *fl; list *arglist; cons *c, *prev_c, *arg_cons; rhs_function *rf; Symbol *result; bool nil_arg_found; if (rhs_value_is_symbol(rv)) { result = rhs_value_to_symbol(rv); symbol_add_ref (result); return result; } if (rhs_value_is_unboundvar(rv)) { long index; Symbol *sym; index = rhs_value_to_unboundvar(rv); if (firer_highest_rhs_unboundvar_index < index) firer_highest_rhs_unboundvar_index = index; sym = *(current_agent(rhs_variable_bindings)+index); if (!sym) { sym = make_new_identifier (new_id_letter, new_id_level); *(current_agent(rhs_variable_bindings)+index) = sym; return sym; } else if (sym->common.symbol_type==VARIABLE_SYMBOL_TYPE) { new_id_letter = *(sym->var.name + 1); sym = make_new_identifier (new_id_letter, new_id_level); *(current_agent(rhs_variable_bindings)+index) = sym; return sym; } else { symbol_add_ref (sym); return sym; } } if (rhs_value_is_reteloc(rv)) { result = get_symbol_from_rete_loc ((unsigned short) rhs_value_to_reteloc_levels_up(rv), (byte)rhs_value_to_reteloc_field_num(rv), tok, w); symbol_add_ref (result); return result; } fl = rhs_value_to_funcall_list(rv); rf = fl->first; /* --- build up a list of the argument values --- */ prev_c = NIL; nil_arg_found = FALSE; arglist = NIL; /* unnecessary, but gcc -Wall warns without it */ for (arg_cons=fl->rest; arg_cons!=NIL; arg_cons=arg_cons->rest) { allocate_cons (&c); c->first = instantiate_rhs_value (arg_cons->first, new_id_level, new_id_letter, tok, w); if (! c->first) nil_arg_found = TRUE; if (prev_c) prev_c->rest = c; else arglist = c; prev_c = c; } if (prev_c) prev_c->rest = NIL; else arglist = NIL; /* --- if all args were ok, call the function --- */ if (!nil_arg_found) result = (*(rf->f))(arglist); else result = NIL; /* --- scan through arglist, dereference symbols and deallocate conses --- */ for (c=arglist; c!=NIL; c=c->rest) if (c->first) symbol_remove_ref ((Symbol *)(c->first)); free_list (arglist); return result; }
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; }
void init_soar_agent(agent* thisAgent) { /* JC ADDED: initialize the rhs function linked list */ thisAgent->rhs_functions = NIL; /* --- initialize everything --- */ init_symbol_tables(thisAgent); create_predefined_symbols(thisAgent); init_production_utilities(thisAgent); init_built_in_rhs_functions (thisAgent); init_rete (thisAgent); init_lexer (thisAgent); init_firer (thisAgent); init_decider (thisAgent); init_soar_io (thisAgent); init_chunker (thisAgent); init_tracing (thisAgent); init_explain(thisAgent); /* AGR 564 */ select_init(thisAgent); predict_init(thisAgent); init_memory_pool( thisAgent, &( thisAgent->gds_pool ), sizeof( goal_dependency_set ), "gds" ); init_memory_pool( thisAgent, &( thisAgent->rl_info_pool ), sizeof( rl_data ), "rl_id_data" ); init_memory_pool( thisAgent, &( thisAgent->rl_et_pool ), sizeof( rl_et_map ), "rl_et" ); init_memory_pool( thisAgent, &( thisAgent->rl_rule_pool ), sizeof( rl_rule_list ), "rl_rules" ); init_memory_pool( thisAgent, &( thisAgent->wma_decay_element_pool ), sizeof( wma_decay_element ), "wma_decay" ); init_memory_pool( thisAgent, &( thisAgent->wma_decay_set_pool ), sizeof( wma_decay_set ), "wma_decay_set" ); init_memory_pool( thisAgent, &( thisAgent->wma_wme_oset_pool ), sizeof( wma_pooled_wme_set ), "wma_oset" ); init_memory_pool( thisAgent, &( thisAgent->wma_slot_refs_pool ), sizeof( wma_sym_reference_map ), "wma_slot_ref" ); init_memory_pool( thisAgent, &( thisAgent->epmem_wmes_pool ), sizeof( epmem_wme_stack ), "epmem_wmes" ); init_memory_pool( thisAgent, &( thisAgent->epmem_info_pool ), sizeof( epmem_data ), "epmem_id_data" ); init_memory_pool( thisAgent, &( thisAgent->smem_wmes_pool ), sizeof( smem_wme_stack ), "smem_wmes" ); init_memory_pool( thisAgent, &( thisAgent->smem_info_pool ), sizeof( smem_data ), "smem_id_data" ); init_memory_pool( thisAgent, &( thisAgent->epmem_literal_pool ), sizeof( epmem_literal), "epmem_literals" ); init_memory_pool( thisAgent, &( thisAgent->epmem_pedge_pool ), sizeof( epmem_pedge ), "epmem_pedges" ); init_memory_pool( thisAgent, &( thisAgent->epmem_uedge_pool ), sizeof( epmem_uedge ), "epmem_uedges" ); init_memory_pool( thisAgent, &( thisAgent->epmem_interval_pool ), sizeof( epmem_interval ), "epmem_intervals" ); thisAgent->epmem_params->exclusions->set_value( "epmem" ); thisAgent->epmem_params->exclusions->set_value( "smem" ); thisAgent->smem_params->base_incremental_threshes->set_string( "10" ); #ifdef REAL_TIME_BEHAVIOR /* RMJ */ init_real_time(thisAgent); #endif /* --- add default object trace formats --- */ add_trace_format (thisAgent, FALSE, FOR_ANYTHING_TF, NIL, "%id %ifdef[(%v[name])]"); add_trace_format (thisAgent, FALSE, FOR_STATES_TF, NIL, "%id %ifdef[(%v[attribute] %v[impasse])]"); { Symbol *evaluate_object_sym; evaluate_object_sym = make_sym_constant (thisAgent, "evaluate-object"); add_trace_format (thisAgent, FALSE, FOR_OPERATORS_TF, evaluate_object_sym, "%id (evaluate-object %o[object])"); symbol_remove_ref (thisAgent, evaluate_object_sym); } /* --- add default stack trace formats --- */ add_trace_format (thisAgent, TRUE, FOR_STATES_TF, NIL, "%right[6,%dc]: %rsd[ ]==>S: %cs"); add_trace_format (thisAgent, TRUE, FOR_OPERATORS_TF, NIL, "%right[6,%dc]: %rsd[ ] O: %co"); reset_statistics (thisAgent); /* RDF: For gSKI */ init_agent_memory(thisAgent); /* END */ }
/* =============================== =============================== */ 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; }