Soar Kernel  9.3.2 08-06-12
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Functions
semantic_memory.cpp File Reference
#include <portability.h>
#include "semantic_memory.h"
#include "agent.h"
#include "prefmem.h"
#include "symtab.h"
#include "wmem.h"
#include "print.h"
#include "xml.h"
#include "lexer.h"
#include "instantiations.h"
#include "rhsfun.h"
#include "decide.h"
#include <list>
#include <map>
#include <queue>
#include <utility>
#include <ctype.h>
#include <fstream>

Go to the source code of this file.

Functions

void _smem_close_vars (agent *my_agent)
void _smem_lti_from_rhs_value (rhs_value rv, std::set< Symbol * > *valid_ltis)
void _smem_lti_from_test (test t, std::set< Symbol * > *valid_ltis)
std::set< smem_lti_id_smem_print_lti (agent *my_agent, smem_lti_id lti_id, char lti_letter, uint64_t lti_number, double lti_act, std::string *return_val)
void _smem_process_buffered_wme_list (agent *my_agent, Symbol *state, soar_module::wme_set &cue_wmes, soar_module::symbol_triple_list &my_list, bool meta)
bool _smem_process_cue_wme (agent *my_agent, wme *w, bool pos_cue, smem_prioritized_weighted_cue &weighted_pq)
void smem_attach (agent *my_agent)
bool smem_backup_db (agent *my_agent, const char *file_name, std::string *err)
void smem_buffer_add_wme (soar_module::symbol_triple_list &my_list, Symbol *id, Symbol *attr, Symbol *value)
void smem_clear_result (agent *my_agent, Symbol *state)
void smem_close (agent *my_agent)
Bool smem_count_ltis (agent *, void *item, void *userdata)
void smem_deallocate_chunk (agent *my_agent, smem_chunk *chunk, bool free_chunk=true)
void smem_disconnect_chunk (agent *my_agent, smem_lti_id parent_id)
bool smem_enabled (agent *my_agent)
smem_wme_listsmem_get_direct_augs_of_id (Symbol *id, tc_number tc=(0))
void smem_go (agent *my_agent, bool store_only)
void smem_init_db (agent *my_agent)
void smem_install_memory (agent *my_agent, Symbol *state, smem_lti_id parent_id, Symbol *lti, bool activate_lti, soar_module::symbol_triple_list &meta_wmes, soar_module::symbol_triple_list &retrieval_wmes)
double smem_lti_activate (agent *my_agent, smem_lti_id lti, bool add_access, uint64_t num_edges=static_cast< uint64_t >(static_cast< uint64_t >(0-1)/static_cast< uint64_t >(2)))
smem_lti_id smem_lti_add_id (agent *my_agent, char name_letter, uint64_t name_number)
double smem_lti_calc_base (agent *my_agent, smem_lti_id lti, int64_t time_now, uint64_t n=0, uint64_t access_1=0)
smem_lti_id smem_lti_get_id (agent *my_agent, char name_letter, uint64_t name_number)
smem_lti_id smem_lti_soar_add (agent *my_agent, Symbol *id)
Symbolsmem_lti_soar_make (agent *my_agent, smem_lti_id lti, char name_letter, uint64_t name_number, goal_stack_level level)
smem_slotsmem_make_slot (smem_slot_map *slots, Symbol *attr)
bool smem_parse_chunk (agent *my_agent, smem_str_to_chunk_map *chunks, smem_chunk_set *newbies)
bool smem_parse_chunks (agent *my_agent, const char *chunks_str, std::string **err_msg)
Symbolsmem_parse_constant_attr (agent *my_agent, struct lexeme_info *lexeme)
std::string * smem_parse_lti_name (struct lexeme_info *lexeme, char *id_letter, uint64_t *id_number)
void smem_print_lti (agent *my_agent, smem_lti_id lti_id, unsigned int depth, std::string *return_val)
void smem_print_store (agent *my_agent, std::string *return_val)
void smem_process_buffered_wmes (agent *my_agent, Symbol *state, soar_module::wme_set &cue_wmes, soar_module::symbol_triple_list &meta_wmes, soar_module::symbol_triple_list &retrieval_wmes)
smem_lti_id smem_process_query (agent *my_agent, Symbol *state, Symbol *query, Symbol *negquery, smem_lti_set *prohibit, soar_module::wme_set &cue_wmes, soar_module::symbol_triple_list &meta_wmes, soar_module::symbol_triple_list &retrieval_wmes, smem_query_levels query_level=qry_full)
void smem_reset (agent *my_agent, Symbol *state)
void smem_reset_id_counters (agent *my_agent)
void smem_respond_to_cmd (agent *my_agent, bool store_only)
Symbolsmem_reverse_hash (agent *my_agent, byte sym_type, smem_hash_id hash_value)
double smem_reverse_hash_float (agent *my_agent, smem_hash_id hash_value)
int64_t smem_reverse_hash_int (agent *my_agent, smem_hash_id hash_value)
void smem_reverse_hash_str (agent *my_agent, smem_hash_id hash_value, std::string &dest)
soar_module::sqlite_statementsmem_setup_web_crawl (agent *my_agent, smem_weighted_cue_element *el)
void smem_soar_store (agent *my_agent, Symbol *id, smem_storage_type store_type=store_level, tc_number tc=(0))
void smem_store_chunk (agent *my_agent, smem_lti_id parent_id, smem_slot_map *children, bool remove_old_children=true, Symbol *print_id=NULL)
bool smem_symbol_is_constant (Symbol *sym)
smem_hash_id smem_temporal_hash (agent *my_agent, Symbol *sym, bool add_on_fail=true)
smem_hash_id smem_temporal_hash_add (agent *my_agent, byte sym_type)
smem_hash_id smem_temporal_hash_float (agent *my_agent, double val, bool add_on_fail=true)
smem_hash_id smem_temporal_hash_int (agent *my_agent, int64_t val, bool add_on_fail=true)
smem_hash_id smem_temporal_hash_str (agent *my_agent, char *val, bool add_on_fail=true)
bool smem_valid_production (condition *lhs_top, action *rhs_top)
void smem_variable_create (agent *my_agent, smem_variable_key variable_id, int64_t variable_value)
bool smem_variable_get (agent *my_agent, smem_variable_key variable_id, int64_t *variable_value)
void smem_variable_set (agent *my_agent, smem_variable_key variable_id, int64_t variable_value)
void smem_visualize_lti (agent *my_agent, smem_lti_id lti_id, unsigned int depth, std::string *return_val)
void smem_visualize_store (agent *my_agent, std::string *return_val)

Function Documentation

void _smem_close_vars ( agent my_agent)
inline

Definition at line 2794 of file semantic_memory.cpp.

References smem_stat_container::chunks, soar_module::primitive_stat< T >::get_value(), smem_stat_container::slots, agent_struct::smem_max_cycle, agent_struct::smem_stats, smem_variable_set(), var_max_cycle, var_num_edges, and var_num_nodes.

Referenced by smem_backup_db(), and smem_close().

{
// store max cycle for future use of the smem database
// store num nodes/edges for future use of the smem database
}
void _smem_lti_from_rhs_value ( rhs_value  rv,
std::set< Symbol * > *  valid_ltis 
)

Definition at line 1277 of file semantic_memory.cpp.

References symbol_union::id, IDENTIFIER_SYMBOL_TYPE, NIL, cons_struct::rest, rhs_value_is_symbol(), rhs_value_to_funcall_list(), rhs_value_to_symbol(), and identifier_struct::smem_lti.

Referenced by smem_valid_production().

{
if ( rhs_value_is_symbol( rv ) )
{
if ( ( sym->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) && ( sym->id.smem_lti != NIL ) )
{
valid_ltis->insert( sym );
}
}
else
{
for ( cons *c=fl->rest; c!=NIL; c=c->rest )
{
_smem_lti_from_rhs_value( static_cast<rhs_value>( c->first ), valid_ltis );
}
}
}
void _smem_lti_from_test ( test  t,
std::set< Symbol * > *  valid_ltis 
)

Definition at line 1248 of file semantic_memory.cpp.

References complex_test_from_test(), complex_test_struct::test_info_union::conjunct_list, CONJUNCTIVE_TEST, complex_test_struct::data, symbol_union::id, IDENTIFIER_SYMBOL_TYPE, NIL, referent_of_equality_test(), identifier_struct::smem_lti, test_is_blank_or_equality_test(), test_is_blank_test(), and complex_test_struct::type.

Referenced by smem_valid_production().

{
if ( test_is_blank_test(t) ) return;
{
if ( ( referent->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) && ( referent->id.smem_lti != NIL ) )
{
valid_ltis->insert( referent );
}
return;
}
{
if ( ct->type==CONJUNCTIVE_TEST )
{
for ( cons *c=ct->data.conjunct_list; c!=NIL; c=c->rest )
{
_smem_lti_from_test( static_cast<test>( c->first ), valid_ltis );
}
}
}
}
std::set< smem_lti_id > _smem_print_lti ( agent my_agent,
smem_lti_id  lti_id,
char  lti_letter,
uint64_t  lti_number,
double  lti_act,
std::string *  return_val 
)
inline

Definition at line 4365 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), FLOAT_CONSTANT_SYMBOL_TYPE, INT_CONSTANT_SYMBOL_TYPE, soar_module::statement::reinitialize(), soar_module::row, smem_reverse_hash_float(), smem_reverse_hash_int(), smem_reverse_hash_str(), agent_struct::smem_stmts, SMEM_WEB_NULL, SYM_CONSTANT_SYMBOL_TYPE, and smem_statement_container::web_expand.

Referenced by smem_print_lti(), and smem_print_store().

{
std::set< smem_lti_id > next;
std::string temp_str, temp_str2, temp_str3;
int64_t temp_int;
double temp_double;
std::map< std::string, std::list< std::string > > augmentations;
std::map< std::string, std::list< std::string > >::iterator lti_slot;
std::list< std::string >::iterator slot_val;
//
//
return_val->append( "(@" );
return_val->push_back( lti_letter );
to_string( lti_number, temp_str );
return_val->append( temp_str );
// get direct children: attr_type, attr_hash, value_type, value_hash, value_letter, value_num, value_lti
expand_q->bind_int( 1, lti_id );
while ( expand_q->execute() == soar_module::row )
{
// get attribute
switch ( expand_q->column_int(0) )
{
smem_reverse_hash_str( my_agent, expand_q->column_int(1), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, expand_q->column_int(1) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, expand_q->column_int(1) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
// identifier vs. constant
if ( expand_q->column_int( 6 ) != SMEM_WEB_NULL )
{
temp_str2.clear();
temp_str2.push_back( '@' );
// letter
temp_str2.push_back( static_cast<char>( expand_q->column_int( 4 ) ) );
// number
temp_int = expand_q->column_int( 5 );
to_string( temp_int, temp_str3 );
temp_str2.append( temp_str3 );
// add to next
next.insert( static_cast< smem_lti_id >( expand_q->column_int( 6 ) ) );
}
else
{
switch ( expand_q->column_int(2) )
{
smem_reverse_hash_str( my_agent, expand_q->column_int(3), temp_str2 );
break;
temp_int = smem_reverse_hash_int( my_agent, expand_q->column_int(3) );
to_string( temp_int, temp_str2 );
break;
temp_double = smem_reverse_hash_float( my_agent, expand_q->column_int(3) );
to_string( temp_double, temp_str2 );
break;
default:
temp_str2.clear();
break;
}
}
augmentations[ temp_str ].push_back( temp_str2 );
}
expand_q->reinitialize();
// output augmentations nicely
{
for ( lti_slot=augmentations.begin(); lti_slot!=augmentations.end(); lti_slot++ )
{
return_val->append( " ^" );
return_val->append( lti_slot->first );
for ( slot_val=lti_slot->second.begin(); slot_val!=lti_slot->second.end(); slot_val++ )
{
return_val->append( " " );
return_val->append( (*slot_val) );
}
}
}
augmentations.clear();
return_val->append( " [" );
to_string( lti_act, temp_str, 3, true );
if ( lti_act >= 0 )
{
return_val->append( "+" );
}
return_val->append( temp_str );
return_val->append( "]" );
return_val->append( ")\n" );
return next;
}
void _smem_process_buffered_wme_list ( agent my_agent,
Symbol state,
soar_module::wme_set cue_wmes,
soar_module::symbol_triple_list my_list,
bool  meta 
)
inline

Definition at line 670 of file semantic_memory.cpp.

References add_preference_to_tm(), chunk_instantiation(), symbol_union::id, insert_at_head_of_dll, preference_struct::inst_next, soar_module::make_fake_instantiation(), instantiation_struct::next, NIL, preference_add_ref(), preference_remove_ref(), identifier_struct::preferences_from_goal, instantiation_struct::preferences_generated, identifier_struct::smem_info, smem_data_struct::smem_wmes, wma_activate_wmes_in_pref(), and wma_enabled().

Referenced by smem_process_buffered_wmes().

{
if ( my_list.empty() )
{
return;
}
instantiation* inst = soar_module::make_fake_instantiation( my_agent, state, &cue_wmes, &my_list );
for ( preference* pref=inst->preferences_generated; pref; pref=pref->inst_next )
{
// add the preference to temporary memory
if ( add_preference_to_tm( my_agent, pref ) )
{
// and add it to the list of preferences to be removed
// when the goal is removed
insert_at_head_of_dll( state->id.preferences_from_goal, pref, all_of_goal_next, all_of_goal_prev );
pref->on_goal_list = true;
if ( meta )
{
// if this is a meta wme, then it is completely local
// to the state and thus we will manually remove it
// (via preference removal) when the time comes
state->id.smem_info->smem_wmes->push_back( pref );
}
}
else
{
preference_remove_ref( my_agent, pref );
}
}
if ( !meta )
{
// otherwise, we submit the fake instantiation to backtracing
// such as to potentially produce justifications that can follow
// it to future adventures (potentially on new states)
instantiation *my_justification_list = NIL;
chunk_instantiation( my_agent, inst, false, &my_justification_list );
// if any justifications are created, assert their preferences manually
// (copied mainly from assert_new_preferences with respect to our circumstances)
if ( my_justification_list != NIL )
{
preference *just_pref = NIL;
instantiation *next_justification = NIL;
for ( instantiation *my_justification=my_justification_list;
my_justification!=NIL;
my_justification=next_justification )
{
next_justification = my_justification->next;
if ( my_justification->in_ms )
{
insert_at_head_of_dll( my_justification->prod->instantiations, my_justification, next, prev );
}
for ( just_pref=my_justification->preferences_generated; just_pref!=NIL; just_pref=just_pref->inst_next )
{
if ( add_preference_to_tm( my_agent, just_pref ) )
{
if ( wma_enabled( my_agent ) )
{
wma_activate_wmes_in_pref( my_agent, just_pref );
}
}
else
{
preference_add_ref( just_pref );
preference_remove_ref( my_agent, just_pref );
}
}
}
}
}
}
bool _smem_process_cue_wme ( agent my_agent,
wme w,
bool  pos_cue,
smem_prioritized_weighted_cue weighted_pq 
)
inline

Definition at line 2139 of file semantic_memory.cpp.

References wme_struct::attr, smem_weighted_cue_element_struct::attr_hash, attr_t, soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), smem_statement_container::ct_attr_get, smem_statement_container::ct_const_get, smem_statement_container::ct_lti_get, smem_weighted_cue_element_struct::cue_element, smem_weighted_cue_element_struct::element_type, soar_module::statement::execute(), symbol_union::id, NIL, smem_weighted_cue_element_struct::pos_element, soar_module::statement::reinitialize(), soar_module::row, identifier_struct::smem_lti, agent_struct::smem_stmts, smem_symbol_is_constant(), smem_temporal_hash(), wme_struct::value, value_const_t, smem_weighted_cue_element_struct::value_hash, smem_weighted_cue_element_struct::value_lti, value_lti_t, and smem_weighted_cue_element_struct::weight.

Referenced by smem_process_query().

{
bool good_wme = true;
smem_weighted_cue_element *new_cue_element;
smem_hash_id attr_hash;
smem_hash_id value_hash;
smem_lti_id value_lti;
smem_cue_element_type element_type;
{
// we only have to do hard work if
attr_hash = smem_temporal_hash( my_agent, w->attr, false );
if ( attr_hash != NIL )
{
{
value_lti = NIL;
value_hash = smem_temporal_hash( my_agent, w->value, false );
if ( value_hash != NIL )
{
q = my_agent->smem_stmts->ct_const_get;
q->bind_int( 1, attr_hash );
q->bind_int( 2, value_hash );
element_type = value_const_t;
}
else
{
if ( pos_cue )
{
good_wme = false;
}
}
}
else
{
value_lti = w->value->id.smem_lti;
value_hash = NIL;
if ( value_lti == NIL )
{
q = my_agent->smem_stmts->ct_attr_get;
q->bind_int( 1, attr_hash );
element_type = attr_t;
}
else
{
q = my_agent->smem_stmts->ct_lti_get;
q->bind_int( 1, attr_hash );
q->bind_int( 2, value_lti );
element_type = value_lti_t;
}
}
if ( good_wme )
{
if ( q->execute() == soar_module::row )
{
new_cue_element = new smem_weighted_cue_element;
new_cue_element->weight = q->column_int( 0 );
new_cue_element->attr_hash = attr_hash;
new_cue_element->value_hash = value_hash;
new_cue_element->value_lti = value_lti;
new_cue_element->cue_element = w;
new_cue_element->element_type = element_type;
new_cue_element->pos_element = pos_cue;
weighted_pq.push( new_cue_element );
new_cue_element = NULL;
}
else
{
if ( pos_cue )
{
good_wme = false;
}
}
}
}
else
{
if ( pos_cue )
{
good_wme = false;
}
}
}
return good_wme;
}
void smem_attach ( agent my_agent)
bool smem_backup_db ( agent my_agent,
const char *  file_name,
std::string *  err 
)
void smem_buffer_add_wme ( soar_module::symbol_triple_list my_list,
Symbol id,
Symbol attr,
Symbol value 
)
inline

Definition at line 756 of file semantic_memory.cpp.

References symbol_add_ref().

Referenced by smem_install_memory(), smem_process_query(), and smem_respond_to_cmd().

{
my_list.push_back( new soar_module::symbol_triple( id, attr, value ) );
symbol_add_ref( attr );
symbol_add_ref( value );
}
void smem_clear_result ( agent my_agent,
Symbol state 
)

Definition at line 2526 of file semantic_memory.cpp.

References symbol_union::id, preference_struct::in_tm, remove_preference_from_tm(), identifier_struct::smem_info, and smem_data_struct::smem_wmes.

Referenced by smem_respond_to_cmd().

{
preference *pref;
while ( !state->id.smem_info->smem_wmes->empty() )
{
pref = state->id.smem_info->smem_wmes->back();
state->id.smem_info->smem_wmes->pop_back();
if ( pref->in_tm )
{
remove_preference_from_tm( my_agent, pref );
}
}
}
void smem_close ( agent my_agent)
Bool smem_count_ltis ( agent ,
void *  item,
void *  userdata 
)

Definition at line 1396 of file semantic_memory.cpp.

References symbol_union::id, NIL, and identifier_struct::smem_lti.

Referenced by reset_id_counters().

{
Symbol *id = static_cast<symbol_union *>(item);
if ( id->id.smem_lti != NIL )
{
uint64_t* counter = reinterpret_cast<uint64_t*>( userdata );
(*counter)++;
}
return false;
}
void smem_deallocate_chunk ( agent my_agent,
smem_chunk chunk,
bool  free_chunk = true 
)

Definition at line 2832 of file semantic_memory.cpp.

References smem_chunk_struct::slots, symbol_remove_ref(), and value_const_t.

Referenced by smem_parse_chunk(), and smem_parse_chunks().

{
if ( chunk )
{
// proceed to slots
if ( chunk->slots )
{
smem_slot_map::iterator s;
smem_slot::iterator v;
// iterate over slots
while ( !chunk->slots->empty() )
{
s = chunk->slots->begin();
// proceed to slot contents
if ( s->second )
{
// iterate over each value
for ( v=s->second->begin(); v!=s->second->end(); v=s->second->erase(v) )
{
// de-allocation of value is dependent upon type
if ( (*v)->val_const.val_type == value_const_t )
{
symbol_remove_ref( my_agent, (*v)->val_const.val_value );
}
else
{
// we never deallocate the lti chunk, as we assume
// it will exist elsewhere for deallocation
// delete (*s)->val_lti.val_value;
}
delete (*v);
}
delete s->second;
}
// deallocate attribute for each corresponding value
symbol_remove_ref( my_agent, s->first );
chunk->slots->erase( s );
}
// remove slots
delete chunk->slots;
chunk->slots = NULL;
}
// remove chunk itself
if ( free_chunk )
{
delete chunk;
chunk = NULL;
}
}
}
void smem_disconnect_chunk ( agent my_agent,
smem_lti_id  parent_id 
)

Definition at line 1553 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), smem_statement_container::ct_attr_update, smem_statement_container::ct_const_update, smem_statement_container::ct_lti_update, soar_module::statement::execute(), soar_module::primitive_stat< T >::get_value(), soar_module::op_reinit, soar_module::statement::reinitialize(), soar_module::row, soar_module::primitive_stat< T >::set_value(), smem_stat_container::slots, agent_struct::smem_stats, agent_struct::smem_stmts, SMEM_WEB_NULL, smem_statement_container::web_all, and smem_statement_container::web_truncate.

