Soar Kernel  9.3.2 08-06-12
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Macros | Functions | Variables
io.cpp File Reference
#include <portability.h>
#include <stdlib.h>
#include "io_soar.h"
#include "callback.h"
#include "agent.h"
#include "print.h"
#include "init_soar.h"
#include "gdatastructs.h"
#include "wmem.h"
#include "symtab.h"
#include "decide.h"
#include "production.h"
#include "lexer.h"
#include "xml.h"
#include "soar_TraceNames.h"
#include "utilities.h"
#include "wma.h"
#include <ctype.h>
#include <assert.h>

Go to the source code of this file.

Macros

#define LINK_NAME_SIZE   1024
#define MAX_TEXT_INPUT_LINE_LENGTH   1000 /* used to be in soarkernel.h */
#define MODIFIED_BUT_SAME_TC_OL_STATUS
#define MODIFIED_OL_STATUS
#define NEW_OL_STATUS   0 /* just created it */
#define REMOVED_OL_STATUS   4 /* link has just been removed */
#define UNCHANGED_OL_STATUS   1 /* normal status */

Functions

void add_id_to_output_link_tc (agent *thisAgent, Symbol *id)
void add_input_function (agent *thisAgent, soar_callback_fn f, soar_callback_data cb_data, soar_callback_free_fn free_fn, const char *name)
wmeadd_input_wme (agent *thisAgent, Symbol *id, Symbol *attr, Symbol *value)
void add_output_function (agent *thisAgent, soar_callback_fn f, soar_callback_data cb_data, soar_callback_free_fn free_fn, int eventID, const char *output_link_name)
void add_wme_to_collected_io_wmes (agent *thisAgent, wme *w)
void calculate_output_link_tc_info (agent *thisAgent, output_link *ol)
void deallocate_io_wme_list (agent *thisAgent, io_wme *iw)
void do_input_cycle (agent *thisAgent)
void do_output_cycle (agent *thisAgent)
wmefind_input_wme_by_timetag_from_id (agent *thisAgent, Symbol *idSym, uint64_t timetag, tc_number tc)
void gds_invalid_so_remove_goal (agent *thisAgent, wme *w)
Symbolget_io_float_constant (agent *thisAgent, double value)
Symbolget_io_identifier (agent *thisAgent, char first_letter, uint64_t number)
Symbolget_io_int_constant (agent *thisAgent, int64_t value)
Symbolget_io_sym_constant (agent *thisAgent, char const *name)
Symbolget_io_symbol_from_tio_constituent_string (agent *thisAgent, char *input_string)
io_wmeget_io_wmes_for_output_link (agent *thisAgent, output_link *ol)
Symbolget_new_io_identifier (agent *thisAgent, char first_letter)
Symbolget_next_io_symbol_from_text_input_line (agent *thisAgent, char **text_read_position)
Symbolget_output_value (io_wme *outputs, Symbol *id, Symbol *attr)
void inform_output_module_of_wm_changes (agent *thisAgent, list *wmes_being_added, list *wmes_being_removed)
void init_soar_io (agent *thisAgent)
uint64_t release_io_symbol (agent *thisAgent, Symbol *sym)
void remove_input_function (agent *thisAgent, const char *name)
Bool remove_input_wme (agent *thisAgent, wme *w)
void remove_output_function (agent *thisAgent, const char *name)
void remove_output_link_tc_info (agent *thisAgent, output_link *ol)
void update_for_io_wme_change (wme *w)
void update_for_top_state_wme_addition (agent *thisAgent, wme *w)
void update_for_top_state_wme_removal (wme *w)

Variables

char extra_tio_constituents [] = "+-._"
Bool tio_constituent_char [256]
Bool tio_whitespace [256]

Macro Definition Documentation

#define LINK_NAME_SIZE   1024

Definition at line 411 of file io.cpp.

Referenced by update_for_top_state_wme_addition().

#define MAX_TEXT_INPUT_LINE_LENGTH   1000 /* used to be in soarkernel.h */

Definition at line 867 of file io.cpp.

Referenced by get_next_io_symbol_from_text_input_line().

#define MODIFIED_BUT_SAME_TC_OL_STATUS
Value:
2 /* some value in its TC has been
modified, but the ids in its TC
are the same */

Definition at line 381 of file io.cpp.

Referenced by do_output_cycle().

#define MODIFIED_OL_STATUS
Value:
3 /* the set of ids in its TC has
changed */

Definition at line 382 of file io.cpp.

Referenced by do_output_cycle().

#define NEW_OL_STATUS   0 /* just created it */

Definition at line 379 of file io.cpp.

