void add_id_to_output_link_tc(Symbol * id) { slot *s; wme *w; /* --- if id is already in the TC, exit --- */ if (id->id.tc_num == current_agent(output_link_tc_num)) return; id->id.tc_num = current_agent(output_link_tc_num); /* --- add id to output_link's list --- */ push(id, current_agent(output_link_for_tc)->ids_in_tc); symbol_add_ref(id); /* make sure the id doesn't get deallocated before we have a chance to free the cons cell we just added */ /* --- add output_link to id's list --- */ push(current_agent(output_link_for_tc), id->id.associated_output_links); /* --- do TC through working memory --- */ /* --- scan through all wmes for all slots for this id --- */ for (w = id->id.input_wmes; w != NIL; w = w->next) if (w->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE) add_id_to_output_link_tc(w->value); for (s = id->id.slots; s != NIL; s = s->next) for (w = s->wmes; w != NIL; w = w->next) if (w->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE) add_id_to_output_link_tc(w->value); /* don't need to check impasse_wmes, because we couldn't have a pointer to a goal or impasse identifier */ }
void retract_instantiation (instantiation *inst) { preference *pref, *next; bool retracted_a_preference; bool trace_it; /* --- invoke callback function --- */ #ifndef NO_CALLBACKS soar_invoke_callbacks(soar_agent, RETRACTION_CALLBACK, (soar_call_data) inst); #endif retracted_a_preference = FALSE; trace_it = trace_firings_of_inst (inst); /* --- retract any preferences that are in TM and aren't o-supported --- */ pref = inst->preferences_generated; while (pref!=NIL) { next = pref->inst_next; if (pref->in_tm && (! pref->o_supported)) { if (trace_it) { if (!retracted_a_preference) { if (get_printer_output_column()!=1) print ("\n"); /* AGR 617/634 */ print ("Retracting "); print_instantiation_with_wmes (inst, (wme_trace_type)current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM]); if (current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) print (" -->"); } if (current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { print (" "); print_preference (pref); } } remove_preference_from_tm (pref); retracted_a_preference = TRUE; } pref = next; } /* --- remove inst from list of instantiations of this production --- */ remove_from_dll (inst->prod->instantiations, inst, next, prev); /* --- if retracting a justification, excise it --- */ /* * if the reference_count on the production is 1 (or less) then the * only thing supporting this justification is the instantiation, hence * it has already been excised, and doing it again is wrong. */ if (inst->prod->type==JUSTIFICATION_PRODUCTION_TYPE && inst->prod->reference_count > 1) excise_production (inst->prod, FALSE); /* --- mark as no longer in MS, and possibly deallocate --- */ inst->in_ms = FALSE; possibly_deallocate_instantiation (inst); }
void lex_ampersand (void) { /* Lexeme might be "&", or symbol */ /* Note: this routine relies on & being a constituent character */ read_constituent_string(); if (current_agent(lexeme).length==1) { current_agent(lexeme).type = AMPERSAND_LEXEME; return; } determine_type_of_constituent_string(); }
void lex_equal (void) { /* Lexeme might be "=", or symbol */ /* Note: this routine relies on = being a constituent character */ read_constituent_string(); if (current_agent(lexeme).length==1) { current_agent(lexeme).type = EQUAL_LEXEME; return; } determine_type_of_constituent_string(); }
void skip_ahead_to_balanced_parentheses (int parentheses_level) { while (TRUE) { if (current_agent(lexeme).type==EOF_LEXEME) return; if ((current_agent(lexeme).type==R_PAREN_LEXEME) && (parentheses_level==current_agent(current_file)->parentheses_level)) return; get_lexeme(); } }
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 lex_period (void) { store_and_advance(); finish(); /* --- if we stopped at '.', it might be a floating-point number, so be careful to check for this case --- */ if (isdigit(current_agent(current_char))) read_rest_of_floating_point_number(); if (current_agent(lexeme).length==1) { current_agent(lexeme).type = PERIOD_LEXEME; return; } determine_type_of_constituent_string(); }
void lex_eof (void) { if (current_agent(current_file)->fake_rparen_at_eol) { do_fake_rparen(); return; } store_and_advance(); finish(); current_agent(lexeme).type = EOF_LEXEME; }
void read_constituent_string (void) { #ifdef __SC__ char *buf; int i,len; #endif while ((current_agent(current_char)!=EOF_AS_CHAR) && constituent_char[(unsigned char)current_agent(current_char)]) store_and_advance(); finish(); }
void calculate_output_link_tc_info(output_link * ol) { /* --- if link doesn't have any substructure, there's no TC --- */ if (ol->link_wme->value->common.symbol_type != IDENTIFIER_SYMBOL_TYPE) return; /* --- do TC starting with the link wme's value --- */ current_agent(output_link_for_tc) = ol; current_agent(output_link_tc_num) = get_new_tc_number(); add_id_to_output_link_tc(ol->link_wme->value); }
void do_input_cycle(void) { /* I don't really think we need to do this, so I'll try not using it. */ /* do_buffered_wm_and_ownership_changes(); */ current_agent(prev_top_state) = current_agent(top_state); current_agent(output_link_changed) = FALSE; }
bool remove_input_wme(wme * w) { wme *temp; /* --- a little bit of error checking --- */ if (!w) { print("Error: an input routine called remove_input_wme on a NULL wme.\n"); return FALSE; } for (temp = w->id->id.input_wmes; temp != NIL; temp = temp->next) if (temp == w) break; if (!temp) { print("Error: an input routine called remove_input_wme on a wme that\n"); print("isn't one of the input wmes currently in working memory.\n"); return FALSE; } /* SW NOTE: * Since we cannot capture wmes asserted during add_input_wme, * we will not capture wmes removed during this function call. */ /* Note: for efficiency, it might be better to use a hash table for the above test, rather than scanning the linked list. We could have one global hash table for all the input wmes in the system. */ /* --- go ahead and remove the wme --- */ remove_from_dll(w->id->id.input_wmes, w, next, prev); /* REW: begin 09.15.96 */ #ifndef SOAR_8_ONLY if (current_agent(operand2_mode)) { #endif if (w->gds) { if (w->gds->goal != NIL) { if (current_agent(soar_verbose_flag)) print("\nremove_input_wme: Removing goal %d because element in GDS changed.\n", w->gds->goal->id.level); gds_invalid_so_remove_goal(w); /* NOTE: the call to remove_wme_from_wm will take care of checking if GDS should be removed */ } } #ifndef SOAR_8_ONLY } #endif /* REW: end 09.15.96 */ remove_wme_from_wm(w); return TRUE; }
void trace_grounded_potentials(void) { tc_number tc; cons *c, *next_c, *prev_c; condition *pot; bool need_another_pass; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) print_string("\n\n*** Tracing Grounded Potentials ***\n"); #endif /* --- setup the tc of the ground set --- */ tc = get_new_tc_number(); for (c = current_agent(grounds); c != NIL; c = c->rest) add_cond_to_tc(c->first, tc, NIL, NIL); need_another_pass = TRUE; while (need_another_pass) { need_another_pass = FALSE; /* --- look for any potentials that are in the tc now --- */ prev_c = NIL; for (c = current_agent(positive_potentials); c != NIL; c = next_c) { next_c = c->rest; pot = c->first; if (cond_is_in_tc(pot, tc)) { /* --- pot is a grounded potential, move it over to ground set --- */ #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_BACKTRACING_SYSPARAM]) { print_string("\n-->Moving to grounds: "); print_wme(pot->bt.wme); } #endif if (prev_c) prev_c->rest = next_c; else current_agent(positive_potentials) = next_c; if (pot->bt.wme->grounds_tc != current_agent(grounds_tc)) { /* add pot to grounds */ pot->bt.wme->grounds_tc = current_agent(grounds_tc); c->rest = current_agent(grounds); current_agent(grounds) = c; add_cond_to_tc(pot, tc, NIL, NIL); need_another_pass = TRUE; } else { /* pot was already in the grounds, do don't add it */ free_cons(c); } } else { prev_c = c; } } /* end of for c */ } /* end of while need_another_pass */ }
void stop_lex_from_file (void) { lexer_source_file *lsf; if (reading_from_top_level()) { print ("Internal error: tried to stop_lex_from_file at top level\n"); return; } lsf = current_agent(current_file); current_agent(current_file) = current_agent(current_file)->parent_file; current_agent(current_char) = lsf->saved_current_char; current_agent(lexeme) = lsf->saved_lexeme; free_memory_block_for_string (lsf->filename); free_memory (lsf, MISCELLANEOUS_MEM_USAGE); }
void lex_digit (void) { int i; bool could_be_floating_point; read_constituent_string(); /* --- if we stopped at '.', it might be a floating-point number, so be careful to check for this case --- */ if (current_agent(current_char)=='.') { could_be_floating_point = TRUE; for (i=1; i<current_agent(lexeme).length; i++) if (! isdigit(current_agent(lexeme).string[i])) could_be_floating_point = FALSE; if (could_be_floating_point) read_rest_of_floating_point_number(); } determine_type_of_constituent_string(); }
void parallel_producer_consumer(int *buffer, int size, int *vec, int n, int n_threads) { int i, j; long long unsigned sum = 0; // Prevents successive threads creation by placing pragma omp // here instead of inner for statments. #pragma omp parallel num_threads(n_threads) \ private(i, j) \ reduction(+: sum) for(i = 0; i < n; i++) if(current_agent(i) == PRODUCER) #pragma omp for for (j = 0; j < size; j++) buffer[j] = vec[i] + j * vec[i + 1]; else #pragma omp for for (j = 0; j < size; j++) sum += buffer[j]; printf("%llu\n", sum); }
void lex_plus (void) { /* Lexeme might be +, number, or symbol */ /* Note: this routine relies on various things being constituent chars */ int i; bool could_be_floating_point; read_constituent_string(); /* --- if we stopped at '.', it might be a floating-point number, so be careful to check for this case --- */ if (current_agent(current_char)=='.') { could_be_floating_point = TRUE; for (i=1; i<current_agent(lexeme).length; i++) if (! isdigit(current_agent(lexeme).string[i])) could_be_floating_point = FALSE; if (could_be_floating_point) read_rest_of_floating_point_number(); } if (current_agent(lexeme).length==1) { current_agent(lexeme).type = PLUS_LEXEME; return; } determine_type_of_constituent_string(); }
void do_fake_rparen (void) { record_position_of_start_of_lexeme(); current_agent(lexeme).type = R_PAREN_LEXEME; current_agent(lexeme).length = 1; current_agent(lexeme).string[0] = ')'; current_agent(lexeme).string[1] = 0; if (current_agent(current_file)->parentheses_level > 0) current_agent(current_file)->parentheses_level--; current_agent(current_file)->fake_rparen_at_eol = FALSE; }
void start_lex_from_file (char *filename, FILE *already_opened_file) { lexer_source_file *lsf; lsf = allocate_memory (sizeof(lexer_source_file), MISCELLANEOUS_MEM_USAGE); lsf->saved_lexeme = current_agent(lexeme); lsf->saved_current_char = current_agent(current_char); lsf->parent_file = current_agent(current_file); current_agent(current_file) = lsf; lsf->filename = make_memory_block_for_string (filename); lsf->file = already_opened_file; lsf->fake_rparen_at_eol = FALSE; lsf->allow_ids = TRUE; lsf->parentheses_level = 0; lsf->column_of_start_of_last_lexeme = 0; lsf->line_of_start_of_last_lexeme = 0; lsf->current_line = 0; lsf->current_column = 0; lsf->buffer[0] = 0; current_agent(current_char) = ' '; /* whitespace--to force immediate read of first line */ }
void lex_greater (void) { /* Lexeme might be ">", ">=", ">>", or symbol */ /* Note: this routine relies on =,> being constituent characters */ read_constituent_string(); if (current_agent(lexeme).length==1) { current_agent(lexeme).type = GREATER_LEXEME; return; } if (current_agent(lexeme).length==2) { if (current_agent(lexeme).string[1]=='>') { current_agent(lexeme).type = GREATER_GREATER_LEXEME; return;} if (current_agent(lexeme).string[1]=='=') { current_agent(lexeme).type = GREATER_EQUAL_LEXEME; return; } } determine_type_of_constituent_string(); }
void sequential_producer_consumer(int *buffer, int size, int *vec, int n) { int i, j; long long unsigned sum = 0; for(i = 0; i < n; i++) if(current_agent(i) == PRODUCER) for(j = 0; j < size; j++) buffer[j] = vec[i] + j * vec[i + 1]; else for(j = 0; j < size; j++) sum += buffer[j]; printf("%llu\n", sum); }
void inform_output_module_of_wm_changes(list * wmes_being_added, list * wmes_being_removed) { cons *c; wme *w; /* if wmes are added, set flag so can stop when running til output */ for (c = wmes_being_added; c != NIL; c = c->rest) { w = c->first; if (w->id == current_agent(io_header)) { update_for_top_state_wme_addition(w); current_agent(output_link_changed) = TRUE; /* KJC 11/23/98 */ } if (w->id->id.associated_output_links) { update_for_io_wme_change(w); current_agent(output_link_changed) = TRUE; /* KJC 11/23/98 */ } #if DEBUG_RTO else { char id[100]; symbol_to_string(w->id, FALSE, id); if (!strcmp(id, "I3")) { print("--> Added to I3, but doesn't register as an OL change!"); } } #endif } for (c = wmes_being_removed; c != NIL; c = c->rest) { w = c->first; if (w->id == current_agent(io_header)) update_for_top_state_wme_removal(w); if (w->id->id.associated_output_links) update_for_io_wme_change(w); } }
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 update_for_top_state_wme_addition(wme * w) { output_link *ol; soar_callback *cb; char link_name[LINK_NAME_SIZE]; /* --- check whether the attribute is an output function --- */ symbol_to_string(w->attr, FALSE, link_name, LINK_NAME_SIZE); cb = soar_exists_callback_id(soar_agent, OUTPUT_PHASE_CALLBACK, link_name); if (!cb) return; /* --- create new output link structure --- */ allocate_with_pool(¤t_agent(output_link_pool), &ol); insert_at_head_of_dll(current_agent(existing_output_links), ol, next, prev); ol->status = NEW_OL_STATUS; ol->link_wme = w; wme_add_ref(w); ol->ids_in_tc = NIL; ol->cb = cb; /* --- make wme point to the structure --- */ w->output_link = ol; /* SW 07 10 2003 previously, this wouldn't be done until the first OUTPUT phase. However, if we add an output command in the 1st decision cycle, Soar seems to ignore it. There may be two things going on, the first having to do with the tc calculation, which may get done too late, in such a way that the initial calculation includes the command. The other thing appears to be that some data structures are not initialized until the first output phase. Namely, id->associated_output_links does not seem reflect the current output links until the first output-phase. To get past these issues, we fake a transitive closure calculation with the knowledge that the only thing on the output link at this point is the output-link identifier itself. This way, we capture a snapshot of the empty output link, so Soar can detect any changes that might occur before the first output_phase. */ current_agent(output_link_tc_num) = get_new_tc_number(); ol->link_wme->value->id.tc_num = current_agent(output_link_tc_num); current_agent(output_link_for_tc) = ol; /* --- add output_link to id's list --- */ push(current_agent(output_link_for_tc), ol->link_wme->value->id.associated_output_links); }
void lex_unknown (void) { if(reading_from_top_level() && current_agent(current_char) == 0) { } else { print ("Error: Unknown character encountered by lexer, code=%d\n", current_agent(current_char)); print ("File %s, line %lu, column %lu.\n", current_agent(current_file)->filename, current_agent(current_file)->current_line, current_agent(current_file)->current_column); if (! reading_from_top_level()) { respond_to_load_errors (); if (current_agent(load_errors_quit)) current_agent(current_char) = EOF_AS_CHAR; } } get_next_char(); get_lexeme(); }
void do_preference_phase (void) { production *prod; struct token_struct *tok; wme *w; instantiation *inst; /* AGR 617/634: These are 2 bug reports that report the same problem, namely that when 2 chunk firings happen in succession, there is an extra newline printed out. The simple fix is to monitor get_printer_output_column and see if it's at the beginning of a line or not when we're ready to print a newline. 94.11.14 */ if (current_agent(sysparams)[TRACE_PHASES_SYSPARAM]) { if (current_agent(operand2_mode) == TRUE) { switch (current_agent(FIRING_TYPE)) { case PE_PRODS: print ("\t--- Firing Productions (PE) ---\n"); break; case IE_PRODS: print ("\t--- Firing Productions (IE) ---\n"); break; } } else print ("\n--- Preference Phase ---\n"); } current_agent(newly_created_instantiations) = NIL; /* MVP 6-8-94 */ while (get_next_assertion (&prod, &tok, &w)) { if (current_agent(max_chunks_reached)) { current_agent(system_halted) = TRUE; return; } create_instantiation (prod, tok, w); } assert_new_preferences (); while (get_next_retraction (&inst)) retract_instantiation (inst); /* REW: begin 08.20.97 */ /* In Waterfall, if there are nil goal retractions, then we want to retract them as well, even though they are not associated with any particular goal (because their goal has been deleted). The functionality of this separte routine could have been easily combined in get_next_retraction but I wanted to highlight the distinction between regualr retractions (those that can be mapped onto a goal) and nil goal retractions that require a special data strucutre (because they don't appear on any goal) REW. */ if (current_agent(operand2_mode) && current_agent(nil_goal_retractions)) { while (get_next_nil_goal_retraction (&inst)) retract_instantiation (inst); } /* REW: end 08.20.97 */ }
void do_input_cycle(void) { wme *w; #ifndef TRACE_CONTEXT_DECISIONS_ONLY if (current_agent(sysparams)[TRACE_PHASES_SYSPARAM]) print("\n--- Input Phase --- \n"); #endif if (current_agent(prev_top_state) && (!current_agent(top_state))) { /* --- top state was just removed --- */ release_io_symbol(current_agent(io_header)); release_io_symbol(current_agent(io_header_input)); release_io_symbol(current_agent(io_header_output)); current_agent(io_header) = NIL; /* RBD added 3/25/95 */ current_agent(io_header_input) = NIL; /* RBD added 3/25/95 */ current_agent(io_header_output) = NIL; /* KJC added 3/3/99 */ current_agent(io_header_link) = NIL; /* KJC added 3/3/99 */ soar_invoke_callbacks(soar_agent, INPUT_PHASE_CALLBACK, (soar_call_data) TOP_STATE_JUST_REMOVED); } else if ((!current_agent(prev_top_state)) && current_agent(top_state)) { /* --- top state was just created --- */ /* Create io structure on top state. */ current_agent(io_header) = get_new_io_identifier('I'); current_agent(io_header_link) = add_input_wme(current_agent(top_state), current_agent(io_symbol), current_agent(io_header)); current_agent(io_header_input) = get_new_io_identifier('I'); current_agent(io_header_output) = get_new_io_identifier('I'); w = add_input_wme(current_agent(io_header), make_sym_constant("input-link"), current_agent(io_header_input)); w = add_input_wme(current_agent(io_header), make_sym_constant("output-link"), current_agent(io_header_output)); /* --- add top state io link before calling input phase callback so * --- code can use "wmem" command. */ do_buffered_wm_and_ownership_changes(); soar_invoke_callbacks(soar_agent, INPUT_PHASE_CALLBACK, (soar_call_data) TOP_STATE_JUST_CREATED); } /* --- if there is a top state, do the normal input cycle --- */ if (current_agent(top_state)) { soar_invoke_callbacks(soar_agent, INPUT_PHASE_CALLBACK, (soar_call_data) NORMAL_INPUT_CYCLE); } /* --- do any WM resulting changes --- */ do_buffered_wm_and_ownership_changes(); /* --- save current top state for next time --- */ current_agent(prev_top_state) = current_agent(top_state); /* --- reset the output-link status flag to FALSE * --- when running til output, only want to stop if agent * --- does add-wme to output. don't stop if add-wme done * --- during input cycle (eg simulator updates sensor status) * KJC 11/23/98 */ current_agent(output_link_changed) = FALSE; }
/* -------------------------------------------------------------------- Building the list of IO_Wme's These routines create and destroy the list of io_wme's in the TC of a given output_link. Get_io_wmes_for_output_link() and deallocate_io_wme_list() are the main entry points. The TC info must have already been calculated for the given output link before get_io_wmes_for_output_link() is called. -------------------------------------------------------------------- */ void add_wme_to_collected_io_wmes(wme * w) { io_wme *new; allocate_with_pool(¤t_agent(io_wme_pool), &new); new->next = current_agent(collected_io_wmes); current_agent(collected_io_wmes) = new; new->id = w->id; new->attr = w->attr; new->value = w->value; } io_wme *get_io_wmes_for_output_link(output_link * ol) { cons *c; Symbol *id; slot *s; wme *w; current_agent(collected_io_wmes) = NIL;
void assert_new_preferences (void) { instantiation *inst, *next_inst; preference *pref, *next_pref; preference *o_rejects; o_rejects = NIL; /* REW: begin 09.15.96 */ if ((current_agent(operand2_mode) == TRUE) && (current_agent(soar_verbose_flag) == TRUE)) printf("\n in assert_new_preferences:"); /* REW: end 09.15.96 */ for (inst=current_agent(newly_created_instantiations); inst!=NIL; inst=next_inst) { next_inst = inst->next; if (inst->in_ms) insert_at_head_of_dll (inst->prod->instantiations, inst, next, prev); /* REW: begin 09.15.96 */ if (current_agent(operand2_mode) == TRUE) { if (current_agent(soar_verbose_flag) == TRUE) print_with_symbols("\n asserting instantiation: %y\n", inst->prod->name); } /* REW: end 09.15.96 */ for (pref=inst->preferences_generated; pref!=NIL; pref=next_pref) { next_pref = pref->inst_next; if ((pref->type==REJECT_PREFERENCE_TYPE)&&(pref->o_supported)) { /* --- o-reject: just put it in the buffer for later --- */ pref->next = o_rejects; o_rejects = pref; /* REW: begin 09.15.96 */ /* No knowledge retrieval necessary in Operand2 */ /* REW: end 09.15.96 */ } else if (inst->in_ms || pref->o_supported) { /* --- normal case --- */ add_preference_to_tm (pref); /* REW: begin 09.15.96 */ /* No knowledge retrieval necessary in Operand2 */ /* REW: end 09.15.96 */ } else { /* --- inst. is refracted chunk, and pref. is not o-supported: remove the preference --- */ /* --- first splice it out of the clones list--otherwise we might accidentally deallocate some clone that happens to have refcount==0 just because it hasn't been asserted yet --- */ if (pref->next_clone) pref->next_clone->prev_clone = pref->prev_clone; if (pref->prev_clone) pref->prev_clone->next_clone = pref->next_clone; pref->next_clone = pref->prev_clone = NIL; /* --- now add then remove ref--this should result in deallocation */ preference_add_ref (pref); preference_remove_ref (pref); } } } if (o_rejects) process_o_rejects_and_deallocate_them (o_rejects); }
void create_instantiation (production *prod, struct token_struct *tok, wme *w) { instantiation *inst; condition *cond; preference *pref; action *a; cons *c; bool need_to_do_support_calculations; bool trace_it; long index; Symbol **cell; allocate_with_pool (¤t_agent(instantiation_pool), &inst); inst->next = current_agent(newly_created_instantiations); current_agent(newly_created_instantiations) = inst; inst->prod = prod; inst->rete_token = tok; inst->rete_wme = w; inst->okay_to_variablize = TRUE; inst->in_ms = TRUE; /* REW: begin 09.15.96 */ /* We want to initialize the GDS_evaluated_already flag * when a new instantiation is created. */ inst->GDS_evaluated_already = FALSE; if (current_agent(operand2_mode) == TRUE) { if (current_agent(soar_verbose_flag) == TRUE) print_with_symbols("\n in create_instantiation: %y", inst->prod->name); } /* REW: end 09.15.96 */ current_agent(production_being_fired) = inst->prod; prod->firing_count++; current_agent(production_firing_count)++; /* --- build the instantiated conditions, and bind LHS variables --- */ p_node_to_conditions_and_nots (prod->p_node, tok, w, &(inst->top_of_instantiated_conditions), &(inst->bottom_of_instantiated_conditions), &(inst->nots), NIL); /* --- record the level of each of the wmes that was positively tested --- */ for (cond=inst->top_of_instantiated_conditions; cond!=NIL; cond=cond->next) { if (cond->type==POSITIVE_CONDITION) { cond->bt.level = cond->bt.wme->id->id.level; cond->bt.trace = cond->bt.wme->preference; } } /* --- print trace info --- */ trace_it = trace_firings_of_inst (inst); if (trace_it) { if (get_printer_output_column()!=1) print ("\n"); /* AGR 617/634 */ print ("Firing "); print_instantiation_with_wmes (inst, (wme_trace_type)(current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM])); } /* --- initialize rhs_variable_bindings array with names of variables (if there are any stored on the production -- for chunks there won't be any) --- */ index = 0; cell = current_agent(rhs_variable_bindings); for (c=prod->rhs_unbound_variables; c!=NIL; c=c->rest) { *(cell++) = c->first; index++; } firer_highest_rhs_unboundvar_index = index-1; /* 7.1/8 merge: Not sure about this. This code in 704, but not in either 7.1 or 703/soar8 */ /* --- Before executing the RHS actions, tell the user that the -- */ /* --- phase has changed to output by printing the arrow --- */ if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { print (" -->\n");} /* --- execute the RHS actions, collect the results --- */ inst->preferences_generated = NIL; need_to_do_support_calculations = FALSE; for (a=prod->action_list; a!=NIL; a=a->next) { pref = execute_action (a, tok, w); if (pref) { pref->inst = inst; insert_at_head_of_dll (inst->preferences_generated, pref, inst_next, inst_prev); if (inst->prod->declared_support==DECLARED_O_SUPPORT) pref->o_supported = TRUE; else if (inst->prod->declared_support==DECLARED_I_SUPPORT) pref->o_supported = FALSE; else { if (current_agent(operand2_mode) == TRUE) { pref->o_supported = (current_agent(FIRING_TYPE) == PE_PRODS) ? TRUE : FALSE; } /* REW: end 09.15.96 */ else { if (a->support==O_SUPPORT) pref->o_supported = TRUE; else if (a->support==I_SUPPORT) pref->o_supported = FALSE; else { need_to_do_support_calculations = TRUE; if (current_agent(soar_verbose_flag) == TRUE) printf("\n\nin create_instantiation(): need_to_do_support_calculations == TRUE!!!\n\n"); } } } } } /* --- reset rhs_variable_bindings array to all zeros --- */ index = 0; cell = current_agent(rhs_variable_bindings); while (index++ <= firer_highest_rhs_unboundvar_index) *(cell++) = NIL; /* --- fill in lots of other stuff --- */ fill_in_new_instantiation_stuff (inst, need_to_do_support_calculations); /* --- print trace info: printing preferences --- */ /* Note: can't move this up, since fill_in_new_instantiation_stuff gives the o-support info for the preferences we're about to print */ if (trace_it && current_agent(sysparams)[TRACE_FIRINGS_PREFERENCES_SYSPARAM]) { for (pref=inst->preferences_generated; pref!=NIL; pref=pref->inst_next) { print (" "); print_preference (pref); } } /* mvp 5-17-94 */ build_prohibits_list (inst); current_agent(production_being_fired) = NIL; /* --- build chunks/justifications if necessary --- */ chunk_instantiation (inst, (bool)current_agent(sysparams)[LEARNING_ON_SYSPARAM]); #ifndef NO_CALLBACKS /* kjc 1/00 */ /* MVP 6-8-94 */ if (!current_agent(system_halted)) { /* --- invoke callback function --- */ soar_invoke_callbacks(soar_agent, FIRING_CALLBACK, (soar_call_data) inst); } #endif }