Referenced by smem_store_chunk().

{
// adjust attr, attr/value counts
{
uint64_t pair_count = 0;
smem_lti_id child_attr = 0;
std::set<smem_lti_id> distinct_attr;
// pairs first, accumulate distinct attributes and pair count
my_agent->smem_stmts->web_all->bind_int( 1, parent_id );
while ( my_agent->smem_stmts->web_all->execute() == soar_module::row )
{
pair_count++;
child_attr = my_agent->smem_stmts->web_all->column_int( 0 );
distinct_attr.insert( child_attr );
// null -> attr/lti
if ( my_agent->smem_stmts->web_all->column_int( 1 ) != SMEM_WEB_NULL )
{
// adjust in opposite direction ( adjust, attribute, const )
my_agent->smem_stmts->ct_const_update->bind_int( 1, -1 );
my_agent->smem_stmts->ct_const_update->bind_int( 2, child_attr );
my_agent->smem_stmts->ct_const_update->bind_int( 3, my_agent->smem_stmts->web_all->column_int( 1 ) );
}
else
{
// adjust in opposite direction ( adjust, attribute, lti )
my_agent->smem_stmts->ct_lti_update->bind_int( 1, -1 );
my_agent->smem_stmts->ct_lti_update->bind_int( 2, child_attr );
my_agent->smem_stmts->ct_lti_update->bind_int( 3, my_agent->smem_stmts->web_all->column_int( 2 ) );
}
}
// now attributes
for (std::set<smem_lti_id>::iterator a=distinct_attr.begin(); a!=distinct_attr.end(); a++)
{
// adjust in opposite direction ( adjust, attribute )
my_agent->smem_stmts->ct_attr_update->bind_int( 1, -1 );
my_agent->smem_stmts->ct_attr_update->bind_int( 2, *a );
}
// update local statistic
my_agent->smem_stats->slots->set_value( my_agent->smem_stats->slots->get_value() - pair_count );
}
// disconnect
{
my_agent->smem_stmts->web_truncate->bind_int( 1, parent_id );
}
}
bool smem_enabled ( agent my_agent)
smem_wme_list* smem_get_direct_augs_of_id ( Symbol id,
tc_number  tc = (0) 
)

Definition at line 609 of file semantic_memory.cpp.

References wme_struct::acceptable, symbol_union::id, IDENTIFIER_SYMBOL_TYPE, identifier_struct::impasse_wmes, identifier_struct::input_wmes, wme_struct::next, slot_struct::next, NIL, identifier_struct::slots, identifier_struct::tc_num, and slot_struct::wmes.

Referenced by smem_process_query(), smem_respond_to_cmd(), and smem_soar_store().

{
slot *s;
wme *w;
smem_wme_list *return_val = new smem_wme_list;
// augs only exist for identifiers
if ( id->common.symbol_type == IDENTIFIER_SYMBOL_TYPE )
{
if ( tc != NIL )
{
if ( tc == id->id.tc_num )
{
return return_val;
}
else
{
id->id.tc_num = tc;
}
}
// impasse wmes
for ( w=id->id.impasse_wmes; w!=NIL; w=w->next )
{
if ( !w->acceptable )
{
return_val->push_back( w );
}
}
// input wmes
for ( w=id->id.input_wmes; w!=NIL; w=w->next )
{
return_val->push_back( w );
}
// regular wmes
for ( s=id->id.slots; s!=NIL; s=s->next )
{
for ( w=s->wmes; w!=NIL; w=w->next )
{
if ( !w->acceptable )
{
return_val->push_back( w );
}
}
}
}
return return_val;
}
void smem_go ( agent my_agent,
bool  store_only 
)

Definition at line 3797 of file semantic_memory.cpp.

References smem_respond_to_cmd(), agent_struct::smem_timers, soar_module::timer::start(), soar_module::timer::stop(), and smem_timer_container::total.

Referenced by do_one_top_level_phase().

{
my_agent->smem_timers->total->start();
#ifndef SMEM_EXPERIMENT
smem_respond_to_cmd( my_agent, store_only );
#else // SMEM_EXPERIMENT
#endif // SMEM_EXPERIMENT
my_agent->smem_timers->total->stop();
}
void smem_init_db ( agent my_agent)

Definition at line 2568 of file semantic_memory.cpp.

References smem_param_container::activation_mode, smem_statement_container::begin, smem_param_container::cache_size, smem_stat_container::chunks, smem_statement_container::commit, soar_module::sqlite_database::connect(), smem_param_container::database, soar_module::disconnected, soar_module::statement::execute(), soar_module::status_object< T >::get_errmsg(), soar_module::status_object< T >::get_status(), soar_module::primitive_param< T >::get_string(), soar_module::primitive_param< T >::get_value(), soar_module::string_param::get_value(), soar_module::constant_param< T >::get_value(), smem_timer_container::init, smem_param_container::lazy_commit, smem_param_container::memory, soar_module::on, soar_module::op_reinit, smem_param_container::opt, smem_param_container::opt_speed, smem_param_container::page_16k, smem_param_container::page_1k, smem_param_container::page_2k, smem_param_container::page_32k, smem_param_container::page_4k, smem_param_container::page_64k, smem_param_container::page_8k, smem_param_container::page_size, smem_param_container::path, soar_module::statement::prepare(), soar_module::statement_container::prepare(), print(), soar_module::problem, soar_module::ready, soar_module::primitive_param< T >::set_value(), soar_module::constant_param< T >::set_value(), soar_module::primitive_stat< T >::set_value(), smem_stat_container::slots, agent_struct::smem_db, agent_struct::smem_max_cycle, agent_struct::smem_params, smem_reset_id_counters(), SMEM_SIGNATURE, agent_struct::smem_stats, agent_struct::smem_stmts, agent_struct::smem_timers, agent_struct::smem_validation, smem_variable_create(), smem_variable_get(), soar_module::timer::start(), soar_module::timer::stop(), soar_module::sqlite_statement_container::structure(), smem_param_container::thresh, var_act_mode, var_act_thresh, var_max_cycle, var_num_edges, var_num_nodes, and xml_generate_warning().

Referenced by smem_attach().

{
{
return;
}
my_agent->smem_timers->init->start();
const char *db_path;
{
db_path = ":memory:";
}
else
{
db_path = my_agent->smem_params->path->get_value();
}
// attempt connection
my_agent->smem_db->connect( db_path );
if ( my_agent->smem_db->get_status() == soar_module::problem )
{
char buf[256];
SNPRINTF( buf, 254, "DB ERROR: %s", my_agent->smem_db->get_errmsg() );
print( my_agent, buf );
xml_generate_warning( my_agent, buf );
}
else
{
// temporary queries for one-time init actions
// apply performance options
{
// page_size
{
switch ( my_agent->smem_params->page_size->get_value() )
{
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 1024" );
break;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 2048" );
break;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 4096" );
break;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 8192" );
break;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 16384" );
break;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 32768" );
break;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA page_size = 65536" );
break;
}
temp_q->prepare();
temp_q->execute();
delete temp_q;
temp_q = NULL;
}
// cache_size
{
std::string cache_sql( "PRAGMA cache_size = " );
char* str = my_agent->smem_params->cache_size->get_string();
cache_sql.append( str );
free(str);
str = NULL;
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, cache_sql.c_str() );
temp_q->prepare();
temp_q->execute();
delete temp_q;
temp_q = NULL;
}
// optimization
{
// synchronous - don't wait for writes to complete (can corrupt the db in case unexpected crash during transaction)
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA synchronous = OFF" );
temp_q->prepare();
temp_q->execute();
delete temp_q;
temp_q = NULL;
// journal_mode - no atomic transactions (can result in database corruption if crash during transaction)
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA journal_mode = OFF" );
temp_q->prepare();
temp_q->execute();
delete temp_q;
temp_q = NULL;
// locking_mode - no one else can view the database after our first write
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "PRAGMA locking_mode = EXCLUSIVE" );
temp_q->prepare();
temp_q->execute();
delete temp_q;
temp_q = NULL;
}
}
// update validation count
my_agent->smem_validation++;
// setup common structures/queries
my_agent->smem_stmts = new smem_statement_container( my_agent );
// setup initial structures (if necessary)
bool tabula_rasa;
{
// create structures if database does not contain signature table
// which we can detect by trying to create it
// note: this only could have been done with an open database (hence in initialization)
temp_q = new soar_module::sqlite_statement( my_agent->smem_db, "CREATE TABLE " SMEM_SIGNATURE " (uid INTEGER)" );
temp_q->prepare();
tabula_rasa = ( temp_q->get_status() == soar_module::ready );
if ( tabula_rasa )
{
// if was possible to prepare, the table doesn't exist so we create it
temp_q->execute();
// and all other structures
my_agent->smem_stmts->structure();
}
delete temp_q;
temp_q = NULL;
}
// initialize queries given database structure
my_agent->smem_stmts->prepare();
// initialize persistent variables
if ( tabula_rasa )
{
{
// max cycle
my_agent->smem_max_cycle = static_cast<int64_t>( 1 );
// number of nodes
my_agent->smem_stats->chunks->set_value( 0 );
// number of edges
my_agent->smem_stats->slots->set_value( 0 );
// threshold (from user parameter value)
smem_variable_create( my_agent, var_act_thresh, static_cast<int64_t>( my_agent->smem_params->thresh->get_value() ) );
// activation mode (from user parameter value)
smem_variable_create( my_agent, var_act_mode, static_cast<int64_t>( my_agent->smem_params->activation_mode->get_value() ) );
}
}
else
{
int64_t temp;
// max cycle
smem_variable_get( my_agent, var_max_cycle, &( my_agent->smem_max_cycle ) );
// number of nodes
smem_variable_get( my_agent, var_num_nodes, &( temp ) );
my_agent->smem_stats->chunks->set_value( temp );
// number of edges
smem_variable_get( my_agent, var_num_edges, &( temp ) );
my_agent->smem_stats->slots->set_value( temp );
// threshold
smem_variable_get( my_agent, var_act_thresh, &( temp ) );
my_agent->smem_params->thresh->set_value( temp );
// activation mode
smem_variable_get( my_agent, var_act_mode, &( temp ) );
my_agent->smem_params->activation_mode->set_value( static_cast< smem_param_container::act_choices >( temp ) );
}
// reset identifier counters
// if lazy commit, then we encapsulate the entire lifetime of the agent in a single transaction
{
}
}
my_agent->smem_timers->init->stop();
}
void smem_install_memory ( agent my_agent,
Symbol state,
smem_lti_id  parent_id,
Symbol lti,
bool  activate_lti,
soar_module::symbol_triple_list meta_wmes,
soar_module::symbol_triple_list retrieval_wmes 
)