Referenced by do_output_cycle(), and update_for_top_state_wme_addition().

#define REMOVED_OL_STATUS   4 /* link has just been removed */

Definition at line 383 of file io.cpp.

Referenced by do_output_cycle().

#define UNCHANGED_OL_STATUS   1 /* normal status */

Definition at line 380 of file io.cpp.

Referenced by do_output_cycle().

Function Documentation

void add_id_to_output_link_tc ( agent thisAgent,
Symbol id 
)

Definition at line 564 of file io.cpp.

{
slot *s;
wme *w;
/* --- if id is already in the TC, exit --- */
if (id->id.tc_num == thisAgent->output_link_tc_num) return;
id->id.tc_num = thisAgent->output_link_tc_num;
/* --- add id to output_link's list --- */
push (thisAgent, id, thisAgent->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 (thisAgent, thisAgent->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)
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)
void add_input_function ( agent thisAgent,
soar_callback_fn  f,
soar_callback_data  cb_data,
soar_callback_free_fn  free_fn,
const char *  name 
)

Definition at line 81 of file io.cpp.

References INPUT_PHASE_CALLBACK, and soar_add_callback().

{
soar_add_callback(thisAgent, INPUT_PHASE_CALLBACK, f, INPUT_PHASE_CALLBACK, cb_data, free_fn, name);
}
wme* add_input_wme ( agent thisAgent,
Symbol id,
Symbol attr,
Symbol value 
)

Definition at line 199 of file io.cpp.

References add_wme_to_wm(), FALSE, symbol_union::id, identifier_struct::input_wmes, insert_at_head_of_dll, make_wme(), pi_struct::next, NIL, pi_struct::prev, print(), wma_activate_wme(), and wma_enabled().

Referenced by init_agent_memory().

{
wme *w;
/* --- a little bit of error checking --- */
if (! (id && attr && value)) {
print (thisAgent, "Error: an input routine gave a NULL argument to add_input_wme.\n");
return NIL;
}
/* --- go ahead and add the wme --- */
w = make_wme (thisAgent, id, attr, value, FALSE);
insert_at_head_of_dll (id->id.input_wmes, w, next, prev);
if ( wma_enabled( thisAgent ) )
{
wma_activate_wme( thisAgent, w );
}
add_wme_to_wm (thisAgent, w);
//PrintDebugFormat("Added wme with timetag %d to id %c%d ",w->timetag,id->id.name_letter,id->id.name_number) ;
return w;
}
void add_output_function ( agent thisAgent,
soar_callback_fn  f,
soar_callback_data  cb_data,
soar_callback_free_fn  free_fn,
int  eventID,
const char *  output_link_name 
)

Definition at line 91 of file io.cpp.

References OUTPUT_PHASE_CALLBACK, print(), soar_add_callback(), and soar_exists_callback_id().

{
if (soar_exists_callback_id (thisAgent, OUTPUT_PHASE_CALLBACK, output_link_name)
!= NULL)
{
print (thisAgent, "Error: tried to add_output_function with duplicate name %s\n",
output_link_name);
/* Replaced deprecated control_c_handler with an appropriate assertion */
//control_c_handler(0);
assert(0 && "error in io.cpp (control_c_handler() used to be called here)");
}
else
{
soar_add_callback(thisAgent, OUTPUT_PHASE_CALLBACK, f, eventID, cb_data, free_fn,
output_link_name);
}
}
void add_wme_to_collected_io_wmes ( agent thisAgent,
wme w 
)

Definition at line 614 of file io.cpp.

References wme_struct::attr, io_wme_struct::attr, agent_struct::collected_io_wmes, wme_struct::id, io_wme_struct::id, agent_struct::io_wme_pool, io_wme_struct::next, wme_struct::value, and io_wme_struct::value.

{
io_wme *New;
allocate_with_pool (thisAgent, &thisAgent->io_wme_pool, &New);
New->next = thisAgent->collected_io_wmes;
thisAgent->collected_io_wmes = New;
New->id = w->id;
New->attr = w->attr;
void calculate_output_link_tc_info ( agent thisAgent,
output_link ol 
)

Definition at line 594 of file io.cpp.

Referenced by do_output_cycle().

{
/* --- 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 --- */
thisAgent->output_link_for_tc = ol;
void deallocate_io_wme_list ( agent thisAgent,
io_wme iw 
)

Definition at line 645 of file io.cpp.

Referenced by do_output_cycle().

{
io_wme *next;
while (iw) {
next = iw->next;
free_with_pool (&thisAgent->io_wme_pool, iw);
void do_input_cycle ( agent thisAgent)

Definition at line 287 of file io.cpp.

References do_buffered_wm_and_ownership_changes(), FALSE, INPUT_PHASE_CALLBACK, agent_struct::io_header, agent_struct::io_header_input, agent_struct::io_header_link, agent_struct::io_header_output, NIL, NORMAL_INPUT_CYCLE, agent_struct::output_link_changed, agent_struct::prev_top_state, release_io_symbol(), soar_invoke_callbacks(), agent_struct::top_state, and TOP_STATE_JUST_REMOVED.

Referenced by clear_goal_stack(), do_one_top_level_phase(), and init_agent_memory().

{
if (thisAgent->prev_top_state && (!thisAgent->top_state)) {
/* --- top state was just removed --- */
reinterpret_cast<soar_call_data>(TOP_STATE_JUST_REMOVED) );
release_io_symbol (thisAgent, thisAgent->io_header);
release_io_symbol (thisAgent, thisAgent->io_header_input);
release_io_symbol (thisAgent, thisAgent->io_header_output);
thisAgent->io_header = NIL; /* RBD added 3/25/95 */
thisAgent->io_header_input = NIL; /* RBD added 3/25/95 */
thisAgent->io_header_output = NIL; /* KJC added 3/3/99 */
thisAgent->io_header_link = NIL; /* KJC added 3/3/99 */
} else if ((!thisAgent->prev_top_state) && thisAgent->top_state) {
/* --- top state was just created --- */
/* Create io structure on top state. */
/*
thisAgent->io_header = get_new_io_identifier (thisAgent, 'I');
thisAgent->io_header_link = add_input_wme (thisAgent,
thisAgent->top_state,
thisAgent->io_symbol,
thisAgent->io_header);
thisAgent->io_header_input = get_new_io_identifier (thisAgent, 'I');
thisAgent->io_header_output = get_new_io_identifier (thisAgent, 'I');
add_input_wme (thisAgent, thisAgent->io_header,
make_sym_constant(thisAgent, "input-link"),
thisAgent->io_header_input);
add_input_wme (thisAgent, thisAgent->io_header,
make_sym_constant(thisAgent, "output-link"),
thisAgent->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(thisAgent);
soar_invoke_callbacks(thisAgent, thisAgent, INPUT_PHASE_CALLBACK,
(soar_call_data) TOP_STATE_JUST_CREATED);
*/
}
/* --- if there is a top state, do the normal input cycle --- */
if (thisAgent->top_state) {
reinterpret_cast<soar_call_data>(NORMAL_INPUT_CYCLE) );
}
/* --- do any WM resulting changes --- */
/* --- save current top state for next time --- */
thisAgent->prev_top_state = thisAgent->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
*/
thisAgent->output_link_changed = FALSE;
}
void do_output_cycle ( agent thisAgent)

Definition at line 665 of file io.cpp.

References ADDED_OUTPUT_COMMAND, calculate_output_link_tc_info(), output_link_struct::cb, agent_struct::current_phase, callback_struct::data, deallocate_io_wme_list(), callback_struct::eventid, agent_struct::existing_output_links, callback_struct::function, get_io_wmes_for_output_link(), output_link_struct::link_wme, output_call_info_struct::mode, MODIFIED_BUT_SAME_TC_OL_STATUS, MODIFIED_OL_STATUS, MODIFIED_OUTPUT_COMMAND, NEW_OL_STATUS, pi_struct::next, output_link_struct::next, NIL, agent_struct::output_link_pool, output_call_info_struct::outputs, pi_struct::prev, remove_from_dll, remove_output_link_tc_info(), REMOVED_OL_STATUS, REMOVED_OUTPUT_COMMAND, output_link_struct::status, agent_struct::timers_decision_cycle_phase, agent_struct::timers_kernel, agent_struct::timers_output_function_cpu_time, agent_struct::timers_phase, agent_struct::timers_total_kernel_time, UNCHANGED_OL_STATUS, and wme_remove_ref().

Referenced by clear_goal_stack(), do_one_top_level_phase(), and init_agent_memory().

{
output_link *ol, *next_ol;
io_wme *iw_list;
output_call_info output_call_data;
for (ol=thisAgent->existing_output_links; ol!=NIL; ol=next_ol) {
next_ol = ol->next;
switch (ol->status) {
/* --- output link is unchanged, so do nothing --- */
break;
/* --- calculate tc, and call the output function --- */
iw_list = get_io_wmes_for_output_link (thisAgent, ol);
output_call_data.mode = ADDED_OUTPUT_COMMAND;
output_call_data.outputs = iw_list;
#ifndef NO_TIMING_STUFF /* moved here from do_one_top_level_phase June 05. KJC */
thisAgent->timers_phase.stop();
thisAgent->timers_kernel.stop();
thisAgent->timers_total_kernel_time.update(thisAgent->timers_kernel);
thisAgent->timers_decision_cycle_phase[thisAgent->current_phase].update(thisAgent->timers_phase);
thisAgent->timers_kernel.start();
#endif
if (ol->cb) (ol->cb->function)(thisAgent, ol->cb->eventid, ol->cb->data, &output_call_data);
#ifndef NO_TIMING_STUFF
thisAgent->timers_kernel.stop();
thisAgent->timers_output_function_cpu_time.update(thisAgent->timers_kernel);
thisAgent->timers_kernel.start();
thisAgent->timers_phase.start();
#endif
deallocate_io_wme_list (thisAgent, iw_list);
break;
/* --- don't have to redo the TC, but do call the output function --- */
iw_list = get_io_wmes_for_output_link (thisAgent, ol);
output_call_data.mode = MODIFIED_OUTPUT_COMMAND;
output_call_data.outputs = iw_list;
#ifndef NO_TIMING_STUFF /* moved here from do_one_top_level_phase June 05. KJC */
thisAgent->timers_phase.stop();
thisAgent->timers_kernel.stop();
thisAgent->timers_total_kernel_time.update(thisAgent->timers_kernel);
thisAgent->timers_decision_cycle_phase[thisAgent->current_phase].update(thisAgent->timers_phase);
thisAgent->timers_kernel.start();
#endif
if (ol->cb) (ol->cb->function)(thisAgent, ol->cb->eventid, ol->cb->data, &output_call_data);
#ifndef NO_TIMING_STUFF
thisAgent->timers_kernel.stop();
thisAgent->timers_output_function_cpu_time.update(thisAgent->timers_kernel);
thisAgent->timers_kernel.start();
thisAgent->timers_phase.start();
#endif
deallocate_io_wme_list (thisAgent, iw_list);
break;
/* --- redo the TC, and call the output function */
remove_output_link_tc_info (thisAgent, ol);
iw_list = get_io_wmes_for_output_link (thisAgent, ol);
output_call_data.mode = MODIFIED_OUTPUT_COMMAND;
output_call_data.outputs = iw_list;
#ifndef NO_TIMING_STUFF /* moved here from do_one_top_level_phase June 05. KJC */
thisAgent->timers_phase.stop();
thisAgent->timers_kernel.stop();
thisAgent->timers_total_kernel_time.update(thisAgent->timers_kernel);
thisAgent->timers_decision_cycle_phase[thisAgent->current_phase].update(thisAgent->timers_phase);
thisAgent->timers_kernel.start();
#endif
if (ol->cb) (ol->cb->function)(thisAgent, ol->cb->eventid, ol->cb->data, &output_call_data);
#ifndef NO_TIMING_STUFF
thisAgent->timers_kernel.stop();
thisAgent->timers_output_function_cpu_time.update(thisAgent->timers_kernel);
thisAgent->timers_kernel.start();
thisAgent->timers_phase.start();
#endif
deallocate_io_wme_list (thisAgent, iw_list);
break;
/* --- call the output function, and free output_link structure --- */
remove_output_link_tc_info (thisAgent, ol); /* sets ids_in_tc to NIL */
iw_list = get_io_wmes_for_output_link (thisAgent, ol); /* gives just the link wme */
output_call_data.mode = REMOVED_OUTPUT_COMMAND;
output_call_data.outputs = iw_list;
#ifndef NO_TIMING_STUFF /* moved here from do_one_top_level_phase June 05. KJC */
thisAgent->timers_phase.stop();
thisAgent->timers_kernel.stop();
thisAgent->timers_total_kernel_time.update(thisAgent->timers_kernel);
thisAgent->timers_decision_cycle_phase[thisAgent->current_phase].update(thisAgent->timers_phase);
thisAgent->timers_kernel.start();
#endif
if (ol->cb) (ol->cb->function)(thisAgent, ol->cb->eventid, ol->cb->data, &output_call_data);
#ifndef NO_TIMING_STUFF
thisAgent->timers_kernel.stop();
thisAgent->timers_output_function_cpu_time.update(thisAgent->timers_kernel);
thisAgent->timers_kernel.start();
thisAgent->timers_phase.start();
#endif
deallocate_io_wme_list (thisAgent, iw_list);
wme_remove_ref (thisAgent, ol->link_wme);
remove_from_dll (thisAgent->existing_output_links, ol, next, prev);
free_with_pool (&thisAgent->output_link_pool, ol);
break;
}
wme* find_input_wme_by_timetag_from_id ( agent thisAgent,
Symbol idSym,
uint64_t  timetag,
tc_number  tc 
)

Definition at line 224 of file io.cpp.

References symbol_union::id, IDENTIFIER_SYMBOL_TYPE, identifier_struct::input_wmes, wme_struct::next, NIL, identifier_struct::tc_num, wme_struct::timetag, and wme_struct::value.

{
wme *pWME,*w;
//PrintDebugFormat("Scanning id %c%d", idSym->id.name_letter, idSym->id.name_number) ;
// Mark this id as having been visited (the key here is that tc numbers always increase so tc_num must be < tc until it's marked)
idSym->id.tc_num = tc ;
// This is inefficient. Using a hash table could save a lot here.
for (pWME = idSym->id.input_wmes; pWME != NIL; pWME = pWME->next)
{
//PrintDebugFormat("Timetag %ld", pWME->timetag) ;
if (pWME->timetag == timetag)
return pWME ;
// NOTE: The test for the tc_num keeps us from getting stuck in loops within graphs
if (pWME->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE && pWME->value->id.tc_num != tc)
{
w = find_input_wme_by_timetag_from_id(thisAgent, pWME->value, timetag, tc) ;
if (w)
return w ;
}
}
return NIL ;
}
void gds_invalid_so_remove_goal ( agent thisAgent,
wme w 
)

Definition at line 3386 of file decide.cpp.

References agent_struct::current_phase, wme_struct::gds, gds_struct::goal, identifier_struct::higher_goal, agent_struct::highest_goal_whose_context_changed, symbol_union::id, identifier_struct::level, slot_struct::next, print_string(), print_with_symbols(), print_wme(), remove_existing_context_and_descendents(), identifier_struct::slots, snprintf_with_symbols(), agent_struct::soar_verbose_flag, agent_struct::sysparams, TRACE_GDS_SYSPARAM, TRACE_OPERAND2_REMOVALS_SYSPARAM, xml_att_val(), xml_begin_tag(), and xml_end_tag().

Referenced by decide_non_context_slot(), remove_input_wme(), and soar_module::remove_module_wme().

{
if (thisAgent->soar_verbose_flag || thisAgent->sysparams[TRACE_GDS_SYSPARAM]) {
// BADBAD: the XML code makes this all very ugly
char msgbuf[256];
memset(msgbuf, 0, 256);
snprintf_with_symbols(thisAgent, msgbuf, 255, "Removing state %y because element in GDS changed. WME: ", w->gds->goal);
print_string(thisAgent, msgbuf);
xml_begin_tag(thisAgent, soar_TraceNames::kTagVerbose);
xml_att_val(thisAgent, soar_TraceNames::kTypeString, msgbuf);
print_wme(thisAgent, w); // prints XML, too
xml_end_tag(thisAgent, soar_TraceNames::kTagVerbose);
}
/* REW: begin 11.25.96 */
#ifndef NO_TIMING_STUFF
#ifdef DETAILED_TIMING_STATS
thisAgent->timers_gds.start();
#endif
#endif
/* REW: end 11.25.96 */
/* This call to GDS_PrintCmd will have to be uncommented later. -ajc */
//if (thisAgent->soar_verbose_flag) {} //GDS_PrintCmd();
/* REW: BUG. I have no idea right now if this is a terrible hack or
* actually what we want to do. The idea here is that the context of
* the immediately higher goal above a retraction should be marked as
* having its context changed in order that the architecture doesn't
* look below this level for context changes. I think it's a hack b/c
* it seems like there should aready be mechanisms for doing this in
* the architecture but I couldn't find any.
*/
/* Note: the inner 'if' is correct -- we only want to change
* highest_goal_whose_context_changed if the pointer is currently at
* or below (greater than) the goal which we are going to retract.
* However, I'm not so sure about the outer 'else.' If we don't set
* this to the goal above the retraction, even if the current value
* is NIL, we still seg fault in certain cases. But setting it as we do
* in the inner 'if' seems to clear up the difficulty.
*/
{
{
}
}
else
{
/* If nothing has yet changed (highest_ ... = NIL) then set
* the goal automatically */
// Tell those slots they are changed so that the impasses can be regenerated
// bug 1011
for ( slot* s = thisAgent->highest_goal_whose_context_changed->id.slots; s != 0; s = s->next )
{
if (s->isa_context_slot && !s->changed)
s->changed = reinterpret_cast<dl_cons*>(1); // use non-zero value to indicate change, see definition of slot::changed
}
}
{
print_with_symbols(thisAgent, "\n REMOVING GOAL [%y] due to change in GDS WME ", w->gds->goal);
print_wme(thisAgent, w);
}
/* BUG: Need to reset highest_goal here ???*/
/* usually, we'd call do_buffered_wm_and_ownership_changes() here, but
* we don't need to because it will be done at the end of the working
* memory phase; cf. the end of do_working_memory_phase().
*/
/* REW: begin 11.25.96 */
#ifndef NO_TIMING_STUFF
#ifdef DETAILED_TIMING_STATS
thisAgent->timers_gds.stop();
thisAgent->timers_gds_cpu_time[thisAgent->current_phase].update(thisAgent->timers_gds);
#endif
#endif
/* REW: end 11.25.96 */
}
Symbol* get_io_float_constant ( agent thisAgent,
double  value 
)

Definition at line 191 of file io.cpp.

References make_float_constant().

Referenced by get_io_symbol_from_tio_constituent_string().

{
return make_float_constant (thisAgent, value);
}
Symbol* get_io_identifier ( agent thisAgent,
char  first_letter,
uint64_t  number 
)

Definition at line 166 of file io.cpp.

References find_identifier(), make_new_identifier(), symbol_add_ref(), and TOP_GOAL_LEVEL.

{
Symbol* id = find_identifier(thisAgent, first_letter, number) ;
// DJP: The other "make_<type>" methods either make a new object or incremenent the refence
// on an existing object. So I'm going to make this method function the same way for identifiers.
if (id)
{
}
else
{
id = make_new_identifier (thisAgent, first_letter, TOP_GOAL_LEVEL);
}
return id ;
}
Symbol* get_io_int_constant ( agent thisAgent,
int64_t  value 
)

Definition at line 187 of file io.cpp.

References make_int_constant().

Referenced by get_io_symbol_from_tio_constituent_string().

{
return make_int_constant (thisAgent, value);
}
Symbol* get_io_sym_constant ( agent thisAgent,
char const *  name 
)

Definition at line 183 of file io.cpp.

References make_sym_constant().

Referenced by get_next_io_symbol_from_text_input_line().

{
return make_sym_constant (thisAgent, name);
}
Symbol* get_io_symbol_from_tio_constituent_string ( agent thisAgent,
char *  input_string 
)

Definition at line 826 of file io.cpp.

References determine_possible_symbol_types_for_string(), get_io_float_constant(), get_io_int_constant(), NIL, and print().

Referenced by get_next_io_symbol_from_text_input_line().

{
int int_val;
double float_val;
Bool possible_id, possible_var, possible_sc, possible_ic, possible_fc;
Bool rereadable;
strlen(input_string),
&possible_id,
&possible_var,
&possible_sc,
&possible_ic,
&possible_fc,
&rereadable);
/* --- check whether it's an integer --- */
if (possible_ic) {
errno = 0;
int_val = strtol (input_string,NULL,10);
if (errno) {
print (thisAgent, "Text Input Error: bad integer (probably too large)\n");
return NIL;
}
return get_io_int_constant (thisAgent, int_val);
}
/* --- check whether it's a floating point number --- */
if (possible_fc) {
errno = 0;
float_val = strtod (input_string,NULL);
if (errno) {
print (thisAgent, "Text Input Error: bad floating point number\n");
return NIL;
}
return get_io_float_constant (thisAgent, float_val);
}
io_wme* get_io_wmes_for_output_link ( agent thisAgent,
output_link ol 
)

Definition at line 626 of file io.cpp.

Referenced by do_output_cycle().

{
cons *c;
Symbol *id;
slot *s;
wme *w;
thisAgent->collected_io_wmes = NIL;
for (c=ol->ids_in_tc; c!=NIL; c=c->rest) {
id = static_cast<symbol_union *>(c->first);
for (w=id->id.input_wmes; w!=NIL; w=w->next)
for (s=id->id.slots; s!=NIL; s=s->next)
for (w=s->wmes; w!=NIL; w=w->next)
Symbol* get_new_io_identifier ( agent thisAgent,
char  first_letter 
)

Definition at line 161 of file io.cpp.

References make_new_identifier(), and TOP_GOAL_LEVEL.

Referenced by init_agent_memory().

{
return make_new_identifier (thisAgent, first_letter, TOP_GOAL_LEVEL);
}
Symbol* get_next_io_symbol_from_text_input_line ( agent thisAgent,
char **  text_read_position 
)

Definition at line 869 of file io.cpp.

References get_io_sym_constant(), get_io_symbol_from_tio_constituent_string(), MAX_TEXT_INPUT_LINE_LENGTH, NIL, tio_constituent_char, and tio_whitespace.

Referenced by accept_rhs_function_code().

{
char *ch;
char input_string[MAX_TEXT_INPUT_LINE_LENGTH+2];
int input_lexeme_length;
ch = *text_read_position;
/* --- scan past any whitespace --- */
while (tio_whitespace[static_cast<unsigned char>(*ch)]) ch++;
/* --- if end of line, return NIL --- */
if ((*ch=='\n')||(*ch==0)) { *text_read_position = ch; return NIL; }
/* --- if not a constituent character, return single-letter symbol --- */
if (! tio_constituent_char[static_cast<unsigned char>(*ch)]) {
input_string[0] = *ch++;
input_string[1] = 0;
*text_read_position = ch;
return get_io_sym_constant (thisAgent, input_string);
}
/* --- read string of constituents --- */
input_lexeme_length = 0;
while (tio_constituent_char[static_cast<unsigned char>(*ch)])
input_string[input_lexeme_length++] = *ch++;
/* --- return the appropriate kind of symbol --- */
input_string[input_lexeme_length] = 0;
Symbol* get_output_value ( io_wme outputs,
Symbol id,
Symbol attr 
)

Definition at line 793 of file io.cpp.

References io_wme_struct::attr, io_wme_struct::id, io_wme_struct::next, NIL, and io_wme_struct::value.

{
io_wme *iw;
for (iw=outputs; iw!=NIL; iw=iw->next)
if ( ((id==NIL)||(id==iw->id)) &&
void inform_output_module_of_wm_changes ( agent thisAgent,
list wmes_being_added,
list wmes_being_removed 
)

Definition at line 485 of file io.cpp.

Referenced by do_buffered_wm_changes().

{
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 = static_cast<wme_struct *>(c->first);
if (w->id==thisAgent->io_header) {
thisAgent->output_link_changed = TRUE; /* KJC 11/23/98 */
thisAgent->d_cycle_last_output = thisAgent->d_cycle_count; /* KJC 11/17/05 */
}
thisAgent->output_link_changed = TRUE; /* KJC 11/23/98 */
thisAgent->d_cycle_last_output = thisAgent->d_cycle_count; /* KJC 11/17/05 */
}
#if DEBUG_RTO
else {
char id[100];
symbol_to_string(thisAgent, w->id, FALSE, id, 100 );
if ( !strcmp( id, "I3" ) ) {
print(thisAgent, "--> Added to I3, but doesn't register as an OL change!" );
}
}
#endif
}
for (c=wmes_being_removed; c!=NIL; c=c->rest) {
w = static_cast<wme_struct *>(c->first);
void init_soar_io ( agent thisAgent)

Definition at line 910 of file io.cpp.

References extra_tio_constituents, FALSE, init_memory_pool(), agent_struct::io_wme_pool, agent_struct::output_link_pool, tio_constituent_char, tio_whitespace, and TRUE.

Referenced by init_soar_agent().

{
unsigned int i;
init_memory_pool (thisAgent, &thisAgent->output_link_pool, sizeof(output_link), "output link");
init_memory_pool (thisAgent, &thisAgent->io_wme_pool, sizeof(io_wme), "io wme");
/* --- setup constituent_char array --- */
for (i=0; i<256; i++) tio_constituent_char[i] = (isalnum(i) != 0);
for (i=0; i<strlen(extra_tio_constituents); i++)
/* --- setup whitespace array --- */
uint64_t release_io_symbol ( agent thisAgent,
Symbol sym 
)

Definition at line 195 of file io.cpp.

References symbol_remove_ref().

Referenced by accept_rhs_function_code(), and do_input_cycle().

{
return symbol_remove_ref (thisAgent, sym);
}
void remove_input_function ( agent thisAgent,
const char *  name 
)

Definition at line 87 of file io.cpp.

References INPUT_PHASE_CALLBACK, and soar_remove_callback().

Bool remove_input_wme ( agent thisAgent,
wme w 
)

Definition at line 251 of file io.cpp.

References FALSE, wme_struct::gds, gds_invalid_so_remove_goal(), gds_struct::goal, wme_struct::id, symbol_union::id, identifier_struct::input_wmes, pi_struct::next, wme_struct::next, NIL, pi_struct::prev, print(), remove_from_dll, remove_wme_from_wm(), and TRUE.

{
wme *temp;
/* --- a little bit of error checking --- */
if (!w) {
print (thisAgent, "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 (thisAgent, "Error: an input routine called remove_input_wme on a wme that\n");
print (thisAgent, "isn't one of the input wmes currently in working memory.\n");
return FALSE;
}
/* 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 */
if (w->gds) {
if (w->gds->goal != NIL) {
/* NOTE: the call to remove_wme_from_wm will take care
of checking if GDS should be removed */
}
}
/* REW: end 09.15.96 */
remove_wme_from_wm (thisAgent, w);
return TRUE;
}
void remove_output_function ( agent thisAgent,
const char *  name 
)

Definition at line 114 of file io.cpp.

References output_link_struct::cb, agent_struct::existing_output_links, output_link_struct::link_wme, pi_struct::next, output_link_struct::next, NIL, wme_struct::output_link, agent_struct::output_link_pool, OUTPUT_PHASE_CALLBACK, pi_struct::prev, remove_from_dll, soar_exists_callback_id(), soar_remove_callback(), and wme_remove_ref().

{
/* Remove indexing structures ... */
if (!cb) return;
for (ol=thisAgent->existing_output_links; ol!=NIL; ol=ol->next)
{
if (ol->cb == cb)
{
/* Remove ol entry */
ol->link_wme->output_link = NULL;
wme_remove_ref(thisAgent, ol->link_wme);
remove_from_dll(thisAgent->existing_output_links, ol, next, prev);
free_with_pool(&(thisAgent->output_link_pool), ol);
break;
}
}
}
void remove_output_link_tc_info ( agent thisAgent,
output_link ol 
)

Definition at line 536 of file io.cpp.

References abort_with_fatal_error(), identifier_struct::associated_output_links, BUFFER_MSG_SIZE, cons_struct::first, free_cons(), symbol_union::id, output_link_struct::ids_in_tc, NIL, cons_struct::rest, and symbol_remove_ref().

Referenced by do_output_cycle().

{
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 = static_cast<symbol_union *>(c->first);
free_cons (thisAgent, 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[BUFFER_MSG_SIZE];
strncpy(msg,"io.c: Internal error: can't find output link in id's list\n", BUFFER_MSG_SIZE);
msg[BUFFER_MSG_SIZE - 1] = 0; /* ensure null termination */
abort_with_fatal_error(thisAgent, msg);
}
if (prev_c) prev_c->rest = c->rest;
else id->id.associated_output_links = c->rest;
free_cons (thisAgent, c);
void update_for_io_wme_change ( wme w)

Definition at line 466 of file io.cpp.

{
cons *c;
for (c=w->id->id.associated_output_links; c!=NIL; c=c->rest) {
ol = static_cast<output_link_struct *>(c->first);
if (w->value->common.symbol_type==IDENTIFIER_SYMBOL_TYPE) {
/* --- mark ol "modified" --- */
} else {
/* --- mark ol "modified but same tc" --- */
void update_for_top_state_wme_addition ( agent thisAgent,
wme w 
)
  • — add output_link to id's list — */

Definition at line 412 of file io.cpp.

References wme_struct::attr, output_link_struct::cb, agent_struct::existing_output_links, FALSE, output_link_struct::ids_in_tc, insert_at_head_of_dll, LINK_NAME_SIZE, output_link_struct::link_wme, NEW_OL_STATUS, pi_struct::next, NIL, wme_struct::output_link, agent_struct::output_link_pool, OUTPUT_PHASE_CALLBACK, pi_struct::prev, soar_exists_callback_id(), output_link_struct::status, symbol_to_string(), and wme_add_ref().

{
char link_name[LINK_NAME_SIZE];
/* --- check whether the attribute is an output function --- */
symbol_to_string(thisAgent, w->attr, FALSE, link_name, LINK_NAME_SIZE);
cb = soar_exists_callback_id(thisAgent, OUTPUT_PHASE_CALLBACK, link_name);
if (!cb) return;
/* --- create new output link structure --- */
allocate_with_pool (thisAgent, &thisAgent->output_link_pool, &ol);
insert_at_head_of_dll (thisAgent->existing_output_links, ol, next, prev);
ol->link_wme = 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. */
/* KJC & RPM 10/06 commenting out SW's change.
See near end of init_agent_memory for details */
//thisAgent->output_link_tc_num = get_new_tc_number(thisAgent);
//ol->link_wme->value->id.tc_num = thisAgent->output_link_tc_num;
//thisAgent->output_link_for_tc = ol;
void update_for_top_state_wme_removal ( wme w)

Definition at line 461 of file io.cpp.

{

Variable Documentation

char extra_tio_constituents[] = "+-._"

Definition at line 908 of file io.cpp.

Referenced by init_soar_io().

Bool tio_constituent_char[256]

Definition at line 823 of file io.cpp.

Referenced by get_next_io_symbol_from_text_input_line(), and init_soar_io().

Bool tio_whitespace[256]

Definition at line 824 of file io.cpp.

Referenced by get_next_io_symbol_from_text_input_line(), and init_soar_io().