char first_letter_from_rhs_value(rhs_value rv) { if (rhs_value_is_symbol(rv)) { return first_letter_from_symbol(rhs_value_to_symbol(rv)); } return '*'; /* function calls, reteloc's, unbound variables */ }
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; }
// 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; }