Definition at line 2016 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), soar_module::constant_param< T >::get_value(), symbol_union::id, identifier_struct::impasse_wmes, identifier_struct::input_wmes, identifier_struct::level, smem_statement_container::lti_letter_num, smem_param_container::merge, smem_param_container::merge_add, smem_timer_container::ncb_retrieval, NIL, soar_module::statement::reinitialize(), soar_module::row, identifier_struct::slots, smem_buffer_add_wme(), smem_lti_activate(), smem_lti_soar_make(), agent_struct::smem_params, identifier_struct::smem_result_header, smem_reverse_hash(), agent_struct::smem_stmts, agent_struct::smem_sym_retrieved, agent_struct::smem_timers, SMEM_WEB_NULL, soar_module::timer::start(), soar_module::timer::stop(), symbol_remove_ref(), and smem_statement_container::web_expand.

Referenced by smem_process_query(), and smem_respond_to_cmd().

{
// get the ^result header for this state
Symbol *result_header = state->id.smem_result_header;
// get identifier if not known
bool lti_created_here = false;
if ( lti == NIL )
{
q->bind_int( 1, parent_id );
q->execute();
lti = smem_lti_soar_make( my_agent, parent_id, static_cast<char>( q->column_int( 0 ) ), static_cast<uint64_t>( q->column_int( 1 ) ), result_header->id.level );
lti_created_here = true;
}
// activate lti
if ( activate_lti )
{
smem_lti_activate( my_agent, parent_id, true );
}
// point retrieved to lti
smem_buffer_add_wme( meta_wmes, result_header, my_agent->smem_sym_retrieved, lti );
if ( lti_created_here )
{
// if the identifier was created above we need to
// remove a single ref count AFTER the wme
// is added (such as to not deallocate the symbol
// prematurely)
symbol_remove_ref( my_agent, lti );
}
// if no children, then retrieve children
// merge may override this behavior
( ( lti->id.impasse_wmes == NIL ) &&
( lti->id.input_wmes == NIL ) &&
( lti->id.slots == NIL ) ) )
{
Symbol *attr_sym;
Symbol *value_sym;
// get direct children: attr_type, attr_hash, value_type, value_hash, value_letter, value_num, value_lti
expand_q->bind_int( 1, parent_id );
while ( expand_q->execute() == soar_module::row )
{
// make the identifier symbol irrespective of value type
attr_sym = smem_reverse_hash( my_agent, static_cast<byte>( expand_q->column_int(0) ), static_cast<smem_hash_id>( expand_q->column_int(1) ) );
// identifier vs. constant
if ( expand_q->column_int( 6 ) != SMEM_WEB_NULL )
{
value_sym = smem_lti_soar_make( my_agent, static_cast<smem_lti_id>( expand_q->column_int( 6 ) ), static_cast<char>( expand_q->column_int( 4 ) ), static_cast<uint64_t>( expand_q->column_int( 5 ) ), lti->id.level );
}
else
{
value_sym = smem_reverse_hash( my_agent, static_cast<byte>( expand_q->column_int(2) ), static_cast<smem_hash_id>( expand_q->column_int(3) ) );
}
// add wme
smem_buffer_add_wme( retrieval_wmes, lti, attr_sym, value_sym );
// deal with ref counts - attribute/values are always created in this function
// (thus an extra ref count is set before adding a wme)
symbol_remove_ref( my_agent, attr_sym );
symbol_remove_ref( my_agent, value_sym );
}
expand_q->reinitialize();
}
}
double smem_lti_activate ( agent my_agent,
smem_lti_id  lti,
bool  add_access,
uint64_t  num_edges = static_cast<uint64_t>( static_cast<uint64_t>( 0 - 1 ) / static_cast<uint64_t>(2) ) 
)
inline

Definition at line 1091 of file semantic_memory.cpp.

References smem_timer_container::act, smem_param_container::act_base, smem_param_container::act_frequency, smem_statement_container::act_lti_child_ct_get, smem_statement_container::act_lti_set, smem_param_container::act_recency, smem_statement_container::act_set, smem_stat_container::act_updates, smem_param_container::activation_mode, smem_param_container::base_incremental_threshes, smem_param_container::base_update, soar_module::sqlite_statement::bind_double(), soar_module::sqlite_statement::bind_int(), smem_param_container::bupt_incremental, soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), soar_module::primitive_param< T >::get_value(), soar_module::constant_param< T >::get_value(), soar_module::primitive_stat< T >::get_value(), smem_statement_container::history_add, smem_statement_container::history_push, smem_statement_container::lti_access_get, smem_statement_container::lti_access_set, smem_statement_container::lti_get_t, soar_module::op_reinit, soar_module::statement::reinitialize(), soar_module::row, soar_module::primitive_set_param< T >::set_begin(), soar_module::primitive_set_param< T >::set_end(), soar_module::primitive_stat< T >::set_value(), SMEM_ACT_MAX, smem_lti_calc_base(), agent_struct::smem_max_cycle, agent_struct::smem_params, agent_struct::smem_stats, agent_struct::smem_stmts, agent_struct::smem_timers, soar_module::timer::start(), soar_module::timer::stop(), and smem_param_container::thresh.

Referenced by smem_install_memory(), smem_process_query(), and smem_store_chunk().

{
my_agent->smem_timers->act->start();
int64_t time_now;
if ( add_access )
{
time_now = my_agent->smem_max_cycle++;
{
int64_t time_diff;
for ( std::set< int64_t >::iterator b=my_agent->smem_params->base_incremental_threshes->set_begin(); b!=my_agent->smem_params->base_incremental_threshes->set_end(); b++ )
{
if ( *b > 0 )
{
time_diff = ( time_now - *b );
if ( time_diff > 0 )
{
std::list< smem_lti_id > to_update;
my_agent->smem_stmts->lti_get_t->bind_int( 1, time_diff );
while ( my_agent->smem_stmts->lti_get_t->execute() == soar_module::row )
{
to_update.push_back( static_cast< smem_lti_id >( my_agent->smem_stmts->lti_get_t->column_int(0) ) );
}
for ( std::list< smem_lti_id >::iterator it=to_update.begin(); it!=to_update.end(); it++ )
{
smem_lti_activate( my_agent, (*it), false );
}
}
}
}
}
}
else
{
time_now = my_agent->smem_max_cycle;
my_agent->smem_stats->act_updates->set_value( my_agent->smem_stats->act_updates->get_value() + 1 );
}
// access information
uint64_t prev_access_n = 0;
uint64_t prev_access_t = 0;
uint64_t prev_access_1 = 0;
{
// get old (potentially useful below)
{
my_agent->smem_stmts->lti_access_get->bind_int( 1, lti );
prev_access_n = my_agent->smem_stmts->lti_access_get->column_int( 0 );
prev_access_t = my_agent->smem_stmts->lti_access_get->column_int( 1 );
prev_access_1 = my_agent->smem_stmts->lti_access_get->column_int( 2 );
}
// set new
if ( add_access )
{
my_agent->smem_stmts->lti_access_set->bind_int( 1, ( prev_access_n + 1 ) );
my_agent->smem_stmts->lti_access_set->bind_int( 2, time_now );
my_agent->smem_stmts->lti_access_set->bind_int( 3, ( ( prev_access_n == 0 )?( time_now ):( prev_access_1 ) ) );
my_agent->smem_stmts->lti_access_set->bind_int( 4, lti );
}
}
// get new activation value (depends upon bias)
double new_activation = 0.0;
{
new_activation = static_cast<double>( time_now );
}
else if ( act_mode == smem_param_container::act_frequency )
{
new_activation = static_cast<double>( prev_access_n + ( ( add_access )?(1):(0) ) );
}
else if ( act_mode == smem_param_container::act_base )
{
if ( prev_access_n == 0 )
{
if ( add_access )
{
my_agent->smem_stmts->history_add->bind_int( 1, lti );
my_agent->smem_stmts->history_add->bind_int( 2, time_now );
}
new_activation = 0;
}
else
{
if ( add_access )
{
my_agent->smem_stmts->history_push->bind_int( 1, time_now );
my_agent->smem_stmts->history_push->bind_int( 2, lti );
}
new_activation = smem_lti_calc_base( my_agent, lti, time_now+( ( add_access )?(1):(0) ), prev_access_n+( ( add_access )?(1):(0) ), prev_access_1 );
}
}
// get number of augmentations (if not supplied)
if ( num_edges == SMEM_ACT_MAX )
{
my_agent->smem_stmts->act_lti_child_ct_get->bind_int( 1, lti );
num_edges = my_agent->smem_stmts->act_lti_child_ct_get->column_int( 0 );
}
// only if augmentation count is less than threshold do we associate with edges
if ( num_edges < static_cast<uint64_t>( my_agent->smem_params->thresh->get_value() ) )
{
// act_value=? WHERE lti=?
my_agent->smem_stmts->act_set->bind_double( 1, new_activation );
my_agent->smem_stmts->act_set->bind_int( 2, lti );
}
// always associate activation with lti
{
// act_value=? WHERE lti=?
my_agent->smem_stmts->act_lti_set->bind_double( 1, new_activation );
my_agent->smem_stmts->act_lti_set->bind_int( 2, lti );
}
my_agent->smem_timers->act->stop();
return new_activation;
}
smem_lti_id smem_lti_add_id ( agent my_agent,
char  name_letter,
uint64_t  name_number 
)
inline

Definition at line 1432 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_double(), soar_module::sqlite_statement::bind_int(), smem_stat_container::chunks, soar_module::statement::execute(), soar_module::primitive_stat< T >::get_value(), soar_module::sqlite_database::last_insert_rowid(), smem_statement_container::lti_add, soar_module::op_reinit, soar_module::primitive_stat< T >::set_value(), agent_struct::smem_db, agent_struct::smem_stats, and agent_struct::smem_stmts.

Referenced by smem_lti_soar_add(), smem_parse_chunks(), and smem_store_chunk().

{
smem_lti_id return_val;
// create lti: letter, number, child_ct, act_value, access_n, access_t, access_1
my_agent->smem_stmts->lti_add->bind_int( 1, static_cast<uint64_t>( name_letter ) );
my_agent->smem_stmts->lti_add->bind_int( 2, static_cast<uint64_t>( name_number ) );
my_agent->smem_stmts->lti_add->bind_int( 3, static_cast<uint64_t>( 0 ) );
my_agent->smem_stmts->lti_add->bind_double( 4, static_cast<double>( 0 ) );
my_agent->smem_stmts->lti_add->bind_int( 5, static_cast<uint64_t>( 0 ) );
my_agent->smem_stmts->lti_add->bind_int( 6, static_cast<uint64_t>( 0 ) );
my_agent->smem_stmts->lti_add->bind_int( 7, static_cast<uint64_t>( 0 ) );
return_val = static_cast<smem_lti_id>( my_agent->smem_db->last_insert_rowid() );
// increment stat
my_agent->smem_stats->chunks->set_value( my_agent->smem_stats->chunks->get_value() + 1 );
return return_val;
}
double smem_lti_calc_base ( agent my_agent,
smem_lti_id  lti,
int64_t  time_now,
uint64_t  n = 0,
uint64_t  access_1 = 0 
)
inline

Definition at line 1041 of file semantic_memory.cpp.

References smem_param_container::base_decay, soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), soar_module::primitive_param< T >::get_value(), smem_statement_container::history_get, smem_statement_container::lti_access_get, soar_module::statement::reinitialize(), SMEM_ACT_HISTORY_ENTRIES, SMEM_ACT_LOW, agent_struct::smem_params, and agent_struct::smem_stmts.

Referenced by smem_lti_activate().

{
double sum = 0.0;
double d = my_agent->smem_params->base_decay->get_value();
uint64_t t_k;
uint64_t t_n = ( time_now - access_1 );
if ( n == 0 )
{
my_agent->smem_stmts->lti_access_get->bind_int( 1, lti );
n = my_agent->smem_stmts->lti_access_get->column_int( 0 );
access_1 = my_agent->smem_stmts->lti_access_get->column_int( 2 );
}
// get all history
my_agent->smem_stmts->history_get->bind_int( 1, lti );
{
int available_history = static_cast<int>( ( SMEM_ACT_HISTORY_ENTRIES<n )?(SMEM_ACT_HISTORY_ENTRIES):(n) );
t_k = static_cast<uint64_t>( time_now - my_agent->smem_stmts->history_get->column_int( available_history-1 ) );
for ( int i=0; i<available_history; i++ )
{
sum += pow( static_cast<double>( time_now - my_agent->smem_stmts->history_get->column_int( i ) ),
static_cast<double>( -d ) );
}
}
// if available history was insufficient, approximate rest
{
double apx_numerator = ( static_cast<double>( n - SMEM_ACT_HISTORY_ENTRIES ) * ( pow( static_cast<double>( t_n ), 1.0-d ) - pow( static_cast<double>( t_k ), 1.0-d ) ) );
double apx_denominator = ( ( 1.0-d ) * static_cast<double>( t_n - t_k ) );
sum += ( apx_numerator / apx_denominator );
}
return ( ( sum > 0 )?( log(sum) ):( SMEM_ACT_LOW ) );
}
smem_lti_id smem_lti_get_id ( agent my_agent,
char  name_letter,
uint64_t  name_number 
)

Definition at line 1410 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), smem_statement_container::lti_get, NIL, soar_module::statement::reinitialize(), soar_module::row, smem_attach(), and agent_struct::smem_stmts.

Referenced by _epmem_install_id_wme(), make_symbol_for_current_lexeme(), parse_rhs_action(), smem_lti_soar_add(), and smem_parse_chunks().

{
smem_lti_id return_val = NIL;
// getting lti ids requires an open semantic database
smem_attach( my_agent );
// letter=? AND number=?
my_agent->smem_stmts->lti_get->bind_int( 1, static_cast<uint64_t>( name_letter ) );
my_agent->smem_stmts->lti_get->bind_int( 2, static_cast<uint64_t>( name_number ) );
if ( my_agent->smem_stmts->lti_get->execute() == soar_module::row )
{
return_val = my_agent->smem_stmts->lti_get->column_int( 0 );
}
return return_val;
}
smem_lti_id smem_lti_soar_add ( agent my_agent,
Symbol id 
)
inline

Definition at line 1455 of file semantic_memory.cpp.

References epmem_schedule_promotion(), agent_struct::epmem_stats, agent_struct::epmem_validation, soar_module::primitive_stat< T >::get_value(), symbol_union::id, IDENTIFIER_SYMBOL_TYPE, identifier_struct::name_letter, identifier_struct::name_number, NIL, identifier_struct::smem_lti, smem_lti_add_id(), smem_lti_get_id(), and epmem_stat_container::time.

Referenced by smem_soar_store().

