rhs_value create_RHS_value(agent* thisAgent, rhs_value rv, condition* cond, char first_letter, ExplainTraceType ebcTraceType) { cons* c, *new_c, *prev_new_c; cons* fl, *new_fl; Symbol* sym; int64_t index; char prefix[2]; test t;//, original_t; uint64_t lO_id = 0; /* (1) Reteloc identifiers or constants originally bound to variables * (2) unbound_vars for unbound vars of course * (3) rhs_symbols for literal constants, including those in RHS functions */ if (rhs_value_is_reteloc(rv)) { /* Symbol pointed to by a rete location * This case seems to only be for identifiers or constants originally bound to variables */ t = var_test_bound_in_reconstructed_conds(thisAgent, cond, rhs_value_to_reteloc_field_num(rv), rhs_value_to_reteloc_levels_up(rv)); return allocate_rhs_value_for_symbol(thisAgent, t->data.referent, t->inst_identity, 0, t->identity); } if (rhs_value_is_unboundvar(rv)) { /* Unbound variable */ index = static_cast<int64_t>(rhs_value_to_unboundvar(rv)); if (! *(thisAgent->rhs_variable_bindings + index)) { prefix[0] = first_letter; prefix[1] = 0; sym = thisAgent->symbolManager->generate_new_variable(prefix); *(thisAgent->rhs_variable_bindings + index) = sym; if (thisAgent->highest_rhs_unboundvar_index < index) { thisAgent->highest_rhs_unboundvar_index = index; } if (ebcTraceType == Explanation_Trace) { lO_id = thisAgent->explanationBasedChunker->get_or_create_inst_identity_for_sym(sym); } /* generate will increment the refcount on the new variable, so don't need to do it here. */ return allocate_rhs_value_for_symbol_no_refcount(thisAgent, sym, lO_id, 0, NULL, true); } else { /* unbound variable was already created in previous rhs action */ sym = *(thisAgent->rhs_variable_bindings + index); } if (ebcTraceType == Explanation_Trace) { lO_id = thisAgent->explanationBasedChunker->get_or_create_inst_identity_for_sym(sym); } return allocate_rhs_value_for_symbol(thisAgent, sym, lO_id, 0, NULL, true); } if (rhs_value_is_funcall(rv)) { fl = rhs_value_to_funcall_list(rv); allocate_cons(thisAgent, &new_fl); new_fl->first = fl->first; prev_new_c = new_fl; for (c = fl->rest; c != NIL; c = c->rest) { allocate_cons(thisAgent, &new_c); new_c->first = create_RHS_value(thisAgent, static_cast<char*>(c->first), cond, first_letter, ebcTraceType); prev_new_c->rest = new_c; prev_new_c = new_c; } prev_new_c->rest = NIL; return funcall_list_to_rhs_value(new_fl); } else { /* Literal values including those in function calls. */ rhs_symbol rs = rhs_value_to_rhs_symbol(rv); if (ebcTraceType == Explanation_Trace) return allocate_rhs_value_for_symbol(thisAgent, rs->referent, rs->inst_identity, rs->cv_id, rs->identity, rs->was_unbound_var); else return allocate_rhs_value_for_symbol(thisAgent, rs->referent, LITERAL_VALUE, 0, NULL, rs->was_unbound_var); } }
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; }