{
if ( ( id->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( id->id.smem_lti == NIL ) )
{
// try to find existing lti
id->id.smem_lti = smem_lti_get_id( my_agent, id->id.name_letter, id->id.name_number );
// if doesn't exist, add
if ( id->id.smem_lti == NIL )
{
id->id.smem_lti = smem_lti_add_id( my_agent, id->id.name_letter, id->id.name_number );
id->id.smem_time_id = my_agent->epmem_stats->time->get_value();
id->id.smem_valid = my_agent->epmem_validation;
epmem_schedule_promotion( my_agent, id );
}
}
return id->id.smem_lti;
}
Symbol* smem_lti_soar_make ( agent my_agent,
smem_lti_id  lti,
char  name_letter,
uint64_t  name_number,
goal_stack_level  level 
)

Definition at line 1478 of file semantic_memory.cpp.

References find_identifier(), symbol_union::id, identifier_struct::level, make_new_identifier(), NIL, identifier_struct::promotion_level, identifier_struct::smem_lti, SMEM_LTI_UNKNOWN_LEVEL, and symbol_add_ref().

Referenced by _epmem_install_id_wme(), make_symbol_for_current_lexeme(), parse_rhs_action(), and smem_install_memory().

{
Symbol *return_val;
// try to find existing
return_val = find_identifier( my_agent, name_letter, name_number );
// otherwise create
if ( return_val == NIL )
{
return_val = make_new_identifier( my_agent, name_letter, level, name_number );
}
else
{
symbol_add_ref( return_val );
if ( ( return_val->id.level == SMEM_LTI_UNKNOWN_LEVEL ) && ( level != SMEM_LTI_UNKNOWN_LEVEL ) )
{
return_val->id.level = level;
return_val->id.promotion_level = level;
}
}
// set lti field irrespective
return_val->id.smem_lti = lti;
return return_val;
}
smem_slot* smem_make_slot ( smem_slot_map slots,
Symbol attr 
)
inline

Definition at line 1541 of file semantic_memory.cpp.

Referenced by smem_parse_chunk(), and smem_soar_store().

{
smem_slot **s =& (*slots)[ attr ];
if ( !(*s) )
{
(*s) = new smem_slot;
}
return (*s);
}
bool smem_parse_chunk ( agent my_agent,
smem_str_to_chunk_map chunks,
smem_chunk_set newbies 
)

Definition at line 2937 of file semantic_memory.cpp.

References AT_LEXEME, FLOAT_CONSTANT_LEXEME, lexeme_info::float_val, get_lexeme(), IDENTIFIER_LEXEME, INT_CONSTANT_LEXEME, lexeme_info::int_val, agent_struct::lexeme, smem_chunk_struct::lti_id, smem_chunk_struct::lti_letter, smem_chunk_struct::lti_number, make_float_constant(), make_int_constant(), make_sym_constant(), sym_constant_struct::name, NIL, PERIOD_LEXEME, R_PAREN_LEXEME, symbol_union::sc, smem_chunk_struct::slots, smem_deallocate_chunk(), smem_make_slot(), smem_parse_constant_attr(), smem_parse_lti_name(), smem_chunk_struct::soar_id, lexeme_info::string, SYM_CONSTANT_LEXEME, SYM_CONSTANT_SYMBOL_TYPE, symbol_remove_ref(), lexeme_info::type, UP_ARROW_LEXEME, smem_chunk_value_union::val_const, smem_chunk_value_union::val_lti, smem_chunk_value_constant::val_type, smem_chunk_value_lti::val_type, smem_chunk_value_constant::val_value, smem_chunk_value_lti::val_value, value_const_t, value_lti_t, and VARIABLE_LEXEME.

Referenced by smem_parse_chunks().

{
bool return_val = false;
smem_chunk *new_chunk = new smem_chunk;
new_chunk->slots = NULL;
std::string *chunk_name = NULL;
char temp_letter;
uint64_t temp_number;
bool good_at;
//
// consume left paren
get_lexeme( my_agent );
if ( ( my_agent->lexeme.type == AT_LEXEME ) || ( my_agent->lexeme.type == IDENTIFIER_LEXEME ) || ( my_agent->lexeme.type == VARIABLE_LEXEME ) )
{
good_at = true;
if ( my_agent->lexeme.type == AT_LEXEME )
{
get_lexeme( my_agent );
good_at = ( my_agent->lexeme.type == IDENTIFIER_LEXEME );
}
if ( good_at )
{
// save identifier
chunk_name = smem_parse_lti_name( &( my_agent->lexeme ), &( temp_letter ), &( temp_number ) );
new_chunk->lti_letter = temp_letter;
new_chunk->lti_number = temp_number;
new_chunk->lti_id = NIL;
new_chunk->soar_id = NIL;
new_chunk->slots = new smem_slot_map;
// consume id
get_lexeme( my_agent );
//
uint64_t intermediate_counter = 1;
smem_chunk *intermediate_parent;
smem_chunk *temp_chunk;
std::string temp_key;
std::string *temp_key2;
Symbol *chunk_attr;
smem_chunk_value *chunk_value;
// populate slots
while ( my_agent->lexeme.type == UP_ARROW_LEXEME )
{
intermediate_parent = new_chunk;
// go on to attribute
get_lexeme( my_agent );
// get the appropriate constant type
chunk_attr = smem_parse_constant_attr( my_agent, &( my_agent->lexeme ) );
// if constant attribute, proceed to value
if ( chunk_attr != NIL )
{
// consume attribute
get_lexeme( my_agent );
// support for dot notation:
// when we encounter a dot, instantiate
// the previous attribute as a temporary
// identifier and use that as the parent
while ( my_agent->lexeme.type == PERIOD_LEXEME )
{
// create a new chunk
temp_chunk = new smem_chunk;
temp_chunk->lti_letter = ( ( chunk_attr->common.symbol_type == SYM_CONSTANT_SYMBOL_TYPE )?( static_cast<char>( static_cast<int>( chunk_attr->sc.name[0] ) ) ):( 'X' ) );
temp_chunk->lti_number = ( intermediate_counter++ );
temp_chunk->lti_id = NIL;
temp_chunk->slots = new smem_slot_map;
temp_chunk->soar_id = NIL;
// add it as a child to the current parent
chunk_value = new smem_chunk_value;
chunk_value->val_lti.val_type = value_lti_t;
chunk_value->val_lti.val_value = temp_chunk;
s = smem_make_slot( intermediate_parent->slots, chunk_attr );
s->push_back( chunk_value );
// create a key guaranteed to be unique
std::string temp_key3;
to_string( temp_chunk->lti_number, temp_key3 );
temp_key.assign( "<" );
temp_key.append( 1, temp_chunk->lti_letter );
temp_key.append( "#" );
temp_key.append( temp_key3 );
temp_key.append( ">" );
// insert the new chunk
(*chunks)[ temp_key ] = temp_chunk;
// definitely a new chunk
newbies->insert( temp_chunk );
// the new chunk is our parent for this set of values (or further dots)
intermediate_parent = temp_chunk;
temp_chunk = NULL;
// get the next attribute
get_lexeme( my_agent );
chunk_attr = smem_parse_constant_attr( my_agent, &( my_agent->lexeme ) );
// consume attribute
get_lexeme( my_agent );
}
if ( chunk_attr != NIL )
{
bool first_value = true;
do
{
// value by type
chunk_value = NIL;
if ( my_agent->lexeme.type == SYM_CONSTANT_LEXEME )
{
chunk_value = new smem_chunk_value;
chunk_value->val_const.val_value = make_sym_constant( my_agent, static_cast<const char *>( my_agent->lexeme.string ) );
}
else if ( my_agent->lexeme.type == INT_CONSTANT_LEXEME )
{
chunk_value = new smem_chunk_value;
chunk_value->val_const.val_value = make_int_constant( my_agent, my_agent->lexeme.int_val );
}
else if ( my_agent->lexeme.type == FLOAT_CONSTANT_LEXEME )
{
chunk_value = new smem_chunk_value;
chunk_value->val_const.val_value = make_float_constant( my_agent, my_agent->lexeme.float_val );
}
else if ( ( my_agent->lexeme.type == AT_LEXEME ) || ( my_agent->lexeme.type == IDENTIFIER_LEXEME ) || ( my_agent->lexeme.type == VARIABLE_LEXEME ) )
{
good_at = true;
if ( my_agent->lexeme.type == AT_LEXEME )
{
get_lexeme( my_agent );
good_at = ( my_agent->lexeme.type == IDENTIFIER_LEXEME );
}
if ( good_at )
{
// create new value
chunk_value = new smem_chunk_value;
chunk_value->val_lti.val_type = value_lti_t;
// get key
temp_key2 = smem_parse_lti_name( &( my_agent->lexeme ), &( temp_letter ), &( temp_number ) );
// search for an existing chunk
smem_str_to_chunk_map::iterator p = chunks->find( (*temp_key2) );
// if exists, point; else create new
if ( p != chunks->end() )
{
chunk_value->val_lti.val_value = p->second;
}
else
{
// create new chunk
temp_chunk = new smem_chunk;
temp_chunk->lti_id = NIL;
temp_chunk->lti_letter = temp_letter;
temp_chunk->lti_number = temp_number;
temp_chunk->lti_id = NIL;
temp_chunk->slots = NIL;
temp_chunk->soar_id = NIL;
// associate with value
chunk_value->val_lti.val_value = temp_chunk;
// add to chunks
(*chunks)[ (*temp_key2) ] = temp_chunk;
// possibly a newbie (could be a self-loop)
newbies->insert( temp_chunk );
}
delete temp_key2;
}
}
if ( chunk_value != NIL )
{
// consume
get_lexeme( my_agent );
// add to appropriate slot
s = smem_make_slot( intermediate_parent->slots, chunk_attr );
if ( first_value && !s->empty() )
{
// in the case of a repeated attribute, remove ref here to avoid leak
symbol_remove_ref( my_agent, chunk_attr );
}
s->push_back( chunk_value );
// if this was the last attribute
if ( my_agent->lexeme.type == R_PAREN_LEXEME )
{
return_val = true;
get_lexeme( my_agent );
chunk_value = NIL;
}
first_value = false;
}
} while ( chunk_value != NIL );
}
}
}
}
else
{
delete new_chunk;
}
}
else
{
delete new_chunk;
}
if ( return_val )
{
// search for an existing chunk (occurs if value comes before id)
smem_chunk **p =& (*chunks)[ (*chunk_name ) ];
if ( !(*p) )
{
(*p) = new_chunk;
// a newbie!
newbies->insert( new_chunk );
}
else
{
// transfer slots
if ( !(*p)->slots )
{
// if none previously, can just use
(*p)->slots = new_chunk->slots;
new_chunk->slots = NULL;
}
else
{
// otherwise, copy
smem_slot_map::iterator ss_p;
smem_slot::iterator s_p;
smem_slot *source_slot;
smem_slot *target_slot;
// for all slots
for ( ss_p=new_chunk->slots->begin(); ss_p!=new_chunk->slots->end(); ss_p++ )
{
target_slot = smem_make_slot( (*p)->slots, ss_p->first );
source_slot = ss_p->second;
// for all values in the slot
for ( s_p=source_slot->begin(); s_p!=source_slot->end(); s_p++ )
{
// copy each value
target_slot->push_back( (*s_p) );
}
// once copied, we no longer need the slot
delete source_slot;
}
// we no longer need the slots
delete new_chunk->slots;
new_chunk->slots = NULL;
}
// contents are new
newbies->insert( (*p) );
// deallocate
smem_deallocate_chunk( my_agent, new_chunk );
}
}
else
{
newbies->clear();
}
// de-allocate id name
if ( chunk_name )
{
delete chunk_name;
}
return return_val;
}
bool smem_parse_chunks ( agent my_agent,
const char *  chunks_str,
std::string **  err_msg 
)

Definition at line 3248 of file semantic_memory.cpp.

References agent_struct::alternate_input_exit, agent_struct::alternate_input_string, agent_struct::alternate_input_suffix, agent_struct::current_char, epmem_schedule_promotion(), agent_struct::epmem_stats, agent_struct::epmem_validation, find_identifier(), get_lexeme(), soar_module::primitive_stat< T >::get_value(), symbol_union::id, agent_struct::id_counter, L_PAREN_LEXEME, agent_struct::lexeme, NIL, set_lexer_allow_ids(), smem_attach(), smem_deallocate_chunk(), identifier_struct::smem_lti, smem_lti_add_id(), smem_lti_get_id(), smem_parse_chunk(), smem_store_chunk(), identifier_struct::smem_time_id, identifier_struct::smem_valid, epmem_stat_container::time, and lexeme_info::type.

{
bool return_val = false;
uint64_t clause_count = 0;
// parsing chunks requires an open semantic database
smem_attach( my_agent );
// copied primarily from cli_sp
my_agent->alternate_input_string = chunks_str;
my_agent->alternate_input_suffix = const_cast<char *>( ") " );
my_agent->current_char = ' ';
my_agent->alternate_input_exit = true;
set_lexer_allow_ids( my_agent, true );
bool good_chunk = true;
smem_str_to_chunk_map::iterator c_old;
smem_chunk_set newbies;
smem_chunk_set::iterator c_new;
// consume next token
get_lexeme( my_agent );
// while there are chunks to consume
while ( ( my_agent->lexeme.type == L_PAREN_LEXEME ) && ( good_chunk ) )
{
good_chunk = smem_parse_chunk( my_agent, &( chunks ), &( newbies ) );
if ( good_chunk )
{
// add all newbie lti's as appropriate
for ( c_new=newbies.begin(); c_new!=newbies.end(); c_new++ )
{
if ( (*c_new)->lti_id == NIL )
{
// deal differently with variable vs. lti
if ( (*c_new)->lti_number == NIL )
{
// add a new lti id (we have a guarantee this won't be in Soar's WM)
(*c_new)->lti_number = ( my_agent->id_counter[ (*c_new)->lti_letter - static_cast<char>('A') ]++ );
(*c_new)->lti_id = smem_lti_add_id( my_agent, (*c_new)->lti_letter, (*c_new)->lti_number );
}
else
{
// should ALWAYS be the case (it's a newbie and we've initialized lti_id to NIL)
if ( (*c_new)->lti_id == NIL )
{
// get existing
(*c_new)->lti_id = smem_lti_get_id( my_agent, (*c_new)->lti_letter, (*c_new)->lti_number );
// if doesn't exist, add it
if ( (*c_new)->lti_id == NIL )
{
(*c_new)->lti_id = smem_lti_add_id( my_agent, (*c_new)->lti_letter, (*c_new)->lti_number );
// this could affect an existing identifier in Soar's WM
Symbol *id_parent = find_identifier( my_agent, (*c_new)->lti_letter, (*c_new)->lti_number );
if ( id_parent != NIL )
{
// if so we make it an lti manually
id_parent->id.smem_lti = (*c_new)->lti_id;
id_parent->id.smem_time_id = my_agent->epmem_stats->time->get_value();
id_parent->id.smem_valid = my_agent->epmem_validation;
epmem_schedule_promotion( my_agent, id_parent );
}
}
}
}
}
}
// add all newbie contents (append, as opposed to replace, children)
for ( c_new=newbies.begin(); c_new!=newbies.end(); c_new++ )
{
if ( (*c_new)->slots != NIL )
{
smem_store_chunk( my_agent, (*c_new)->lti_id, (*c_new)->slots, false );
}
}
// deallocate *contents* of all newbies (need to keep around name->id association for future chunks)
for ( c_new=newbies.begin(); c_new!=newbies.end(); c_new++ )
{
smem_deallocate_chunk( my_agent, (*c_new), false );
}
// increment clause counter
clause_count++;
// clear newbie list
newbies.clear();
}
};
return_val = good_chunk;
// deallocate all chunks
{
for ( c_old=chunks.begin(); c_old!=chunks.end(); c_old++ )
{
smem_deallocate_chunk( my_agent, c_old->second, true );
}
}
// produce error message on failure
if ( !return_val )
{
std::string num;
to_string( clause_count, num );
(*err_msg) = new std::string( "Error parsing clause #" );
(*err_msg)->append( num );
}
return return_val;
}
Symbol* smem_parse_constant_attr ( agent my_agent,
struct lexeme_info lexeme 
)
inline

Definition at line 2917 of file semantic_memory.cpp.

References FLOAT_CONSTANT_LEXEME, INT_CONSTANT_LEXEME, make_float_constant(), make_int_constant(), make_sym_constant(), NIL, and SYM_CONSTANT_LEXEME.

Referenced by smem_parse_chunk().

{
Symbol *return_val = NIL;
if ( (*lexeme).type == SYM_CONSTANT_LEXEME )
{
return_val = make_sym_constant( my_agent, static_cast<const char *>( (*lexeme).string ) );
}
else if ( (*lexeme).type == INT_CONSTANT_LEXEME )
{
return_val = make_int_constant( my_agent, (*lexeme).int_val );
}
else if ( (*lexeme).type == FLOAT_CONSTANT_LEXEME )
{
return_val = make_float_constant( my_agent, (*lexeme).float_val );
}
return return_val;
}
std::string* smem_parse_lti_name ( struct lexeme_info lexeme,
char *  id_letter,
uint64_t *  id_number 
)
inline

Definition at line 2891 of file semantic_memory.cpp.

References IDENTIFIER_LEXEME.

Referenced by smem_parse_chunk().

{
std::string *return_val = new std::string;
if ( (*lexeme).type == IDENTIFIER_LEXEME )
{
std::string num;
to_string( (*lexeme).id_number, num );
return_val->append( 1, (*lexeme).id_letter );
return_val->append( num );
(*id_letter) = (*lexeme).id_letter;
(*id_number) = (*lexeme).id_number;
}
else
{
return_val->assign( (*lexeme).string );
(*id_letter) = static_cast<char>( toupper( (*lexeme).string[1] ) );
(*id_number) = 0;
}
return return_val;
}
void smem_print_lti ( agent my_agent,
smem_lti_id  lti_id,
unsigned int  depth,
std::string *  return_val 
)

Definition at line 4501 of file semantic_memory.cpp.

References _smem_print_lti(), soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_double(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), smem_statement_container::lti_letter_num, soar_module::statement::reinitialize(), smem_attach(), agent_struct::smem_stmts, and smem_statement_container::vis_lti_act.

{
std::set< smem_lti_id > visited;
std::pair< std::set< smem_lti_id >::iterator, bool > visited_ins_result;
std::queue< std::pair< smem_lti_id, unsigned int > > to_visit;
std::pair< smem_lti_id, unsigned int > c;
std::set< smem_lti_id > next;
std::set< smem_lti_id >::iterator next_it;
unsigned int i;
// vizualizing the store requires an open semantic database
smem_attach( my_agent );
// initialize queue/set
to_visit.push( std::make_pair< smem_lti_id, unsigned int >( lti_id, 1 ) );
visited.insert( lti_id );
while ( !to_visit.empty() )
{
c = to_visit.front();
to_visit.pop();
// output leading spaces ala depth
for ( i=1; i<c.second; i++ )
{
return_val->append( " " );
}
// get lti info
{
lti_q->bind_int( 1, c.first );
lti_q->execute();
act_q->bind_int( 1, c.first );
act_q->execute();
next = _smem_print_lti( my_agent, c.first, static_cast<char>( lti_q->column_int( 0 ) ), static_cast<uint64_t>( lti_q->column_int( 1 ) ), act_q->column_double( 0 ), return_val );
// done with lookup
lti_q->reinitialize();
act_q->reinitialize();
// consider further depth
if ( c.second < depth )
{
for ( next_it=next.begin(); next_it!=next.end(); next_it++ )
{
visited_ins_result = visited.insert( (*next_it) );
if ( visited_ins_result.second )
{
to_visit.push( std::make_pair< smem_lti_id, unsigned int >( (*next_it), c.second+1 ) );
}
}
}
}
}
}
void smem_print_store ( agent my_agent,
std::string *  return_val 
)

Definition at line 4487 of file semantic_memory.cpp.

References _smem_print_lti(), soar_module::sqlite_statement::column_double(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), soar_module::statement::reinitialize(), soar_module::row, smem_attach(), agent_struct::smem_stmts, and smem_statement_container::vis_lti.

{
// vizualizing the store requires an open semantic database
smem_attach( my_agent );
// id, letter, number
while ( q->execute() == soar_module::row )
{
_smem_print_lti( my_agent, q->column_int( 0 ), static_cast<char>( q->column_int( 1 ) ), static_cast<uint64_t>( q->column_int( 2 ) ), q->column_double( 3 ), return_val );
}
}
void smem_process_buffered_wmes ( agent my_agent,
Symbol state,
soar_module::wme_set cue_wmes,
soar_module::symbol_triple_list meta_wmes,
soar_module::symbol_triple_list retrieval_wmes 
)
inline

Definition at line 750 of file semantic_memory.cpp.

References _smem_process_buffered_wme_list().

Referenced by smem_respond_to_cmd().

{
_smem_process_buffered_wme_list( my_agent, state, cue_wmes, meta_wmes, true );
_smem_process_buffered_wme_list( my_agent, state, cue_wmes, retrieval_wmes, false );
}
smem_lti_id smem_process_query ( agent my_agent,
Symbol state,
Symbol query,
Symbol negquery,
smem_lti_set prohibit,
soar_module::wme_set cue_wmes,
soar_module::symbol_triple_list meta_wmes,
soar_module::symbol_triple_list retrieval_wmes,
smem_query_levels  query_level = qry_full 
)

Definition at line 2240 of file semantic_memory.cpp.

References _smem_process_cue_wme(), smem_param_container::act_base, smem_statement_container::act_lti_get, smem_param_container::activate_on_query, smem_param_container::activation_mode, attr_t, smem_param_container::base_update, soar_module::sqlite_statement::bind_int(), smem_param_container::bupt_naive, soar_module::sqlite_statement::column_double(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), soar_module::constant_param< T >::get_value(), symbol_union::id, NIL, soar_module::on, soar_module::op_reinit, qry_full, smem_timer_container::query, soar_module::statement::reinitialize(), soar_module::row, SMEM_ACT_MAX, smem_buffer_add_wme(), smem_get_direct_augs_of_id(), smem_install_memory(), smem_lti_activate(), agent_struct::smem_params, identifier_struct::smem_result_header, smem_setup_web_crawl(), agent_struct::smem_stmts, agent_struct::smem_sym_failure, agent_struct::smem_sym_success, agent_struct::smem_timers, soar_module::timer::start(), soar_module::timer::stop(), value_const_t, value_lti_t, smem_statement_container::web_attr_child, smem_statement_container::web_const_child, and smem_statement_container::web_lti_child.

Referenced by smem_respond_to_cmd().

{
smem_weighted_cue_list weighted_cue;
bool good_cue = true;
smem_lti_id king_id = NIL;
my_agent->smem_timers->query->start();
// prepare query stats
{
// positive cue - always
{
if ( cue->empty() )
{
good_cue = false;
}
for ( smem_wme_list::iterator cue_p=cue->begin(); cue_p!=cue->end(); cue_p++ )
{
cue_wmes.insert( (*cue_p) );
if ( good_cue )
{
good_cue = _smem_process_cue_wme( my_agent, (*cue_p), true, weighted_pq );
}
}
delete cue;
}
// negative cue - if present
if ( negquery )
{
for ( smem_wme_list::iterator cue_p=cue->begin(); cue_p!=cue->end(); cue_p++ )
{
cue_wmes.insert( (*cue_p) );
if ( good_cue )
{
good_cue = _smem_process_cue_wme( my_agent, (*cue_p), false, weighted_pq );
}
}
delete cue;
}
// if valid cue, transfer priority queue to list
if ( good_cue )
{
while ( !weighted_pq.empty() )
{
weighted_cue.push_back( weighted_pq.top() );
weighted_pq.pop();
}
}
// else deallocate priority queue contents
else
{
while ( !weighted_pq.empty() )
{
delete weighted_pq.top();
weighted_pq.pop();
}
}
}
// only search if the cue was valid
if ( good_cue && !weighted_cue.empty() )
{
// by definition, the first positive-cue element dictates the candidate set
smem_weighted_cue_list::iterator cand_set;
smem_weighted_cue_list::iterator next_element;
for ( next_element=weighted_cue.begin(); next_element!=weighted_cue.end(); next_element++ )
{
if ( (*next_element)->pos_element )
{
cand_set = next_element;
break;
}
}
smem_lti_set::iterator prohibit_p;
bool good_cand;
{
// naive base-level updates means update activation of
// every candidate in the minimal list before the
// confirmation walk
{
q = smem_setup_web_crawl( my_agent, (*cand_set) );
// queue up distinct lti's to update
// - set because queries could contain wilds
// - not in loop because the effects of activation may actually
// alter the resultset of the query (isolation???)
std::set< smem_lti_id > to_update;
while ( q->execute() == soar_module::row )
{
to_update.insert( q->column_int(0) );
}
for ( std::set< smem_lti_id >::iterator it=to_update.begin(); it!=to_update.end(); it++ )
{
smem_lti_activate( my_agent, (*it), false );
}
}
}
// setup first query, which is sorted on activation already
q = smem_setup_web_crawl( my_agent, (*cand_set) );
// this becomes the minimal set to walk (till match or fail)
if ( q->execute() == soar_module::row )
{
bool more_rows = true;
bool use_db = false;
bool has_feature = false;
while ( more_rows && ( q->column_double( 1 ) == static_cast<double>( SMEM_ACT_MAX ) ) )
{
my_agent->smem_stmts->act_lti_get->bind_int( 1, q->column_int( 0 ) );
my_agent->smem_stmts->act_lti_get->execute();
plentiful_parents.push( std::make_pair< double, smem_lti_id >( my_agent->smem_stmts->act_lti_get->column_double( 0 ), q->column_int( 0 ) ) );
more_rows = ( q->execute() == soar_module::row );
}
while ( ( king_id == NIL ) && ( ( more_rows ) || ( !plentiful_parents.empty() ) ) )
{
// choose next candidate (db vs. priority queue)
{
use_db = false;
if ( !more_rows )
{
use_db = false;
}
else if ( plentiful_parents.empty() )
{
use_db = true;
}
else
{
use_db = ( q->column_double( 1 ) > plentiful_parents.top().first );
}
if ( use_db )
{
cand = q->column_int( 0 );
more_rows = ( q->execute() == soar_module::row );
}
else
{
cand = plentiful_parents.top().second;
plentiful_parents.pop();
}
}
// if not prohibited, submit to the remaining cue elements
prohibit_p = prohibit->find( cand );
if ( prohibit_p == prohibit->end() )
{
good_cand = true;
for ( next_element=weighted_cue.begin(); next_element!=weighted_cue.end(); next_element++ )
{
// don't need to check the generating list
if ( (*next_element) == (*cand_set) )
{
continue;
}
if ( (*next_element)->element_type == attr_t )
{
// parent=? AND attr=?
q2 = my_agent->smem_stmts->web_attr_child;
}
else if ( (*next_element)->element_type == value_const_t )
{
// parent=? AND attr=? AND val_const=?
q2 = my_agent->smem_stmts->web_const_child;
q2->bind_int( 3, (*next_element)->value_hash );
}
else if ( (*next_element)->element_type == value_lti_t )
{
// parent=? AND attr=? AND val_lti=?
q2 = my_agent->smem_stmts->web_lti_child;
q2->bind_int( 3, (*next_element)->value_lti );
}
// all require own id, attribute
q2->bind_int( 1, cand );
q2->bind_int( 2, (*next_element)->attr_hash );
has_feature = ( q2->execute( soar_module::op_reinit ) == soar_module::row );
good_cand = ( ( (*next_element)->pos_element )?( has_feature ):( !has_feature ) );
if ( !good_cand )
{
break;
}
}
if ( good_cand )
{
king_id = cand;
}
}
}
}
q->reinitialize();
// clean weighted cue
for ( next_element=weighted_cue.begin(); next_element!=weighted_cue.end(); next_element++ )
{
delete (*next_element);
}
}
// reconstruction depends upon level
if ( query_level == qry_full )
{
// produce results
if ( king_id != NIL )
{
// success!
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_success, query );
if ( negquery )
{
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_success, negquery );
}
my_agent->smem_timers->query->stop();
smem_install_memory( my_agent, state, king_id, NIL, ( my_agent->smem_params->activate_on_query->get_value() == soar_module::on ), meta_wmes, retrieval_wmes );
}
else
{
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_failure, query );
if ( negquery )
{
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_failure, negquery );
}
my_agent->smem_timers->query->stop();
}
}
else
{
my_agent->smem_timers->query->stop();
}
return king_id;
}
void smem_reset ( agent my_agent,
Symbol state 
)

Definition at line 2543 of file semantic_memory.cpp.

References symbol_union::id, smem_data_struct::last_cmd_count, smem_data_struct::last_cmd_time, identifier_struct::lower_goal, identifier_struct::smem_info, smem_data_struct::smem_wmes, and agent_struct::top_goal.

Referenced by remove_existing_context_and_descendents().

{
if ( state == NULL )
{
state = my_agent->top_goal;
}
while( state )
{
smem_data *data = state->id.smem_info;
data->last_cmd_time[0] = 0;
data->last_cmd_time[1] = 0;
data->last_cmd_count[0] = 0;
data->last_cmd_count[1] = 0;
// this will be called after prefs from goal are already removed,
// so just clear out result stack
data->smem_wmes->clear();
state = state->id.lower_goal;
}
}
void smem_reset_id_counters ( agent my_agent)

Definition at line 1507 of file semantic_memory.cpp.

References soar_module::sqlite_statement::column_int(), soar_module::connected, soar_module::statement::execute(), soar_module::status_object< T >::get_status(), agent_struct::id_counter, smem_statement_container::lti_max, soar_module::statement::reinitialize(), soar_module::row, agent_struct::smem_db, and agent_struct::smem_stmts.

Referenced by reset_id_counters(), and smem_init_db().

{
if ( my_agent->smem_db->get_status() == soar_module::connected )
{
// letter, max
while ( my_agent->smem_stmts->lti_max->execute() == soar_module::row )
{
uint64_t name_letter = static_cast<uint64_t>( my_agent->smem_stmts->lti_max->column_int( 0 ) );
uint64_t letter_max = static_cast<uint64_t>( my_agent->smem_stmts->lti_max->column_int( 1 ) );
// shift to alphabet
name_letter -= static_cast<uint64_t>( 'A' );
// get count
uint64_t *letter_ct =& my_agent->id_counter[ name_letter ];
// adjust if necessary
if ( (*letter_ct) <= letter_max )
{
(*letter_ct) = ( letter_max + 1 );
}
}
}
}
void smem_respond_to_cmd ( agent my_agent,
bool  store_only 
)

Definition at line 3376 of file semantic_memory.cpp.

References smem_timer_container::api, smem_statement_container::begin, agent_struct::bottom_goal, smem_stat_container::cbr, smem_statement_container::commit, do_working_memory_phase(), soar_module::statement::execute(), smem_stat_container::expansions, get_new_tc_number(), soar_module::constant_param< T >::get_value(), soar_module::primitive_stat< T >::get_value(), identifier_struct::higher_goal, symbol_union::id, IDENTIFIER_SYMBOL_TYPE, smem_data_struct::last_cmd_count, smem_data_struct::last_cmd_time, smem_param_container::lazy_commit, smem_param_container::mirroring, smem_stat_container::mirrors, NIL, soar_module::off, soar_module::on, soar_module::op_reinit, soar_module::primitive_stat< T >::set_value(), smem_attach(), smem_buffer_add_wme(), agent_struct::smem_changed_ids, smem_clear_result(), identifier_struct::smem_cmd_header, smem_get_direct_augs_of_id(), agent_struct::smem_ignore_changes, identifier_struct::smem_info, smem_install_memory(), identifier_struct::smem_lti, agent_struct::smem_params, smem_process_buffered_wmes(), smem_process_query(), identifier_struct::smem_result_header, smem_soar_store(), agent_struct::smem_stats, agent_struct::smem_stmts, agent_struct::smem_sym_bad_cmd, agent_struct::smem_sym_failure, agent_struct::smem_sym_negquery, agent_struct::smem_sym_prohibit, agent_struct::smem_sym_query, agent_struct::smem_sym_retrieve, agent_struct::smem_sym_store, agent_struct::smem_sym_success, agent_struct::smem_timers, soar_module::timer::start(), soar_module::timer::stop(), smem_timer_container::storage, store_level, store_recursive, smem_stat_container::stores, and symbol_remove_ref().

Referenced by smem_go().

{
// start at the bottom and work our way up
// (could go in the opposite direction as well)
Symbol *state = my_agent->bottom_goal;
smem_wme_list::iterator w_p;
Symbol *query;
Symbol *negquery;
Symbol *retrieve;
smem_sym_list prohibit;
enum path_type { blank_slate, cmd_bad, cmd_retrieve, cmd_query, cmd_store } path;
unsigned int time_slot = ( ( store_only )?(1):(0) );
uint64_t wme_count;
bool new_cue;
tc_number tc;
Symbol *parent_sym;
std::queue<Symbol *> syms;
int parent_level;
std::queue<int> levels;
bool do_wm_phase = false;
bool mirroring_on = ( my_agent->smem_params->mirroring->get_value() == soar_module::on );
//
while ( state != NULL )
{
my_agent->smem_timers->api->start();
// make sure this state has had some sort of change to the cmd
// NOTE: we only care one-level deep!
new_cue = false;
wme_count = 0;
cmds = NIL;
{
tc = get_new_tc_number( my_agent );
// initialize BFS at command
syms.push( state->id.smem_cmd_header );
levels.push( 0 );
while ( !syms.empty() )
{
// get state
parent_sym = syms.front();
syms.pop();
parent_level = levels.front();
levels.pop();
// get children of the current identifier
wmes = smem_get_direct_augs_of_id( parent_sym, tc );
{
for ( w_p=wmes->begin(); w_p!=wmes->end(); w_p++ )
{
if ( ( ( store_only ) && ( ( parent_level != 0 ) || ( (*w_p)->attr == my_agent->smem_sym_store ) ) ) ||
( ( !store_only ) && ( ( parent_level != 0 ) || ( (*w_p)->attr != my_agent->smem_sym_store ) ) ) )
{
wme_count++;
if ( (*w_p)->timetag > state->id.smem_info->last_cmd_time[ time_slot ] )
{
new_cue = true;
state->id.smem_info->last_cmd_time[ time_slot ] = (*w_p)->timetag;
}
if ( ( (*w_p)->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( parent_level == 0 ) &&
( ( (*w_p)->attr == my_agent->smem_sym_query ) || ( (*w_p)->attr == my_agent->smem_sym_store ) ) )
{
syms.push( (*w_p)->value );
levels.push( parent_level + 1 );
}
}
}
// free space from aug list
if ( cmds == NIL )
{
cmds = wmes;
}
else
{
delete wmes;
}
}
}
// see if any WMEs were removed
if ( state->id.smem_info->last_cmd_count[ time_slot ] != wme_count )
{
new_cue = true;
state->id.smem_info->last_cmd_count[ time_slot ] = wme_count;
}
if ( new_cue )
{
// clear old results
smem_clear_result( my_agent, state );
do_wm_phase = true;
}
}
// a command is issued if the cue is new
// and there is something on the cue
if ( new_cue && wme_count )
{
cue_wmes.clear();
meta_wmes.clear();
retrieval_wmes.clear();
// initialize command vars
retrieve = NIL;
query = NIL;
negquery = NIL;
store.clear();
prohibit.clear();
path = blank_slate;
// process top-level symbols
for ( w_p=cmds->begin(); w_p!=cmds->end(); w_p++ )
{
cue_wmes.insert( (*w_p) );
if ( path != cmd_bad )
{
// collect information about known commands
if ( (*w_p)->attr == my_agent->smem_sym_retrieve )
{
if ( ( (*w_p)->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( path == blank_slate ) )
{
retrieve = (*w_p)->value;
path = cmd_retrieve;
}
else
{
path = cmd_bad;
}
}
else if ( (*w_p)->attr == my_agent->smem_sym_query )
{
if ( ( (*w_p)->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( ( path == blank_slate ) || ( path == cmd_query ) ) &&
( query == NIL ) )
{
query = (*w_p)->value;
path = cmd_query;
}
else
{
path = cmd_bad;
}
}
else if ( (*w_p)->attr == my_agent->smem_sym_negquery )
{
if ( ( (*w_p)->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( ( path == blank_slate ) || ( path == cmd_query ) ) &&
( negquery == NIL ) )
{
negquery = (*w_p)->value;
path = cmd_query;
}
else
{
path = cmd_bad;
}
}
else if ( (*w_p)->attr == my_agent->smem_sym_prohibit )
{
if ( ( (*w_p)->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( ( path == blank_slate ) || ( path == cmd_query ) ) &&
( (*w_p)->value->id.smem_lti != NIL ) )
{
prohibit.push_back( (*w_p)->value );
path = cmd_query;
}
else
{
path = cmd_bad;
}
}
else if ( (*w_p)->attr == my_agent->smem_sym_store )
{
if ( ( (*w_p)->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) &&
( ( path == blank_slate ) || ( path == cmd_store ) ) )
{
store.push_back( (*w_p)->value );
path = cmd_store;
}
else
{
path = cmd_bad;
}
}
else
{
path = cmd_bad;
}
}
}
// if on path 3 must have query/neg-query
if ( ( path == cmd_query ) && ( query == NULL ) )
{
path = cmd_bad;
}
// must be on a path
if ( path == blank_slate )
{
path = cmd_bad;
}
my_agent->smem_timers->api->stop();
// process command
if ( path != cmd_bad )
{
// performing any command requires an initialized database
smem_attach( my_agent );
// retrieve
if ( path == cmd_retrieve )
{
if ( retrieve->id.smem_lti == NIL )
{
// retrieve is not pointing to an lti!
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_failure, retrieve );
}
else
{
// status: success
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_success, retrieve );
// install memory directly onto the retrieve identifier
smem_install_memory( my_agent, state, retrieve->id.smem_lti, retrieve, true, meta_wmes, retrieval_wmes );
// add one to the expansions stat
my_agent->smem_stats->expansions->set_value( my_agent->smem_stats->expansions->get_value() + 1 );
}
}
// query
else if ( path == cmd_query )
{
smem_lti_set prohibit_lti;
smem_sym_list::iterator sym_p;
for ( sym_p=prohibit.begin(); sym_p!=prohibit.end(); sym_p++ )
{
prohibit_lti.insert( (*sym_p)->id.smem_lti );
}
smem_process_query( my_agent, state, query, negquery, &( prohibit_lti ), cue_wmes, meta_wmes, retrieval_wmes );
// add one to the cbr stat
my_agent->smem_stats->cbr->set_value( my_agent->smem_stats->cbr->get_value() + 1 );
}
else if ( path == cmd_store )
{
smem_sym_list::iterator sym_p;
my_agent->smem_timers->storage->start();
// start transaction (if not lazy)
{
}
for ( sym_p=store.begin(); sym_p!=store.end(); sym_p++ )
{
smem_soar_store( my_agent, (*sym_p), ( ( mirroring_on )?( store_recursive ):( store_level ) ) );
// status: success
smem_buffer_add_wme( meta_wmes, state->id.smem_result_header, my_agent->smem_sym_success, (*sym_p) );
// add one to the store stat
my_agent->smem_stats->stores->set_value( my_agent->smem_stats->stores->get_value() + 1 );
}
// commit transaction (if not lazy)
{
}
my_agent->smem_timers->storage->stop();
}
}
else
{
}
if ( !meta_wmes.empty() || !retrieval_wmes.empty() )
{
// process preference assertion en masse
smem_process_buffered_wmes( my_agent, state, cue_wmes, meta_wmes, retrieval_wmes );
// clear cache
{
soar_module::symbol_triple_list::iterator mw_it;
for ( mw_it=retrieval_wmes.begin(); mw_it!=retrieval_wmes.end(); mw_it++ )
{
symbol_remove_ref( my_agent, (*mw_it)->id );
symbol_remove_ref( my_agent, (*mw_it)->attr );
symbol_remove_ref( my_agent, (*mw_it)->value );
delete (*mw_it);
}
retrieval_wmes.clear();
for ( mw_it=meta_wmes.begin(); mw_it!=meta_wmes.end(); mw_it++ )
{
symbol_remove_ref( my_agent, (*mw_it)->id );
symbol_remove_ref( my_agent, (*mw_it)->attr );
symbol_remove_ref( my_agent, (*mw_it)->value );
delete (*mw_it);
}
meta_wmes.clear();
}
// process wm changes on this state
do_wm_phase = true;
}
// clear cue wmes
cue_wmes.clear();
}
else
{
my_agent->smem_timers->api->stop();
}
// free space from aug list
delete cmds;
state = state->id.higher_goal;
}
if ( store_only && mirroring_on && ( !my_agent->smem_changed_ids->empty() ) )
{
my_agent->smem_timers->storage->start();
// start transaction (if not lazy)
{
}
for ( smem_pooled_symbol_set::iterator it=my_agent->smem_changed_ids->begin(); it!=my_agent->smem_changed_ids->end(); it++ )
{
// require that the lti has at least one augmentation
if ( (*it)->id.slots )
{
smem_soar_store( my_agent, (*it), store_recursive );
// add one to the mirrors stat
my_agent->smem_stats->mirrors->set_value( my_agent->smem_stats->mirrors->get_value() + 1 );
}
symbol_remove_ref( my_agent, (*it) );
}
// commit transaction (if not lazy)
{
}
// clear symbol set
my_agent->smem_changed_ids->clear();
my_agent->smem_timers->storage->stop();
}
if ( do_wm_phase )
{
my_agent->smem_ignore_changes = true;
my_agent->smem_ignore_changes = false;
}
}
Symbol* smem_reverse_hash ( agent my_agent,
byte  sym_type,
smem_hash_id  hash_value 
)
inline

Definition at line 1006 of file semantic_memory.cpp.

References FLOAT_CONSTANT_SYMBOL_TYPE, INT_CONSTANT_SYMBOL_TYPE, make_float_constant(), make_int_constant(), make_sym_constant(), smem_reverse_hash_float(), smem_reverse_hash_int(), smem_reverse_hash_str(), and SYM_CONSTANT_SYMBOL_TYPE.

Referenced by smem_install_memory().

{
Symbol *return_val = NULL;
std::string dest;
switch ( sym_type )
{
smem_reverse_hash_str( my_agent, hash_value, dest );
return_val = make_sym_constant( my_agent, const_cast<char *>( dest.c_str() ) );
break;
return_val = make_int_constant( my_agent, smem_reverse_hash_int( my_agent, hash_value ) );
break;
return_val = make_float_constant( my_agent, smem_reverse_hash_float( my_agent, hash_value ) );
break;
default:
return_val = NULL;
break;
}
return return_val;
}
double smem_reverse_hash_float ( agent my_agent,
smem_hash_id  hash_value 
)
inline
int64_t smem_reverse_hash_int ( agent my_agent,
smem_hash_id  hash_value 
)
inline
void smem_reverse_hash_str ( agent my_agent,
smem_hash_id  hash_value,
std::string &  dest 
)
inline
soar_module::sqlite_statement* smem_setup_web_crawl ( agent my_agent,
smem_weighted_cue_element el 
)
inline

Definition at line 2109 of file semantic_memory.cpp.

References smem_weighted_cue_element_struct::attr_hash, attr_t, soar_module::sqlite_statement::bind_int(), smem_weighted_cue_element_struct::element_type, agent_struct::smem_stmts, value_const_t, smem_weighted_cue_element_struct::value_hash, smem_weighted_cue_element_struct::value_lti, value_lti_t, smem_statement_container::web_attr_all, smem_statement_container::web_const_all, and smem_statement_container::web_lti_all.

Referenced by smem_process_query().

{
// first, point to correct query and setup
// query-specific parameters
if ( el->element_type == attr_t )
{
// attr=?
q = my_agent->smem_stmts->web_attr_all;
}
else if ( el->element_type == value_const_t )
{
// attr=? AND val_const=?
q = my_agent->smem_stmts->web_const_all;
q->bind_int( 2, el->value_hash );
}
else if ( el->element_type == value_lti_t )
{
// attr=? AND val_lti=?
q = my_agent->smem_stmts->web_lti_all;
q->bind_int( 2, el->value_lti );
}
// all require hash as first parameter
q->bind_int( 1, el->attr_hash );
return q;
}
void smem_soar_store ( agent my_agent,
Symbol id,
smem_storage_type  store_type = store_level,
tc_number  tc = (0) 
)

Definition at line 1905 of file semantic_memory.cpp.

References get_new_tc_number(), symbol_union::id, smem_chunk_struct::lti_id, NIL, smem_get_direct_augs_of_id(), identifier_struct::smem_lti, smem_lti_soar_add(), smem_make_slot(), smem_store_chunk(), smem_symbol_is_constant(), store_recursive, smem_chunk_value_union::val_const, smem_chunk_value_union::val_lti, smem_chunk_value_constant::val_type, smem_chunk_value_lti::val_type, smem_chunk_value_constant::val_value, smem_chunk_value_lti::val_value, value_const_t, and value_lti_t.

Referenced by smem_respond_to_cmd().

{
// transitive closure only matters for recursive storage
if ( ( store_type == store_recursive ) && ( tc == NIL ) )
{
tc = get_new_tc_number( my_agent );
}
smem_sym_list shorties;
// get level
smem_wme_list::iterator w;
// make the target an lti, so intermediary data structure has lti_id
// (takes care of short-term id self-referencing)
smem_lti_soar_add( my_agent, id );
// encode this level
{
smem_sym_to_chunk_map sym_to_chunk;
smem_sym_to_chunk_map::iterator c_p;
smem_slot_map::iterator s_p;
smem_slot::iterator v_p;
for ( w=children->begin(); w!=children->end(); w++ )
{
// get slot
s = smem_make_slot( &( slots ), (*w)->attr );
// create value, per type
if ( smem_symbol_is_constant( (*w)->value ) )
{
v->val_const.val_value = (*w)->value;
}
else
{
// try to find existing chunk
c =& sym_to_chunk[ (*w)->value ];
// if doesn't exist, add; else use existing
if ( !(*c) )
{
(*c) = new smem_chunk;
(*c)->lti_id = (*w)->value->id.smem_lti;
(*c)->lti_letter = (*w)->value->id.name_letter;
(*c)->lti_number = (*w)->value->id.name_number;
(*c)->slots = NULL;
(*c)->soar_id = (*w)->value;
// only traverse to short-term identifiers
if ( ( store_type == store_recursive ) && ( (*c)->lti_id == NIL ) )
{
shorties.push_back( (*c)->soar_id );
}
}
v->val_lti.val_value = (*c);
}
// add value to slot
s->push_back( v );
}
smem_store_chunk( my_agent, id->id.smem_lti, &( slots ), true, id );
// clean up
{
// de-allocate slots
for ( s_p=slots.begin(); s_p!=slots.end(); s_p++ )
{
for ( v_p=s_p->second->begin(); v_p!=s_p->second->end(); v_p++ )
{
delete (*v_p);
}
delete s_p->second;
}
// de-allocate chunks
for ( c_p=sym_to_chunk.begin(); c_p!=sym_to_chunk.end(); c_p++ )
{
delete c_p->second;
}
delete children;
}
}
// recurse as necessary
for ( smem_sym_list::iterator shorty=shorties.begin(); shorty!=shorties.end(); shorty++ )
{
smem_soar_store( my_agent, (*shorty), store_recursive, tc );
}
}
void smem_store_chunk ( agent my_agent,
smem_lti_id  parent_id,
smem_slot_map children,
bool  remove_old_children = true,
Symbol print_id = NULL 
)

Definition at line 1611 of file semantic_memory.cpp.

References smem_statement_container::act_lti_child_ct_get, smem_statement_container::act_lti_child_ct_set, smem_statement_container::act_set, soar_module::sqlite_statement::bind_double(), soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), smem_statement_container::ct_attr_add, smem_statement_container::ct_attr_check, smem_statement_container::ct_attr_update, smem_statement_container::ct_const_add, smem_statement_container::ct_const_check, smem_statement_container::ct_const_update, smem_statement_container::ct_lti_add, smem_statement_container::ct_lti_check, smem_statement_container::ct_lti_update, epmem_schedule_promotion(), agent_struct::epmem_stats, agent_struct::epmem_validation, soar_module::statement::execute(), soar_module::primitive_param< T >::get_value(), soar_module::primitive_stat< T >::get_value(), NIL, soar_module::op_reinit, print(), soar_module::statement::reinitialize(), soar_module::row, soar_module::primitive_stat< T >::set_value(), smem_stat_container::slots, SMEM_ACT_MAX, smem_disconnect_chunk(), smem_lti_activate(), smem_lti_add_id(), agent_struct::smem_params, agent_struct::smem_stats, agent_struct::smem_stmts, smem_temporal_hash(), SMEM_WEB_NULL, snprintf_with_symbols(), agent_struct::sysparams, smem_param_container::thresh, epmem_stat_container::time, TRACE_SMEM_SYSPARAM, value_const_t, smem_statement_container::web_add, smem_statement_container::web_attr_child, smem_statement_container::web_const_child, smem_statement_container::web_lti_child, and xml_generate_warning().

Referenced by smem_parse_chunks(), and smem_soar_store().

{
// if remove children, disconnect chunk -> no existing edges
// else, need to query number of existing edges
uint64_t existing_edges = 0;
if ( remove_old_children )
{
smem_disconnect_chunk( my_agent, parent_id );
// provide trace output
if ( my_agent->sysparams[ TRACE_SMEM_SYSPARAM ] && ( print_id ) )
{
char buf[256];
snprintf_with_symbols( my_agent, buf, 256, "<=SMEM: (%y ^* *)\n", print_id );
print( my_agent, buf );
xml_generate_warning( my_agent, buf );
}
}
else
{
my_agent->smem_stmts->act_lti_child_ct_get->bind_int( 1, parent_id );
existing_edges = static_cast<uint64_t>( my_agent->smem_stmts->act_lti_child_ct_get->column_int(0) );
}
// get new edges
// if didn't disconnect, entails lookups in existing edges
std::set<smem_hash_id> attr_new;
std::set< std::pair<smem_hash_id, smem_hash_id> > const_new;
std::set< std::pair<smem_hash_id, smem_lti_id> > lti_new;
{
smem_slot_map::iterator s;
smem_slot::iterator v;
smem_hash_id attr_hash = 0;
smem_hash_id value_hash = 0;
smem_lti_id value_lti = 0;
for ( s=children->begin(); s!=children->end(); s++ )
{
attr_hash = smem_temporal_hash( my_agent, s->first );
if ( remove_old_children )
{
attr_new.insert( attr_hash );
}
else
{
// parent_id, attr
my_agent->smem_stmts->web_attr_child->bind_int( 1, parent_id );
my_agent->smem_stmts->web_attr_child->bind_int( 2, attr_hash );
{
attr_new.insert( attr_hash );
}
}
for ( v=s->second->begin(); v!=s->second->end(); v++ )
{
if ( (*v)->val_const.val_type == value_const_t )
{
value_hash = smem_temporal_hash( my_agent, (*v)->val_const.val_value );
if ( remove_old_children )
{
const_new.insert( std::make_pair< smem_hash_id, smem_hash_id >( attr_hash, value_hash ) );
}
else
{
// parent_id, attr, val_const
my_agent->smem_stmts->web_const_child->bind_int( 1, parent_id );
my_agent->smem_stmts->web_const_child->bind_int( 2, attr_hash );
my_agent->smem_stmts->web_const_child->bind_int( 3, value_hash );
{
const_new.insert( std::make_pair< smem_hash_id, smem_hash_id >( attr_hash, value_hash ) );
}
}
// provide trace output
if ( my_agent->sysparams[ TRACE_SMEM_SYSPARAM ] && ( print_id ) )
{
char buf[256];
snprintf_with_symbols( my_agent, buf, 256, "=>SMEM: (%y ^%y %y)\n", print_id, s->first, (*v)->val_const.val_value );
print( my_agent, buf );
xml_generate_warning( my_agent, buf );
}
}
else
{
value_lti = (*v)->val_lti.val_value->lti_id;
if ( value_lti == NIL )
{
value_lti = smem_lti_add_id( my_agent, (*v)->val_lti.val_value->lti_letter, (*v)->val_lti.val_value->lti_number );
(*v)->val_lti.val_value->lti_id = value_lti;
if ( (*v)->val_lti.val_value->soar_id != NIL )
{
(*v)->val_lti.val_value->soar_id->id.smem_lti = value_lti;
(*v)->val_lti.val_value->soar_id->id.smem_time_id = my_agent->epmem_stats->time->get_value();
(*v)->val_lti.val_value->soar_id->id.smem_valid = my_agent->epmem_validation;
epmem_schedule_promotion( my_agent, (*v)->val_lti.val_value->soar_id );
}
}
if ( remove_old_children )
{
lti_new.insert( std::make_pair< smem_hash_id, smem_lti_id >( attr_hash, value_lti ) );
}
else
{
// parent_id, attr, val_lti
my_agent->smem_stmts->web_lti_child->bind_int( 1, parent_id );
my_agent->smem_stmts->web_lti_child->bind_int( 2, attr_hash );
my_agent->smem_stmts->web_lti_child->bind_int( 3, value_lti );
{
lti_new.insert( std::make_pair< smem_hash_id, smem_lti_id >( attr_hash, value_lti ) );
}
}
// provide trace output
if ( my_agent->sysparams[ TRACE_SMEM_SYSPARAM ] && ( print_id ) )
{
char buf[256];
snprintf_with_symbols( my_agent, buf, 256, "=>SMEM: (%y ^%y %y)\n", print_id, s->first, (*v)->val_lti.val_value->soar_id );
print( my_agent, buf );
xml_generate_warning( my_agent, buf );
}
}
}
}
}
// activation function assumes proper thresholding state
// thus, consider four cases of augmentation counts (w.r.t. thresh)
// 1. before=below, after=below: good (activation will update web)
// 2. before=below, after=above: need to update web->inf
// 3. before=after, after=below: good (activation will update web, free transition)
// 4. before=after, after=after: good (activation won't touch web)
//
// hence, we detect + handle case #2 here
uint64_t new_edges = ( existing_edges + const_new.size() + lti_new.size() );
bool after_above;
double web_act = static_cast<double>( SMEM_ACT_MAX );
{
uint64_t thresh = static_cast<uint64_t>( my_agent->smem_params->thresh->get_value() );
after_above = ( new_edges >= thresh );
// if before below
if ( existing_edges < thresh )
{
if ( after_above )
{
// update web to inf
my_agent->smem_stmts->act_set->bind_double( 1, web_act );
my_agent->smem_stmts->act_set->bind_int( 2, parent_id );
}
}
}
// update edge counter
{
my_agent->smem_stmts->act_lti_child_ct_set->bind_int( 1, new_edges );
my_agent->smem_stmts->act_lti_child_ct_set->bind_int( 2, parent_id );
}
// now we can safely activate the lti
{
double lti_act = smem_lti_activate( my_agent, parent_id, true, new_edges );
if ( !after_above )
{
web_act = lti_act;
}
}
// insert new edges, update counters
{
// attr/const pairs
{
for ( std::set< std::pair< smem_hash_id, smem_hash_id > >::iterator p=const_new.begin(); p!=const_new.end(); p++ )
{
// insert
{
// parent_id, attr, val_const, val_lti, act_value
my_agent->smem_stmts->web_add->bind_int( 1, parent_id );
my_agent->smem_stmts->web_add->bind_int( 2, p->first );
my_agent->smem_stmts->web_add->bind_int( 3, p->second );
my_agent->smem_stmts->web_add->bind_double( 5, web_act );
}
// update counter
{
// check if counter exists (and add if does not): attr, val
my_agent->smem_stmts->ct_const_check->bind_int( 1, p->first );
my_agent->smem_stmts->ct_const_check->bind_int( 2, p->second );
{
my_agent->smem_stmts->ct_const_add->bind_int( 1, p->first );
my_agent->smem_stmts->ct_const_add->bind_int( 2, p->second );
}
else
{
// adjust count (adjustment, attr, val)
my_agent->smem_stmts->ct_const_update->bind_int( 1, 1 );
my_agent->smem_stmts->ct_const_update->bind_int( 2, p->first );
my_agent->smem_stmts->ct_const_update->bind_int( 3, p->second );
}
}
}
}
// attr/lti pairs
{
for ( std::set< std::pair< smem_hash_id, smem_lti_id > >::iterator p=lti_new.begin(); p!=lti_new.end(); p++ )
{
// insert
{
// parent_id, attr, val_const, val_lti, act_value
my_agent->smem_stmts->web_add->bind_int( 1, parent_id );
my_agent->smem_stmts->web_add->bind_int( 2, p->first );
my_agent->smem_stmts->web_add->bind_int( 4, p->second );
my_agent->smem_stmts->web_add->bind_double( 5, web_act );
}
// update counter
{
// check if counter exists (and add if does not): attr, val
my_agent->smem_stmts->ct_lti_check->bind_int( 1, p->first );
my_agent->smem_stmts->ct_lti_check->bind_int( 2, p->second );
{
my_agent->smem_stmts->ct_lti_add->bind_int( 1, p->first );
my_agent->smem_stmts->ct_lti_add->bind_int( 2, p->second );
}
else
{
// adjust count (adjustment, attr, lti)
my_agent->smem_stmts->ct_lti_update->bind_int( 1, 1 );
my_agent->smem_stmts->ct_lti_update->bind_int( 2, p->first );
my_agent->smem_stmts->ct_lti_update->bind_int( 3, p->second );
}
}
}
}
// update attribute count
{
for ( std::set< smem_hash_id >::iterator a=attr_new.begin(); a!=attr_new.end(); a++ )
{
// check if counter exists (and add if does not): attr
my_agent->smem_stmts->ct_attr_check->bind_int( 1, *a );
{
my_agent->smem_stmts->ct_attr_add->bind_int( 1, *a );
}
else
{
// adjust count (adjustment, attr)
my_agent->smem_stmts->ct_attr_update->bind_int( 1, 1 );
my_agent->smem_stmts->ct_attr_update->bind_int( 2, *a );
}
}
}
// update local edge count
{
my_agent->smem_stats->slots->set_value( my_agent->smem_stats->slots->get_value() + ( const_new.size() + lti_new.size() ) );
}
}
}
bool smem_symbol_is_constant ( Symbol sym)
inline

Definition at line 661 of file semantic_memory.cpp.

References FLOAT_CONSTANT_SYMBOL_TYPE, INT_CONSTANT_SYMBOL_TYPE, and SYM_CONSTANT_SYMBOL_TYPE.

Referenced by _smem_process_cue_wme(), smem_soar_store(), and smem_temporal_hash().

{
return ( ( sym->common.symbol_type == SYM_CONSTANT_SYMBOL_TYPE ) ||
( sym->common.symbol_type == INT_CONSTANT_SYMBOL_TYPE ) ||
( sym->common.symbol_type == FLOAT_CONSTANT_SYMBOL_TYPE ) );
}
smem_hash_id smem_temporal_hash ( agent my_agent,
Symbol sym,
bool  add_on_fail = true 
)

Definition at line 923 of file semantic_memory.cpp.

References symbol_union::fc, FLOAT_CONSTANT_SYMBOL_TYPE, smem_timer_container::hash, symbol_union::ic, INT_CONSTANT_SYMBOL_TYPE, sym_constant_struct::name, NIL, symbol_union::sc, smem_symbol_is_constant(), smem_temporal_hash_float(), smem_temporal_hash_int(), smem_temporal_hash_str(), agent_struct::smem_timers, agent_struct::smem_validation, soar_module::timer::start(), soar_module::timer::stop(), SYM_CONSTANT_SYMBOL_TYPE, int_constant_struct::value, and float_constant_struct::value.

Referenced by _smem_process_cue_wme(), and smem_store_chunk().

{
smem_hash_id return_val = NIL;
my_agent->smem_timers->hash->start();
{
if ( ( !sym->common.smem_hash ) || ( sym->common.smem_valid != my_agent->smem_validation ) )
{
sym->common.smem_hash = NIL;
sym->common.smem_valid = my_agent->smem_validation;
switch ( sym->common.symbol_type )
{
return_val = smem_temporal_hash_str( my_agent, sym->sc.name, add_on_fail );
break;
return_val = smem_temporal_hash_int( my_agent, sym->ic.value, add_on_fail );
break;
return_val = smem_temporal_hash_float( my_agent, sym->fc.value, add_on_fail );
break;
}
// cache results for later re-use
sym->common.smem_hash = return_val;
sym->common.smem_valid = my_agent->smem_validation;
}
return_val = sym->common.smem_hash;
}
my_agent->smem_timers->hash->stop();
return return_val;
}
smem_hash_id smem_temporal_hash_add ( agent my_agent,
byte  sym_type 
)
inline
smem_hash_id smem_temporal_hash_float ( agent my_agent,
double  val,
bool  add_on_fail = true 
)
inline
smem_hash_id smem_temporal_hash_int ( agent my_agent,
int64_t  val,
bool  add_on_fail = true 
)
inline

Definition at line 841 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), smem_statement_container::hash_add_int, smem_statement_container::hash_get_int, INT_CONSTANT_SYMBOL_TYPE, NIL, soar_module::op_reinit, soar_module::statement::reinitialize(), soar_module::row, agent_struct::smem_stmts, and smem_temporal_hash_add().

Referenced by smem_temporal_hash().

{
smem_hash_id return_val = NIL;
// search first
my_agent->smem_stmts->hash_get_int->bind_int( 1, val );
{
return_val = static_cast<smem_hash_id>( my_agent->smem_stmts->hash_get_int->column_int( 0 ) );
}
// if fail and supposed to add
if ( !return_val && add_on_fail )
{
// type first
// then content
my_agent->smem_stmts->hash_add_int->bind_int( 1, return_val );
my_agent->smem_stmts->hash_add_int->bind_int( 2, val );
}
return return_val;
}
smem_hash_id smem_temporal_hash_str ( agent my_agent,
char *  val,
bool  add_on_fail = true 
)
inline

Definition at line 895 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::bind_text(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), smem_statement_container::hash_add_str, smem_statement_container::hash_get_str, NIL, soar_module::op_reinit, soar_module::statement::reinitialize(), soar_module::row, agent_struct::smem_stmts, smem_temporal_hash_add(), and SYM_CONSTANT_SYMBOL_TYPE.

Referenced by smem_temporal_hash().

{
smem_hash_id return_val = NIL;
// search first
my_agent->smem_stmts->hash_get_str->bind_text( 1, static_cast<const char *>( val ) );
{
return_val = static_cast<smem_hash_id>( my_agent->smem_stmts->hash_get_str->column_int( 0 ) );
}
// if fail and supposed to add
if ( !return_val && add_on_fail )
{
// type first
// then content
my_agent->smem_stmts->hash_add_str->bind_int( 1, return_val );
my_agent->smem_stmts->hash_add_str->bind_text( 2, static_cast<const char*>( val ) );
}
return return_val;
}
bool smem_valid_production ( condition lhs_top,
action rhs_top 
)

Definition at line 1298 of file semantic_memory.cpp.

References _smem_lti_from_rhs_value(), _smem_lti_from_test(), action_struct::already_in_tc, action_struct::attr, action_struct::id, symbol_union::id, IDENTIFIER_SYMBOL_TYPE, MAKE_ACTION, action_struct::next, NIL, POSITIVE_CONDITION, rhs_value_to_symbol(), identifier_struct::smem_lti, action_struct::type, and action_struct::value.

Referenced by chunk_instantiation(), and make_production().

{
bool return_val = true;
std::set<Symbol *> valid_ltis;
std::set<Symbol *>::iterator lti_p;
// collect valid ltis
for ( condition *c=lhs_top; c!=NIL; c=c->next )
{
if ( c->type == POSITIVE_CONDITION )
{
_smem_lti_from_test( c->data.tests.attr_test, &valid_ltis );
_smem_lti_from_test( c->data.tests.value_test, &valid_ltis );
}
}
// validate ltis in actions
// copied primarily from add_all_variables_in_action
{
Symbol *id;
action *a;
int action_counter = 0;
for ( a=rhs_top; a!=NIL; a=a->next )
{
a->already_in_tc = false;
action_counter++;
}
// good_pass detects infinite loops
bool good_pass = true;
bool good_action = true;
while ( good_pass && action_counter )
{
good_pass = false;
for ( a=rhs_top; a!=NIL; a=a->next )
{
if ( !a->already_in_tc )
{
good_action = false;
if ( a->type == MAKE_ACTION )
{
id = rhs_value_to_symbol( a->id );
// non-identifiers are ok
if ( id->common.symbol_type != IDENTIFIER_SYMBOL_TYPE )
{
good_action = true;
}
// short-term identifiers are ok
else if ( id->id.smem_lti == NIL )
{
good_action = true;
}
// valid long-term identifiers are ok
else if ( valid_ltis.find( id ) != valid_ltis.end() )
{
good_action = true;
}
}
else
{
good_action = true;
}
// we've found a new good action
// mark as good, collect all goodies
if ( good_action )
{
a->already_in_tc = true;
// everyone has values
_smem_lti_from_rhs_value( a->value, &valid_ltis );
// function calls don't have attributes
if ( a->type == MAKE_ACTION )
{
_smem_lti_from_rhs_value( a->attr, &valid_ltis );
}
// note that we've dealt with another action
action_counter--;
good_pass = true;
}
}
}
};
return_val = ( action_counter == 0 );
}
return return_val;
}
void smem_variable_create ( agent my_agent,
smem_variable_key  variable_id,
int64_t  variable_value 
)
inline
bool smem_variable_get ( agent my_agent,
smem_variable_key  variable_id,
int64_t *  variable_value 
)
inline
void smem_variable_set ( agent my_agent,
smem_variable_key  variable_id,
int64_t  variable_value 
)
inline
void smem_visualize_lti ( agent my_agent,
smem_lti_id  lti_id,
unsigned int  depth,
std::string *  return_val 
)

Definition at line 4095 of file semantic_memory.cpp.

References soar_module::sqlite_statement::bind_int(), soar_module::sqlite_statement::column_double(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), FLOAT_CONSTANT_SYMBOL_TYPE, INT_CONSTANT_SYMBOL_TYPE, smem_vis_lti_struct::level, smem_vis_lti_struct::lti_id, smem_statement_container::lti_letter_num, smem_vis_lti_struct::lti_name, soar_module::statement::reinitialize(), soar_module::row, smem_reverse_hash_float(), smem_reverse_hash_int(), smem_reverse_hash_str(), agent_struct::smem_stmts, SMEM_WEB_NULL, SYM_CONSTANT_SYMBOL_TYPE, smem_statement_container::vis_lti_act, and smem_statement_container::web_expand.

{
// buffer
std::string return_val2;
uint64_t child_counter;
std::string temp_str;
std::string temp_str2;
int64_t temp_int;
double temp_double;
std::queue<smem_vis_lti *> bfs;
smem_vis_lti *new_lti;
smem_vis_lti *parent_lti;
std::map< smem_lti_id, smem_vis_lti* > close_list;
std::map< smem_lti_id, smem_vis_lti* >::iterator cl_p;
// header
return_val->append( "digraph smem_lti {" );
return_val->append( "\n" );
// root
{
new_lti = new smem_vis_lti;
new_lti->lti_id = lti_id;
new_lti->level = 0;
// fake former linkage
{
// get just this lti
lti_q->bind_int( 1, lti_id );
lti_q->execute();
// letter
new_lti->lti_name.push_back( static_cast<char>( lti_q->column_int( 0 ) ) );
// number
temp_int = lti_q->column_int( 1 );
to_string( temp_int, temp_str );
new_lti->lti_name.append( temp_str );
// done with lookup
lti_q->reinitialize();
}
bfs.push( new_lti );
close_list.insert( std::make_pair< smem_lti_id, smem_vis_lti* >( lti_id, new_lti ) );
new_lti = NULL;
}
// optionally depth-limited breadth-first-search of children
while ( !bfs.empty() )
{
parent_lti = bfs.front();
bfs.pop();
child_counter = 0;
// get direct children: attr_type, attr_hash, value_type, value_hash, value_letter, value_num, value_lti
expand_q->bind_int( 1, parent_lti->lti_id );
while ( expand_q->execute() == soar_module::row )
{
// identifier vs. constant
if ( expand_q->column_int( 6 ) != SMEM_WEB_NULL )
{
new_lti = new smem_vis_lti;
new_lti->lti_id = expand_q->column_int( 6 );
new_lti->level = ( parent_lti->level + 1 );
// add node
{
// letter
new_lti->lti_name.push_back( static_cast<char>( expand_q->column_int( 4 ) ) );
// number
temp_int = expand_q->column_int( 5 );
to_string( temp_int, temp_str );
new_lti->lti_name.append( temp_str );
}
// add linkage
{
// get attribute
switch ( expand_q->column_int(0) )
{
smem_reverse_hash_str( my_agent, expand_q->column_int(1), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, expand_q->column_int(1) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, expand_q->column_int(1) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
// output linkage
return_val2.append( parent_lti->lti_name );
return_val2.append( " -> " );
return_val2.append( new_lti->lti_name );
return_val2.append( " [ label = \"" );
return_val2.append( temp_str );
return_val2.append( "\" ];" );
return_val2.append( "\n" );
}
// prevent looping
{
cl_p = close_list.find( new_lti->lti_id );
if ( cl_p == close_list.end() )
{
close_list.insert( std::make_pair< smem_lti_id, smem_vis_lti* >( new_lti->lti_id, new_lti ) );
if ( ( depth == 0 ) || ( new_lti->level < depth ) )
{
bfs.push( new_lti );
}
}
else
{
delete new_lti;
}
}
new_lti = NULL;
}
else
{
// add value node
{
// get node name
{
temp_str2.assign( parent_lti->lti_name );
temp_str2.append( "_" );
to_string( child_counter, temp_str );
temp_str2.append( temp_str );
}
// get value
switch ( expand_q->column_int(2) )
{
smem_reverse_hash_str( my_agent, expand_q->column_int(3), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, expand_q->column_int(3) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, expand_q->column_int(3) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
// output node
return_val2.append( "node [ shape = plaintext ];" );
return_val2.append( "\n" );
return_val2.append( temp_str2 );
return_val2.append( " [ label=\"" );
return_val2.append( temp_str );
return_val2.append( "\" ];" );
return_val2.append( "\n" );
}
// add linkage
{
// get attribute
switch ( expand_q->column_int(0) )
{
smem_reverse_hash_str( my_agent, expand_q->column_int(1), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, expand_q->column_int(1) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, expand_q->column_int(1) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
// output linkage
return_val2.append( parent_lti->lti_name );
return_val2.append( " -> " );
return_val2.append( temp_str2 );
return_val2.append( " [ label = \"" );
return_val2.append( temp_str );
return_val2.append( "\" ];" );
return_val2.append( "\n" );
}
child_counter++;
}
}
expand_q->reinitialize();
}
// footer
return_val2.append( "}" );
return_val2.append( "\n" );
// handle lti nodes at once
{
return_val->append( "node [ shape = doublecircle ];" );
return_val->append( "\n" );
for ( cl_p=close_list.begin(); cl_p!=close_list.end(); cl_p++ )
{
return_val->append( cl_p->second->lti_name );
return_val->append( " [ label=\"" );
return_val->append( cl_p->second->lti_name );
return_val->append( "\\n[" );
act_q->bind_int( 1, cl_p->first );
if ( act_q->execute() == soar_module::row )
{
temp_double = act_q->column_double( 0 );
to_string( temp_double, temp_str, 3, true );
if ( temp_double >= 0 )
{
return_val->append( "+" );
}
return_val->append( temp_str );
}
act_q->reinitialize();
return_val->append( "]\"" );
return_val->append( " ];" );
return_val->append( "\n" );
delete cl_p->second;
}
}
// transfer buffer after nodes
return_val->append( return_val2 );
}
void smem_visualize_store ( agent my_agent,
std::string *  return_val 
)

Definition at line 3847 of file semantic_memory.cpp.

References soar_module::sqlite_statement::column_double(), soar_module::sqlite_statement::column_int(), soar_module::statement::execute(), FLOAT_CONSTANT_SYMBOL_TYPE, INT_CONSTANT_SYMBOL_TYPE, soar_module::statement::reinitialize(), soar_module::row, smem_attach(), smem_reverse_hash_float(), smem_reverse_hash_int(), smem_reverse_hash_str(), agent_struct::smem_stmts, SYM_CONSTANT_SYMBOL_TYPE, smem_statement_container::vis_lti, smem_statement_container::vis_value_const, and smem_statement_container::vis_value_lti.

{
// vizualizing the store requires an open semantic database
smem_attach( my_agent );
// header
return_val->append( "digraph smem {" );
return_val->append( "\n" );
// LTIs
return_val->append( "node [ shape = doublecircle ];" );
return_val->append( "\n" );
std::map< smem_lti_id, std::string > lti_names;
std::map< smem_lti_id, std::string >::iterator n_p;
{
smem_lti_id lti_id;
char lti_letter;
uint64_t lti_number;
std::string *lti_name;
std::string temp_str;
int64_t temp_int;
double temp_double;
// id, letter, number
q = my_agent->smem_stmts->vis_lti;
while ( q->execute() == soar_module::row )
{
lti_id = q->column_int( 0 );
lti_letter = static_cast<char>( q->column_int( 1 ) );
lti_number = static_cast<uint64_t>( q->column_int( 2 ) );
lti_name =& lti_names[ lti_id ];
lti_name->push_back( lti_letter );
to_string( lti_number, temp_str );
lti_name->append( temp_str );
return_val->append( (*lti_name) );
return_val->append( " [ label=\"" );
return_val->append( (*lti_name) );
return_val->append( "\\n[" );
temp_double = q->column_double( 3 );
to_string( temp_double, temp_str, 3, true );
if ( temp_double >= 0 )
{
return_val->append( "+" );
}
return_val->append( temp_str );
return_val->append( "]\"" );
return_val->append( " ];" );
return_val->append( "\n" );
}
if ( !lti_names.empty() )
{
// terminal nodes first
{
std::map< smem_lti_id, std::list<std::string> > lti_terminals;
std::map< smem_lti_id, std::list<std::string> >::iterator t_p;
std::list<std::string>::iterator a_p;
std::list<std::string> *my_terminals;
std::list<std::string>::size_type terminal_num;
return_val->append( "\n" );
// proceed to terminal nodes
return_val->append( "node [ shape = plaintext ];" );
return_val->append( "\n" );
// parent_id, attr_type, attr_hash, val_type, val_hash
q = my_agent->smem_stmts->vis_value_const;
while ( q->execute() == soar_module::row )
{
lti_id = q->column_int( 0 );
my_terminals =& lti_terminals[ lti_id ];
lti_name =& lti_names[ lti_id ];
// parent prefix
return_val->append( (*lti_name) );
return_val->append( "_" );
// terminal count
terminal_num = my_terminals->size();
to_string( terminal_num, temp_str );
return_val->append( temp_str );
// prepare for value
return_val->append( " [ label = \"" );
// output value
{
switch ( q->column_int( 3 ) )
{
smem_reverse_hash_str( my_agent, q->column_int(4), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, q->column_int(4) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, q->column_int(4) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
return_val->append( temp_str );
}
// store terminal (attribute for edge label)
{
switch ( q->column_int(1) )
{
smem_reverse_hash_str( my_agent, q->column_int(2), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, q->column_int(2) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, q->column_int(2) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
my_terminals->push_back( temp_str );
}
// footer
return_val->append( "\" ];" );
return_val->append( "\n" );
}
// output edges
{
unsigned int terminal_counter;
for ( n_p=lti_names.begin(); n_p!=lti_names.end(); n_p++ )
{
t_p = lti_terminals.find( n_p->first );
if ( t_p != lti_terminals.end() )
{
terminal_counter = 0;
for ( a_p=t_p->second.begin(); a_p!=t_p->second.end(); a_p++ )
{
return_val->append( n_p->second );
return_val ->append( " -> " );
return_val->append( n_p->second );
return_val->append( "_" );
to_string( terminal_counter, temp_str );
return_val->append( temp_str );
return_val->append( " [ label=\"" );
return_val->append( (*a_p) );
return_val->append( "\" ];" );
return_val->append( "\n" );
terminal_counter++;
}
}
}
}
}
// then links to other LTIs
{
// parent_id, attr_type, attr_hash, val_lti
q = my_agent->smem_stmts->vis_value_lti;
while ( q->execute() == soar_module::row )
{
// source
lti_id = q->column_int( 0 );
lti_name =& lti_names[ lti_id ];
return_val->append( (*lti_name) );
return_val->append( " -> " );
// destination
lti_id = q->column_int( 3 );
lti_name =& lti_names[ lti_id ];
return_val->append( (*lti_name) );
return_val->append( " [ label =\"" );
// output attribute
{
switch ( q->column_int(1) )
{
smem_reverse_hash_str( my_agent, q->column_int(2), temp_str );
break;
temp_int = smem_reverse_hash_int( my_agent, q->column_int(2) );
to_string( temp_int, temp_str );
break;
temp_double = smem_reverse_hash_float( my_agent, q->column_int(2) );
to_string( temp_double, temp_str );
break;
default:
temp_str.clear();
break;
}
return_val->append( temp_str );
}
// footer
return_val->append( "\" ];" );
return_val->append( "\n" );
}
}
}
}
// footer
return_val->append( "}" );
return_val->append( "\n" );
}