1 #include <portability.h>
37 #ifdef EPMEM_EXPERIMENT
39 uint64_t epmem_episodes_searched = 0;
40 uint64_t epmem_dc_interval_inserts = 0;
41 uint64_t epmem_dc_interval_removes = 0;
42 uint64_t epmem_dc_wme_adds = 0;
43 std::ofstream* epmem_exp_output = NULL;
52 int64_t epmem_exp_state[] = { 0, 0, 0 };
224 const char *msg =
"Database set to file";
229 value->assign( new_value );
234 template <
typename T>
237 template <
typename T>
533 add_structure(
"CREATE TABLE IF NOT EXISTS vars (id INTEGER PRIMARY KEY,value NONE)" );
534 add_structure(
"CREATE TABLE IF NOT EXISTS rit_left_nodes (min INTEGER, max INTEGER)" );
535 add_structure(
"CREATE TABLE IF NOT EXISTS rit_right_nodes (node INTEGER)" );
536 add_structure(
"CREATE TABLE IF NOT EXISTS temporal_symbol_hash (id INTEGER PRIMARY KEY, sym_const NONE, sym_type INTEGER)" );
537 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS temporal_symbol_hash_const_type ON temporal_symbol_hash (sym_type,sym_const)" );
540 add_structure(
"INSERT OR IGNORE INTO temporal_symbol_hash (id,sym_const,sym_type) VALUES (0,NULL,1)" );
543 add_structure(
"INSERT OR IGNORE INTO temporal_symbol_hash (id,sym_const,sym_type) VALUES (1,'operator*',2)" );
593 add_structure(
"CREATE TABLE IF NOT EXISTS times (id INTEGER PRIMARY KEY)" );
595 add_structure(
"CREATE TABLE IF NOT EXISTS node_now (id INTEGER,start INTEGER)" );
596 add_structure(
"CREATE INDEX IF NOT EXISTS node_now_start ON node_now (start)" );
597 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS node_now_id_start ON node_now (id,start DESC)" );
599 add_structure(
"CREATE TABLE IF NOT EXISTS edge_now (id INTEGER,start INTEGER)" );
600 add_structure(
"CREATE INDEX IF NOT EXISTS edge_now_start ON edge_now (start)" );
601 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS edge_now_id_start ON edge_now (id,start DESC)" );
603 add_structure(
"CREATE TABLE IF NOT EXISTS node_point (id INTEGER,start INTEGER)" );
604 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS node_point_id_start ON node_point (id,start DESC)" );
605 add_structure(
"CREATE INDEX IF NOT EXISTS node_point_start ON node_point (start)" );
607 add_structure(
"CREATE TABLE IF NOT EXISTS edge_point (id INTEGER,start INTEGER)" );
608 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS edge_point_id_start ON edge_point (id,start DESC)" );
609 add_structure(
"CREATE INDEX IF NOT EXISTS edge_point_start ON edge_point (start)" );
611 add_structure(
"CREATE TABLE IF NOT EXISTS node_range (rit_node INTEGER,start INTEGER,end INTEGER,id INTEGER)" );
612 add_structure(
"CREATE INDEX IF NOT EXISTS node_range_lower ON node_range (rit_node,start)" );
613 add_structure(
"CREATE INDEX IF NOT EXISTS node_range_upper ON node_range (rit_node,end)" );
614 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS node_range_id_start ON node_range (id,start DESC)" );
615 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS node_range_id_end_start ON node_range (id,end DESC,start)" );
617 add_structure(
"CREATE TABLE IF NOT EXISTS edge_range (rit_node INTEGER,start INTEGER,end INTEGER,id INTEGER)" );
618 add_structure(
"CREATE INDEX IF NOT EXISTS edge_range_lower ON edge_range (rit_node,start)" );
619 add_structure(
"CREATE INDEX IF NOT EXISTS edge_range_upper ON edge_range (rit_node,end)" );
620 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS edge_range_id_start ON edge_range (id,start DESC)" );
621 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS edge_range_id_end_start ON edge_range (id,end DESC,start)" );
623 add_structure(
"CREATE TABLE IF NOT EXISTS node_unique (child_id INTEGER PRIMARY KEY AUTOINCREMENT,parent_id INTEGER,attrib INTEGER, value INTEGER)" );
624 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS node_unique_parent_attrib_value ON node_unique (parent_id,attrib,value)" );
626 add_structure(
"CREATE TABLE IF NOT EXISTS edge_unique (parent_id INTEGER PRIMARY KEY AUTOINCREMENT,q0 INTEGER,w INTEGER,q1 INTEGER, last INTEGER)" );
627 add_structure(
"CREATE INDEX IF NOT EXISTS edge_unique_q0_w_last ON edge_unique (q0,w,last)" );
628 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS edge_unique_q0_w_q1 ON edge_unique (q0,w,q1)" );
630 add_structure(
"CREATE TABLE IF NOT EXISTS lti (parent_id INTEGER PRIMARY KEY, letter INTEGER, num INTEGER, time_id INTEGER)" );
631 add_structure(
"CREATE UNIQUE INDEX IF NOT EXISTS lti_letter_num ON lti (letter,num)" );
634 add_structure(
"CREATE TABLE IF NOT EXISTS ascii (ascii_num INTEGER PRIMARY KEY, ascii_chr TEXT)" );
637 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (65,'A')" );
638 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (66,'B')" );
639 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (67,'C')" );
640 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (68,'D')" );
641 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (69,'E')" );
642 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (70,'F')" );
643 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (71,'G')" );
644 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (72,'H')" );
645 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (73,'I')" );
646 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (74,'J')" );
647 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (75,'K')" );
648 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (76,'L')" );
649 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (77,'M')" );
650 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (78,'N')" );
651 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (79,'O')" );
652 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (80,'P')" );
653 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (81,'Q')" );
654 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (82,'R')" );
655 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (83,'S')" );
656 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (84,'T')" );
657 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (85,'U')" );
658 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (86,'V')" );
659 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (87,'W')" );
660 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (88,'X')" );
661 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (89,'Y')" );
662 add_structure(
"INSERT INTO ascii (ascii_num, ascii_chr) VALUES (90,'Z')" );
727 get_nodes =
new soar_module::sqlite_statement( new_db,
"SELECT f.child_id, f.parent_id, h1.sym_const, h2.sym_const, h1.sym_type, h2.sym_type FROM node_unique f, temporal_symbol_hash h1, temporal_symbol_hash h2 WHERE f.child_id IN (SELECT n.id FROM node_now n WHERE n.start<= ? UNION ALL SELECT p.id FROM node_point p WHERE p.start=? UNION ALL SELECT e1.id FROM node_range e1, rit_left_nodes lt WHERE e1.rit_node=lt.min AND e1.end >= ? UNION ALL SELECT e2.id FROM node_range e2, rit_right_nodes rt WHERE e2.rit_node = rt.node AND e2.start <= ?) AND f.attrib=h1.id AND f.value=h2.id ORDER BY f.child_id ASC", new_agent->
epmem_timers->
ncb_node );
730 get_edges =
new soar_module::sqlite_statement( new_db,
"SELECT f.q0, h.sym_const, f.q1, h.sym_type, lti.letter, lti.num FROM edge_unique f INNER JOIN temporal_symbol_hash h ON f.w=h.id LEFT JOIN lti ON (f.q1=lti.parent_id AND lti.time_id <= ?) WHERE f.parent_id IN (SELECT n.id FROM edge_now n WHERE n.start<= ? UNION ALL SELECT p.id FROM edge_point p WHERE p.start = ? UNION ALL SELECT e1.id FROM edge_range e1, rit_left_nodes lt WHERE e1.rit_node=lt.min AND e1.end >= ? UNION ALL SELECT e2.id FROM edge_range e2, rit_right_nodes rt WHERE e2.rit_node = rt.node AND e2.start <= ?) ORDER BY f.q0 ASC, f.q1 ASC", new_agent->
epmem_timers->
ncb_edge );
755 const char* epmem_find_edge_queries[2][2] = {
757 "SELECT child_id, value, ? FROM node_unique WHERE parent_id=? AND attrib=?",
758 "SELECT child_id, value, ? FROM node_unique WHERE parent_id=? AND attrib=? AND value=?"
761 "SELECT parent_id, q1, last FROM edge_unique WHERE q0=? AND w=? AND ?<last ORDER BY last DESC",
762 "SELECT parent_id, q1, last FROM edge_unique WHERE q0=? AND w=? AND q1=? AND ?<last"
768 for ( k=0; k<=1; k++ )
779 const char *epmem_find_interval_queries[2][2][3] =
783 "SELECT (e.start - 1) AS start FROM node_range e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC",
784 "SELECT (e.start - 1) AS start FROM node_now e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC",
785 "SELECT (e.start - 1) AS start FROM node_point e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC"
788 "SELECT e.end AS end FROM node_range e WHERE e.id=? AND e.end>0 AND e.start<=? ORDER BY e.end DESC",
789 "SELECT ? AS end FROM node_now e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC",
790 "SELECT e.start AS end FROM node_point e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC"
795 "SELECT (e.start - 1) AS start FROM edge_range e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC",
796 "SELECT (e.start - 1) AS start FROM edge_now e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC",
797 "SELECT (e.start - 1) AS start FROM edge_point e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC"
800 "SELECT e.end AS end FROM edge_range e WHERE e.id=? AND e.end>0 AND e.start<=? ORDER BY e.end DESC",
801 "SELECT ? AS end FROM edge_now e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC",
802 "SELECT e.start AS end FROM edge_point e WHERE e.id=? AND e.start<=? ORDER BY e.start DESC"
826 const char *epmem_find_lti_queries[2][3] =
829 "SELECT (e.start - 1) AS start FROM edge_range e WHERE e.id=? AND ?<e.start AND e.start<=? ORDER BY e.start DESC",
830 "SELECT (e.start - 1) AS start FROM edge_now e WHERE e.id=? AND ?<e.start AND e.start<=? ORDER BY e.start DESC",
831 "SELECT (e.start - 1) AS start FROM edge_point e WHERE e.id=? AND ?<e.start AND e.start<=? ORDER BY e.start DESC"
834 "SELECT e.end AS end FROM edge_range e WHERE e.id=? AND e.end>0 AND ?<=e.start AND e.start<=? ORDER BY e.end DESC",
835 "SELECT ? AS end FROM edge_now e WHERE e.id=? AND ?<=e.start AND e.start<=? ORDER BY e.start",
836 "SELECT e.start AS end FROM edge_point e WHERE e.id=? AND ?<=e.start AND e.start<=? ORDER BY e.start DESC"
881 return_val->push_back( w );
887 return_val->push_back( w );
895 return_val->push_back( w );
900 return_val->push_back( w );
910 if ( my_list.empty() )
925 pref->on_goal_list =
true;
932 epmem_wmes->push_back( pref );
952 if ( my_justification_list !=
NIL )
958 my_justification!=
NIL;
959 my_justification=next_justification )
961 next_justification = my_justification->
next;
963 if ( my_justification->in_ms )
968 for ( just_pref=my_justification->preferences_generated; just_pref!=
NIL; just_pref=just_pref->
inst_next )
1025 var_get->
bind_int( 1, variable_id );
1030 (*variable_value) = var_get->
column_int( 0 );
1047 var_set->
bind_int( 1, variable_id );
1048 var_set->
bind_int( 2, variable_value );
1087 for ( step = ( ( ( node >= 0 )?( node ):( -1 * node ) ) / 2 ); step >= 1; step /= 2 )
1093 else if ( node < lower )
1106 (*step_return) = step;
1160 int64_t left_node, left_step;
1161 int64_t right_node, right_step;
1163 lower = ( lower - offset );
1164 upper = ( upper - offset );
1172 if ( ( lower > node ) || (upper < node ) )
1185 for ( step = ( ( ( node >= 0 )?( node ):( -1 * node ) ) / 2 ); step >= 1; step /= 2 )
1192 else if ( upper < node )
1205 left_node = node - step;
1206 for ( left_step = ( step / 2 ); left_step >= 1; left_step /= 2 )
1208 if ( lower == left_node )
1212 else if ( lower > left_node )
1215 left_node += left_step;
1219 left_node -= left_step;
1224 right_node = node + step;
1225 for ( right_step = ( step / 2 ); right_step >= 1; right_step /= 2 )
1227 if ( upper == right_node )
1231 else if ( upper < right_node )
1234 right_node -= right_step;
1238 right_node += right_step;
1275 int64_t l = ( lower - offset );
1276 int64_t u = ( upper - offset );
1281 left_root =
static_cast<int64_t
>( pow( -2.0, floor( log( static_cast<double>( -l ) ) /
EPMEM_LN_2 ) ) );
1293 right_root =
static_cast<int64_t
>( pow( 2.0, floor( log( static_cast<double>( u ) ) /
EPMEM_LN_2 ) ) );
1356 for ( k=0; k<=1; k++ )
1390 epmem_parent_id_pool::iterator p;
1391 epmem_hashed_id_pool::iterator p_p;
1395 for ( p_p=p->second->begin(); p_p!=p->second->end(); p_p++ )
1407 delete rf_it->second;
1424 #ifdef EPMEM_EXPERIMENT
1425 if ( epmem_exp_output )
1427 epmem_exp_output->close();
1428 delete epmem_exp_output;
1429 epmem_exp_output = NULL;
1431 if ( epmem_exp_timer )
1433 delete epmem_exp_timer;
1468 if ( state == NULL )
1520 const char *db_path;
1523 db_path =
":memory:";
1538 print( my_agent, buf );
1590 std::string cache_sql(
"PRAGMA cache_size = " );
1592 cache_sql.append( str );
1659 #ifdef USE_MEM_POOL_ALLOCATORS
1667 wms_temp->insert( static_cast<wme*>(NULL) );
1678 int64_t stored_id =
NIL;
1704 int64_t var_val =
NIL;
1768 time_last = ( time_max - 1 );
1770 const char *now_select[] = {
"SELECT id,start FROM node_now",
"SELECT id,start FROM edge_now" };
1772 const char *now_delete[] = {
"DELETE FROM node_now",
"DELETE FROM edge_now" };
1776 temp_q = now_add[i];
1786 if ( range_start == time_last )
1819 const char *minmax_select[] = {
"SELECT MAX(child_id) FROM node_unique",
"SELECT MAX(parent_id) FROM edge_unique" };
1830 std::vector<bool>::size_type num_ids = temp_q->
column_int( 0 );
1832 minmax_max[i]->resize( num_ids,
true );
1833 minmax_min[i]->resize( num_ids, time_max );
1865 ip =& (*(*hp))[ w ];
1869 (*ip)->push_front( std::make_pair( q1, parent_id ) );
1936 if ( ( !sym->common.epmem_hash ) || ( sym->common.epmem_valid != my_agent->
epmem_validation ) )
1938 sym->common.epmem_hash =
NIL;
1947 switch ( sym->common.symbol_type )
1971 if ( !return_val && add_on_fail )
1974 switch ( sym->common.symbol_type )
1994 sym->common.epmem_hash = return_val;
1998 return_val = sym->common.epmem_hash;
2042 std::map< wme*, epmem_id_reservation* >& id_reservations, std::set< Symbol* >& new_identifiers, std::queue< epmem_node_id >& epmem_node, std::queue< epmem_node_id >&
epmem_edge )
2044 epmem_wme_list::iterator w_p;
2045 bool value_known_apriori =
false;
2054 epmem_id_pool::iterator pool_p;
2055 std::map<wme *, epmem_id_reservation *>::iterator r_p;
2060 epmem_wme_list::iterator w_p2;
2061 bool good_recurse =
false;
2064 for ( w_p=w_b; w_p!=w_e; w_p++ )
2074 ( !(*w_p)->value->id.smem_lti ) )
2085 new_id_reservation->
my_pool = NULL;
2087 if ( (*w_p)->acceptable )
2098 if ( (*my_id_repo) )
2100 for ( pool_p = (*my_id_repo)->begin(); pool_p != (*my_id_repo)->end(); pool_p++ )
2102 if ( pool_p->first == (*w_p)->value->id.epmem_id )
2104 new_id_reservation->
my_id = pool_p->second;
2105 (*my_id_repo)->erase( pool_p );
2116 new_id_reservation->
my_pool = (*my_id_repo);
2117 id_reservations[ (*w_p) ] = new_id_reservation;
2118 new_id_reservation = NULL;
2122 for ( w_p=w_b; w_p!=w_e; w_p++ )
2149 if ( (*w_p)->value->id.smem_lti )
2152 if ( !value_known_apriori )
2189 if ( (*w_p)->acceptable )
2214 if ( value_known_apriori )
2216 r_p = id_reservations.find( (*w_p) );
2218 if ( r_p != id_reservations.end() )
2221 my_hash = r_p->second->my_hash;
2222 my_id_repo2 = r_p->second->my_pool;
2226 (*w_p)->epmem_id = r_p->second->my_id;
2232 id_reservations.erase( r_p );
2238 if ( (*w_p)->acceptable )
2249 if ( (*my_id_repo) )
2251 if ( !(*my_id_repo)->empty() )
2253 for ( pool_p = (*my_id_repo)->begin(); pool_p != (*my_id_repo)->end(); pool_p++ )
2255 if ( pool_p->first == (*w_p)->value->id.epmem_id )
2257 (*w_p)->epmem_id = pool_p->second;
2258 (*my_id_repo)->erase( pool_p );
2272 my_id_repo2 = (*my_id_repo);
2279 new_identifiers.insert( (*w_p)->value );
2282 if ( (*w_p)->acceptable )
2293 if ( (*my_id_repo) )
2296 if ( !(*my_id_repo)->empty() )
2298 for (pool_p = (*my_id_repo)->begin(); pool_p != (*my_id_repo)->end(); pool_p++)
2302 (*w_p)->epmem_id = pool_p->second;
2303 (*w_p)->value->id.epmem_id = pool_p->first;
2305 (*my_id_repo)->erase( pool_p );
2319 my_id_repo2 = (*my_id_repo);
2355 if ( !(*w_p)->value->id.smem_lti )
2362 epmem_edge.push( (*w_p)->epmem_id );
2374 epmem_edge.push( (*w_p)->epmem_id );
2384 if ( new_identifiers.find( (*w_p)->value ) != new_identifiers.end() )
2390 if ( (*w_p)->value->id.tc_num != tc )
2392 parent_syms.push( (*w_p)->value );
2393 parent_ids.push( (*w_p)->value->id.epmem_id );
2434 epmem_node.push( (*w_p)->epmem_id );
2446 epmem_node.push( (*w_p)->epmem_id );
2480 SNPRINTF( buf, 254,
"NEW EPISODE: %ld", static_cast<long int>(time_counter) );
2482 print( my_agent, buf );
2489 std::queue<epmem_node_id> epmem_node;
2501 std::queue< Symbol* > parent_syms;
2502 Symbol* parent_sym = NULL;
2503 std::queue< epmem_node_id > parent_ids;
2507 std::map< wme*, epmem_id_reservation* > id_reservations;
2508 std::set< Symbol* > new_identifiers;
2516 parent_syms.push( (*id_p) );
2517 parent_ids.push( (*id_p)->id.epmem_id );
2518 while ( !parent_syms.empty() )
2520 parent_sym = parent_syms.front();
2522 parent_id = parent_ids.front();
2525 if ( ! wmes->empty() )
2527 _epmem_store_level( my_agent, parent_syms, parent_ids, tc, wmes->begin(), wmes->end(), parent_id, time_counter, id_reservations, new_identifiers, epmem_node,
epmem_edge );
2539 #ifdef EPMEM_EXPERIMENT
2540 epmem_dc_interval_inserts = epmem_node.size() + epmem_edge.size();
2544 while ( !epmem_node.empty() )
2546 temp_node =& epmem_node.front();
2561 while ( !epmem_edge.empty() )
2563 temp_node =& epmem_edge.front();
2584 epmem_id_removal_map::iterator r;
2588 #ifdef EPMEM_EXPERIMENT
2589 epmem_dc_interval_removes = 0;
2598 #ifdef EPMEM_EXPERIMENT
2599 epmem_dc_interval_removes++;
2608 range_end = ( time_counter - 1 );
2611 if ( range_start == range_end )
2637 #ifdef EPMEM_EXPERIMENT
2638 epmem_dc_interval_removes++;
2647 range_end = ( time_counter - 1 );
2653 if ( range_start == range_end )
2678 if ( ( (*p_it)->id.smem_time_id == time_counter ) && ( (*p_it)->id.smem_valid == my_agent->
epmem_validation ) )
2699 while ( state != NULL )
2747 bool return_val =
false;
2761 inline void _epmem_install_id_wme(
agent* my_agent,
Symbol* parent,
Symbol* attr, std::map<
epmem_node_id, std::pair< Symbol*, bool > >* ids,
epmem_node_id q1,
bool val_is_short_term,
char val_letter, uint64_t val_num,
epmem_id_mapping* id_record,
soar_module::symbol_triple_list& retrieval_wmes )
2763 std::map< epmem_node_id, std::pair< Symbol*, bool > >::iterator id_p = ids->find( q1 );
2764 bool existing_identifier = ( id_p != ids->end() );
2766 if ( val_is_short_term )
2768 if ( !existing_identifier )
2773 epmem_id_mapping::iterator rec_p = id_record->find( q1 );
2774 if ( rec_p != id_record->end() )
2776 rec_p->second = id_p->second.first;
2783 if ( !existing_identifier )
2790 if ( existing_identifier )
2800 epmem_id_mapping::iterator rec_p = id_record->find( q1 );
2801 if ( rec_p != id_record->end() )
2803 rec_p->second = value;
2839 int64_t num_wmes = 0;
2860 Symbol *retrieved_header;
2897 std::map< epmem_node_id, std::pair< Symbol*, bool > > ids;
2907 ids[
EPMEM_NODEID_ROOT ] = std::make_pair< Symbol*, bool >( retrieved_header, true );
2917 bool val_is_short_term =
false;
2918 char val_letter =
NIL;
2919 int64_t val_num =
NIL;
2923 std::map< epmem_node_id, std::pair< Symbol*, bool> >::iterator id_p;
2926 std::queue< epmem_edge* > orphans;
2931 my_q->bind_int( 1, memory_id );
2932 my_q->bind_int( 2, memory_id );
2933 my_q->bind_int( 3, memory_id );
2934 my_q->bind_int( 4, memory_id );
2935 my_q->bind_int( 5, memory_id );
2939 q0 = my_q->column_int( 0 );
2940 q1 = my_q->column_int( 2 );
2941 w_type = my_q->column_int( 3 );
2954 attr =
make_sym_constant( my_agent, const_cast<char *>( reinterpret_cast<const char *>( my_q->column_text( 1 ) ) ) );
2960 if ( !val_is_short_term )
2962 val_letter =
static_cast<char>( my_q->column_int( 4 ) );
2963 val_num =
static_cast<uint64_t
>( my_q->column_int( 5 ) );
2967 id_p = ids.find( q0 );
2968 if ( id_p != ids.end() )
2971 if ( dont_abide_by_ids_second || id_p->second.second )
2973 _epmem_install_id_wme( my_agent, id_p->second.first, attr, &( ids ), q1, val_is_short_term, val_letter, val_num, id_record, retrieval_wmes );
2991 if ( !val_is_short_term )
2997 orphans.push( orphan );
3000 my_q->reinitialize();
3004 if ( !orphans.empty() )
3006 std::queue<epmem_edge *>::size_type orphans_left;
3007 std::queue<epmem_edge *> still_orphans;
3011 orphans_left = orphans.size();
3013 while ( !orphans.empty() )
3015 orphan = orphans.front();
3019 id_p = ids.find( orphan->
q0 );
3020 if ( id_p != ids.end() )
3022 if ( dont_abide_by_ids_second || id_p->second.second )
3034 still_orphans.push( orphan );
3038 orphans = still_orphans;
3039 while ( !still_orphans.empty() )
3041 still_orphans.pop();
3044 }
while ( ( !orphans.empty() ) && ( orphans_left != orphans.size() ) );
3046 while ( !orphans.empty() )
3048 orphan = orphans.front();
3066 std::pair< Symbol*, bool > parent;
3071 my_q->bind_int( 1, memory_id );
3072 my_q->bind_int( 2, memory_id );
3073 my_q->bind_int( 3, memory_id );
3074 my_q->bind_int( 4, memory_id );
3078 child_id = my_q->column_int( 0 );
3079 parent_id = my_q->column_int( 1 );
3080 attr_type = my_q->column_int( 4 );
3081 value_type = my_q->column_int( 5 );
3084 parent = ids[ parent_id ];
3086 if ( dont_abide_by_ids_second || parent.second )
3089 switch ( attr_type )
3100 attr =
make_sym_constant( my_agent, const_cast<char *>( reinterpret_cast<const char *>( my_q->column_text( 2 ) ) ) );
3105 switch ( value_type )
3116 value =
make_sym_constant( my_agent, const_cast<char *>( (
const char *) my_q->column_text( 3 ) ) );
3127 my_q->reinitialize();
3298 #define QUERY_DEBUG 0
3302 std::cout << std::endl;
3303 std::cout <<
"digraph {" << std::endl;
3304 std::cout <<
"node [style=\"filled\"];" << std::endl;
3306 std::cout <<
"subgraph cluster_literals {" << std::endl;
3307 std::cout <<
"node [fillcolor=\"#0084D1\"];" << std::endl;
3308 for (epmem_wme_literal_map::iterator lit_iter = literals.begin(); lit_iter != literals.end(); lit_iter++) {
3311 std::cout <<
"\"" << literal->
value_sym <<
"\" [";
3313 std::cout <<
"label=\"" << literal->
value_sym <<
"\"";
3315 std::cout <<
"label=\"" << literal->
q1 <<
"\"";
3318 std::cout <<
", shape=\"rect\"";
3320 if (literal->
matches.size() == 0) {
3321 std::cout <<
", penwidth=\"2.0\"";
3324 std::cout <<
", fillcolor=\"#C5000B\"";
3326 std::cout <<
"];" << std::endl;
3327 std::cout <<
"\"" << literal->
id_sym <<
"\" -> \"" << literal->
value_sym <<
"\" [label=\"";
3331 std::cout << literal->
w;
3333 std::cout <<
"\\n" << literal <<
"\"];" << std::endl;
3336 std::cout <<
"};" << std::endl;
3338 std::cout <<
"subgraph cluster_uedges{" << std::endl;
3339 std::cout <<
"node [fillcolor=\"#FFD320\"];" << std::endl;
3342 for (epmem_triple_uedge_map::iterator uedge_iter = uedge_cache->begin(); uedge_iter != uedge_cache->end(); uedge_iter++) {
3346 std::cout <<
"\"n" << triple.
q1 <<
"\" [shape=\"rect\"];" << std::endl;
3348 std::cout <<
"\"e" << triple.
q0 <<
"\" -> \"" << (type ==
EPMEM_RIT_STATE_NODE ?
"n" :
"e") << triple.
q1 <<
"\" [label=\"" << triple.
w <<
"\"];" << std::endl;
3352 std::cout <<
"};" << std::endl;
3354 std::cout <<
"subgraph cluster_pedges {" << std::endl;
3355 std::cout <<
"node [fillcolor=\"#008000\"];" << std::endl;
3356 std::multimap<epmem_node_id, epmem_pedge*> parent_pedge_map;
3358 for (epmem_triple_pedge_map::iterator pedge_iter = pedge_caches[type].begin(); pedge_iter != pedge_caches[type].end(); pedge_iter++) {
3362 std::cout <<
"\"" << pedge <<
"\" [label=\"" << pedge <<
"\\n(" << triple.
q0 <<
", " << triple.
w <<
", ";
3366 std::cout << triple.
q1;
3370 std::cout <<
", shape=\"rect\"";
3372 std::cout <<
"];" << std::endl;
3373 for (epmem_literal_set::iterator lit_iter = pedge->
literals.begin(); lit_iter != pedge->
literals.end(); lit_iter++) {
3375 std::cout <<
"\"" << literal->
value_sym <<
"\" -> \"" << pedge <<
"\";" << std::endl;
3377 parent_pedge_map.insert(std::make_pair(triple.
q0, pedge));
3381 std::cout <<
"};" << std::endl;
3383 std::set<std::pair<epmem_pedge*, epmem_node_id> > drawn;
3386 for (epmem_triple_uedge_map::iterator uedge_iter = uedge_cache->begin(); uedge_iter != uedge_cache->end(); uedge_iter++) {
3390 for (epmem_pedge_set::iterator pedge_iter = uedge->
pedges.begin(); pedge_iter != uedge->
pedges.end(); pedge_iter++) {
3392 std::pair<epmem_pedge*, epmem_node_id> pair = std::make_pair(pedge, triple.
q0);
3393 if (!drawn.count(pair)) {
3395 std::cout <<
"\"" << pedge <<
"\" -> \"e" << triple.
q0 <<
"\";" << std::endl;
3397 std::cout <<
"\"" << pedge <<
"\" -> \"" << (pedge->
value_is_id ?
"e" :
"n") << triple.
q1 <<
"\" [style=\"dashed\"];" << std::endl;
3398 std::pair<std::multimap<epmem_node_id, epmem_pedge*>::iterator, std::multimap<epmem_node_id, epmem_pedge*>::iterator> pedge_iters = parent_pedge_map.equal_range(triple.
q1);
3399 for (std::multimap<epmem_node_id, epmem_pedge*>::iterator pedge_iter = pedge_iters.first; pedge_iter != pedge_iters.second; pedge_iter++) {
3400 std::cout <<
"\"" << pedge <<
"\" -> \"" << (*pedge_iter).second <<
"\";" << std::endl;
3406 std::cout <<
"}" << std::endl;
3416 if (visiting.count(cue_wme->
value)) {
3420 if (literal_cache.count(cue_wme)) {
3421 return literal_cache[cue_wme];
3424 cue_wmes.insert(cue_wme);
3435 leaf_literals.insert(literal);
3445 leaf_literals.insert(literal);
3448 literal->
parents.~epmem_literal_set();
3449 literal->
children.~epmem_literal_set();
3461 if (children->empty()) {
3463 leaf_literals.insert(literal);
3467 visiting.insert(cue_wme->
value);
3468 for (epmem_wme_list::iterator wme_iter = children->begin(); wme_iter != children->end(); wme_iter++) {
3471 epmem_literal* child =
epmem_build_dnf(*wme_iter, literal_cache, leaf_literals, symbol_num_incoming, gm_ordering, currents, query_type, visiting, cue_wmes, my_agent);
3473 child->
parents.insert(literal);
3480 visiting.erase(cue_wme->
value);
3484 if (cycle && literal->
children.empty()) {
3485 literal->
parents.~epmem_literal_set();
3486 literal->
children.~epmem_literal_set();
3491 epmem_symbol_int_map::iterator rem_iter = symbol_num_incoming.find(value);
3492 if (rem_iter == symbol_num_incoming.end()) {
3493 symbol_num_incoming[value] = 1;
3495 (*rem_iter).second++;
3501 gm_ordering.push_front(literal);
3506 literal->
is_current = (currents.count(value) > 0);
3510 #ifdef USE_MEM_POOL_ALLOCATORS
3517 literal_cache[cue_wme] = literal;
3528 std::cout <<
" RECURSING ON " << parent <<
" " << literal << std::endl;
3533 epmem_triple_pedge_map::iterator pedge_iter = pedge_cache->find(triple);
3535 if (pedge_iter == pedge_cache->end() || (*pedge_iter).second == NULL) {
3540 pedge_sql->
bind_int(bind_pos++, LLONG_MAX);
3543 pedge_sql->
bind_int(bind_pos++, triple.
w);
3548 pedge_sql->
bind_int(bind_pos++, after);
3553 child_pedge->
triple = triple;
3556 child_pedge->
sql = pedge_sql;
3558 child_pedge->
literals.insert(literal);
3560 pedge_pq.push(child_pedge);
3561 (*pedge_cache)[triple] = child_pedge;
3567 }
else if (!child_pedge->
literals.count(literal)) {
3568 child_pedge->
literals.insert(literal);
3574 bool created =
false;
3576 for (epmem_triple_uedge_map::iterator uedge_iter = uedge_cache->lower_bound(triple); uedge_iter != uedge_cache->end(); uedge_iter++) {
3579 if (child_triple.
q0 != triple.
q0 || child_triple.
w != triple.
w) {
3584 for (epmem_literal_set::iterator child_iter = literal->
children.begin(); child_iter != literal->
children.end(); child_iter++) {
3585 created |=
epmem_register_pedges(child_triple.
q1, *child_iter, pedge_pq, after, pedge_caches, uedge_caches, my_agent);
3596 epmem_symbol_node_pair_int_map::iterator match_iter;
3598 std::cout <<
" RECURSING ON " << parent <<
" " << child <<
" " << literal << std::endl;
3601 bool parents_satisfied = (literal->
id_sym == NULL);
3602 if (!parents_satisfied) {
3606 int num_incoming = symbol_num_incoming[literal->
id_sym];
3607 match_iter = symbol_node_count.find(std::make_pair(literal->
id_sym, parent));
3609 parents_satisfied = (match_iter != symbol_node_count.end()) && ((*match_iter).second == num_incoming);
3612 if (parents_satisfied) {
3614 literal->
matches.insert(std::make_pair(parent, child));
3615 epmem_node_int_map::iterator values_iter = literal->
values.find(child);
3616 if (values_iter == literal->
values.end()) {
3617 literal->
values[child] = 1;
3619 if (literal->
matches.size() == 1) {
3620 current_score += literal->
weight;
3621 current_cardinality += (literal->
is_neg_q ? -1 : 1);
3623 std::cout <<
" NEW SCORE: " << current_score <<
", " << current_cardinality << std::endl;
3628 bool changed_score =
false;
3631 match_iter = symbol_node_count.find(match);
3632 if (match_iter == symbol_node_count.end()) {
3633 symbol_node_count[match] = 1;
3635 symbol_node_count[match]++;
3638 for (epmem_literal_set::iterator child_iter = literal->
children.begin(); child_iter != literal->
children.end(); child_iter++) {
3642 epmem_triple_uedge_map::iterator uedge_iter;
3645 uedge_iter = uedge_cache->lower_bound(child_triple);
3646 while (uedge_iter != uedge_cache->end()) {
3647 child_triple = (*uedge_iter).first;
3648 child_uedge = (*uedge_iter).second;
3649 if (child_triple.
q0 != child || child_triple.
w != child_lit->
w) {
3653 changed_score |=
epmem_satisfy_literal(child_lit, child_triple.
q0, child_triple.
q1, current_score, current_cardinality, symbol_node_count, uedge_caches, symbol_num_incoming);
3658 uedge_iter = uedge_cache->find(child_triple);
3659 child_uedge = (*uedge_iter).second;
3661 changed_score |=
epmem_satisfy_literal(child_lit, child_triple.
q0, child_triple.
q1, current_score, current_cardinality, symbol_node_count, uedge_caches, symbol_num_incoming);
3665 return changed_score;
3668 (*values_iter).second++;
3675 epmem_symbol_int_map::iterator count_iter;
3676 if (literal->
matches.size() == 0) {
3680 std::cout <<
" RECURSING ON " << parent <<
" " << child <<
" " << literal << std::endl;
3683 epmem_node_pair_set::iterator lit_match_iter = literal->
matches.find(std::make_pair(parent, child));
3684 if (lit_match_iter != literal->
matches.end()) {
3686 literal->
matches.erase(lit_match_iter);
3687 epmem_node_int_map::iterator values_iter = literal->
values.find(child);
3688 (*values_iter).second--;
3689 if ((*values_iter).second == 0) {
3690 literal->
values.erase(values_iter);
3692 if (literal->
matches.size() == 0) {
3693 current_score -= literal->
weight;
3694 current_cardinality -= (literal->
is_neg_q ? -1 : 1);
3696 std::cout <<
" NEW SCORE: " << current_score <<
", " << current_cardinality << std::endl;
3701 bool changed_score =
false;
3703 epmem_symbol_node_pair_int_map::iterator match_iter = symbol_node_count.find(match);
3704 (*match_iter).second--;
3705 if ((*match_iter).second == 0) {
3706 symbol_node_count.erase(match_iter);
3710 if (literal->
matches.size() == 0) {
3711 for (epmem_literal_set::iterator child_iter = literal->
children.begin(); child_iter != literal->
children.end(); child_iter++) {
3713 for (epmem_node_pair_set::iterator node_iter = child_lit->
matches.begin(); node_iter != child_lit->
matches.end(); node_iter++) {
3714 changed_score |=
epmem_unsatisfy_literal(child_lit, (*node_iter).first, (*node_iter).second, current_score, current_cardinality, symbol_node_count);
3719 for (epmem_literal_set::iterator child_iter = literal->
children.begin(); child_iter != literal->
children.end(); child_iter++) {
3721 epmem_node_pair_set::iterator node_iter = child_lit->
matches.lower_bound(node_pair);
3722 if (node_iter != child_lit->
matches.end() && (*node_iter).first == child) {
3723 changed_score |=
epmem_unsatisfy_literal(child_lit, (*node_iter).first, (*node_iter).second, current_score, current_cardinality, symbol_node_count);
3727 return changed_score;
3735 if (dnf_iter == iter_end) {
3739 if (bindings.count(literal)) {
3742 epmem_literal_deque::iterator next_iter = dnf_iter;
3744 #ifdef USE_MEM_POOL_ALLOCATORS
3752 for (epmem_node_pair_set::iterator match_iter = literal->
matches.begin(); match_iter != literal->
matches.end(); match_iter++) {
3755 if (failed_parents.count(q0)) {
3759 for (
int i = 0; i < depth; i++) {
3762 std::cout <<
"TRYING " << literal <<
" " << q0 << std::endl;
3764 bool relations_okay =
true;
3766 for (epmem_literal_set::iterator parent_iter = literal->
parents.begin(); relations_okay && parent_iter != literal->
parents.end(); parent_iter++) {
3768 epmem_literal_node_pair_map::iterator bind_iter = bindings.find(parent);
3769 if (bind_iter != bindings.end() && (*bind_iter).second.second != q0) {
3770 relations_okay =
false;
3773 if (!relations_okay) {
3775 for (
int i = 0; i < depth; i++) {
3778 std::cout <<
"PARENT CONSTRAINT FAIL" << std::endl;
3780 failed_parents.insert(q0);
3784 epmem_node_symbol_map::iterator binder = bound_nodes[literal->
value_is_id].find(q1);
3785 if (binder != bound_nodes[literal->
value_is_id].end() && (*binder).second != literal->
value_sym) {
3786 failed_children.insert(q1);
3790 for (
int i = 0; i < depth; i++) {
3793 std::cout <<
"TRYING " << literal <<
" " << q0 <<
" " << q1 << std::endl;
3796 relations_okay =
false;
3799 for (epmem_literal_set::iterator child_iter = literal->
children.begin(); relations_okay && child_iter != literal->
children.end(); child_iter++) {
3801 epmem_literal_node_pair_map::iterator bind_iter = bindings.find(child);
3802 if (bind_iter != bindings.end() && (*bind_iter).second.first != q1) {
3803 relations_okay =
false;
3806 if (!relations_okay) {
3808 for (
int i = 0; i < depth; i++) {
3811 std::cout <<
"CHILD CONSTRAINT FAIL" << std::endl;
3813 failed_children.insert(q1);
3817 for (
int i = 0; i < depth; i++) {
3820 std::cout << literal <<
" " << q0 <<
" " << q1 << std::endl;
3823 bindings[literal] = std::make_pair(q0, q1);
3826 bool list_satisfied =
epmem_graph_match(next_iter, iter_end, bindings, bound_nodes, my_agent, depth + 1);
3829 if (list_satisfied) {
3832 bindings.erase(literal);
3839 for (
int i = 0; i < depth; i++) {
3842 std::cout <<
"EPIC FAIL" << std::endl;
3847 void epmem_process_query(
agent *my_agent,
Symbol *state,
Symbol *pos_query,
Symbol *neg_query,
epmem_time_list& prohibits,
epmem_time_id before,
epmem_time_id after,
epmem_symbol_set& currents,
soar_module::wme_set& cue_wmes,
soar_module::symbol_triple_list& meta_wmes,
soar_module::symbol_triple_list& retrieval_wmes,
int level=3) {
3849 if (pos_query == NULL) {
3861 std::cout << std::endl <<
"==========================" << std::endl << std::endl;
3867 if (!prohibits.empty()) {
3868 std::sort(prohibits.begin(), prohibits.end());
3878 #ifdef USE_MEM_POOL_ALLOCATORS
3906 double best_score = 0;
3907 bool best_graph_matched =
false;
3908 long int best_cardinality = 0;
3910 double current_score = 0;
3911 long int current_cardinality = 0;
3920 root_literal->
id_sym = NULL;
3924 root_literal->
is_leaf =
false;
3928 root_literal->
weight = 0.0;
3931 #ifdef USE_MEM_POOL_ALLOCATORS
3937 symbol_num_incoming[pos_query] = 1;
3938 literal_cache[NULL] = root_literal;
3940 std::set<Symbol*> visiting;
3941 visiting.insert(pos_query);
3942 visiting.insert(neg_query);
3944 Symbol* query_root = NULL;
3945 switch (query_type) {
3947 query_root = pos_query;
3950 query_root = neg_query;
3958 for (epmem_wme_list::iterator wme_iter = children->begin(); wme_iter != children->end(); wme_iter++) {
3959 epmem_literal* child =
epmem_build_dnf(*wme_iter, literal_cache, leaf_literals, symbol_num_incoming, gm_ordering, currents, query_type, visiting, cue_wmes, my_agent);
3962 child->
id_sym = pos_query;
3963 child->
parents.insert(root_literal);
3964 root_literal->
children.insert(child);
3973 double perfect_score = 0;
3974 int perfect_cardinality = 0;
3975 for (epmem_literal_set::iterator iter = leaf_literals.begin(); iter != leaf_literals.end(); iter++) {
3976 if (!(*iter)->is_neg_q) {
3977 perfect_score += (*iter)->weight;
3978 perfect_cardinality++;
3986 before = before - 1;
4001 root_pedge->
triple = triple;
4005 root_pedge->
literals.insert(root_literal);
4010 root_pedge->
time = LLONG_MAX;
4011 pedge_pq.push(root_pedge);
4016 root_uedge->
triple = triple;
4027 root_interval->
uedge = root_uedge;
4033 root_interval->
time = before;
4034 interval_pq.push(root_interval);
4035 interval_cleanup.insert(root_interval);
4042 #ifdef EPMEM_EXPERIMENT
4043 epmem_episodes_searched = 0;
4048 while (pedge_pq.size() && current_episode > after) {
4052 bool changed_score =
false;
4055 next_edge = pedge_pq.top()->time;
4058 while (pedge_pq.size() && (pedge_pq.top()->time == next_edge || pedge_pq.top()->time >= current_episode)) {
4065 std::cout <<
" EDGE " << triple.
q0 <<
"-" << triple.
w <<
"-" << triple.
q1 << std::endl;
4070 bool created =
false;
4071 for (epmem_literal_set::iterator literal_iter = pedge->
literals.begin(); literal_iter != pedge->
literals.end(); literal_iter++) {
4073 for (epmem_literal_set::iterator child_iter = literal->
children.begin(); child_iter != literal->
children.end(); child_iter++) {
4074 created |=
epmem_register_pedges(triple.
q1, *child_iter, pedge_pq, after, pedge_caches, uedge_caches, my_agent);
4084 epmem_triple_uedge_map::iterator uedge_iter = uedge_cache->find(triple);
4085 if (uedge_iter == uedge_cache->end()) {
4097 bool created =
false;
4112 switch (interval_type) {
4145 interval_sql->
bind_int(bind_pos++, current_episode);
4147 interval_sql->
bind_int(bind_pos++, edge_id);
4150 interval_sql->
bind_int(bind_pos++, promo_time);
4152 interval_sql->
bind_int(bind_pos++, current_episode);
4157 interval->
uedge = uedge;
4159 interval->
sql = interval_sql;
4160 interval_pq.push(interval);
4161 interval_cleanup.insert(interval);
4174 start_interval->
uedge = uedge;
4176 start_interval->
time = promo_time - 1;
4177 start_interval->
sql = NULL;
4178 interval_pq.push(start_interval);
4179 interval_cleanup.insert(start_interval);
4181 uedge->
pedges.insert(pedge);
4182 uedge_cache->insert(std::make_pair(triple, uedge));
4184 uedge->
pedges.~epmem_pedge_set();
4189 uedge->
pedges.insert(pedge);
4191 for (epmem_literal_set::iterator lit_iter = pedge->
literals.begin(); lit_iter != pedge->
literals.end(); lit_iter++) {
4194 changed_score |=
epmem_satisfy_literal(literal, triple.
q0, triple.
q1, current_score, current_cardinality, symbol_node_count, uedge_caches, symbol_num_incoming);
4204 pedge_pq.push(pedge);
4205 }
else if (pedge->
sql) {
4210 next_edge = (pedge_pq.empty() ? after : pedge_pq.top()->time);
4215 while (interval_pq.size() && interval_pq.top()->time > next_edge && current_episode > after) {
4217 std::cout <<
"EPISODE " << current_episode << std::endl;
4220 while (interval_pq.size() && interval_pq.top()->time >= current_episode) {
4226 std::cout <<
" INTERVAL (" << (interval->
is_end_point ?
"end" :
"start") <<
"): " << triple.
q0 <<
"-" << triple.
w <<
"-" << triple.
q1 << std::endl;
4231 for (epmem_pedge_set::iterator pedge_iter = uedge->
pedges.begin(); pedge_iter != uedge->
pedges.end(); pedge_iter++) {
4233 for (epmem_literal_set::iterator lit_iter = pedge->
literals.begin(); lit_iter != pedge->
literals.end(); lit_iter++) {
4236 changed_score |=
epmem_satisfy_literal(literal, triple.
q0, triple.
q1, current_score, current_cardinality, symbol_node_count, uedge_caches, symbol_num_incoming);
4242 for (epmem_pedge_set::iterator pedge_iter = uedge->
pedges.begin(); pedge_iter != uedge->
pedges.end(); pedge_iter++) {
4244 for (epmem_literal_set::iterator lit_iter = pedge->
literals.begin(); lit_iter != pedge->
literals.end(); lit_iter++) {
4253 interval_pq.push(interval);
4254 }
else if (interval->
sql) {
4256 interval->
sql = NULL;
4259 interval_cleanup.erase(interval);
4266 next_interval = (interval_pq.empty() ? after : interval_pq.top()->time);
4267 next_episode = (next_edge > next_interval ? next_edge : next_interval);
4270 while (prohibits.size() && prohibits.back() > current_episode) {
4271 prohibits.pop_back();
4274 while (prohibits.size() && current_episode > next_episode && current_episode == prohibits.back()) {
4276 prohibits.pop_back();
4285 SNPRINTF(buf, 254,
"CONSIDERING EPISODE (time, cardinality, score) (%lld, %ld, %f)\n", static_cast<long long int>(current_episode), current_cardinality, current_score);
4286 print(my_agent, buf);
4290 #ifdef EPMEM_EXPERIMENT
4291 epmem_episodes_searched++;
4299 if (current_episode > next_episode && changed_score && (best_episode ==
EPMEM_MEMID_NONE || current_score > best_score || (do_graph_match && current_score == best_score && !best_graph_matched))) {
4300 bool new_king =
false;
4302 best_episode = current_episode;
4303 best_score = current_score;
4304 best_cardinality = current_cardinality;
4308 if (current_cardinality == perfect_cardinality) {
4309 bool graph_matched =
false;
4310 if (do_graph_match) {
4312 std::sort(gm_ordering.begin(), gm_ordering.end());
4316 epmem_literal_deque::iterator begin = gm_ordering.begin();
4317 epmem_literal_deque::iterator end = gm_ordering.end();
4318 best_bindings.clear();
4321 std::cout <<
" GRAPH MATCH" << std::endl;
4325 graph_matched =
epmem_graph_match(begin, end, best_bindings, bound_nodes, my_agent, 2);
4328 if (!do_graph_match || graph_matched) {
4329 best_episode = current_episode;
4330 best_graph_matched =
true;
4337 SNPRINTF(buf, 254,
"NEW KING (perfect, graph-match): (%s, %s)\n", (current_cardinality == perfect_cardinality ?
"true" :
"false"), (best_graph_matched ?
"true" :
"false"));
4338 print(my_agent, buf);
4346 current_episode = next_episode;
4387 if (do_graph_match) {
4394 if (best_graph_matched) {
4401 for (epmem_literal_node_pair_map::iterator iter = best_bindings.begin(); iter != best_bindings.end(); iter++) {
4402 if ((*iter).first->value_is_id) {
4410 node_map_map[(*iter).second.second] = temp_sym;
4411 node_mem_map[(*iter).second.second] = NULL;
4420 if (best_graph_matched) {
4421 for (epmem_id_mapping::iterator iter = node_mem_map.begin(); iter != node_mem_map.end(); iter++) {
4422 epmem_id_mapping::iterator map_iter = node_map_map.find((*iter).first);
4423 if (map_iter != node_map_map.end() && (*iter).second) {
4434 for (epmem_interval_set::iterator iter = interval_cleanup.begin(); iter != interval_cleanup.end(); iter++) {
4436 if (interval->
sql) {
4442 for (epmem_triple_pedge_map::iterator iter = pedge_caches[type].begin(); iter != pedge_caches[type].end(); iter++) {
4447 pedge->
literals.~epmem_literal_set();
4450 for (epmem_triple_uedge_map::iterator iter = uedge_caches[type].begin(); iter != uedge_caches[type].end(); iter++) {
4452 uedge->
pedges.~epmem_pedge_set();
4456 for (epmem_wme_literal_map::iterator iter = literal_cache.begin(); iter != literal_cache.end(); iter++) {
4458 literal->
parents.~epmem_literal_set();
4459 literal->
children.~epmem_literal_set();
4460 literal->
matches.~epmem_node_pair_set();
4461 literal->
values.~epmem_node_int_map();
4481 to_string(
id, t2 );
4505 std::map< epmem_node_id, std::string > ltis;
4506 std::map< epmem_node_id, std::map< std::string, std::list< std::string > > > ep;
4509 std::string temp_s, temp_s2, temp_s3;
4518 bool val_is_short_term;
4538 temp_i =
static_cast<int64_t
>( my_q->
column_int( 1 ) );
4539 to_string( temp_i, temp_s );
4544 to_string( temp_d, temp_s );
4548 temp_s.assign( const_cast<char *>( reinterpret_cast<const char *>( my_q->
column_text( 1 ) ) ) );
4552 if ( val_is_short_term )
4558 temp_s2.assign(
"@" );
4559 temp_s2.push_back( static_cast< char >( my_q->
column_int( 4 ) ) );
4561 temp_i =
static_cast< uint64_t
>( my_q->
column_int( 5 ) );
4562 to_string( temp_i, temp_s3 );
4563 temp_s2.append( temp_s3 );
4565 ltis[ q1 ] = temp_s2;
4568 ep[ q0 ][ temp_s ].push_back( temp_s2 );
4591 switch ( attr_type )
4594 temp_i =
static_cast<int64_t
>( my_q->
column_int( 2 ) );
4595 to_string( temp_i, temp_s );
4600 to_string( temp_d, temp_s );
4604 temp_s.assign( const_cast<char *>( reinterpret_cast<const char *>( my_q->
column_text( 2 ) ) ) );
4608 switch ( value_type )
4611 temp_i =
static_cast<int64_t
>( my_q->
column_int( 3 ) );
4612 to_string( temp_i, temp_s2 );
4617 to_string( temp_d, temp_s2 );
4621 temp_s2.assign( const_cast<char *>( reinterpret_cast<const char *>( my_q->
column_text( 3 ) ) ) );
4625 ep[ parent_id ][ temp_s ].push_back( temp_s2 );
4634 std::map< epmem_node_id, std::string >::iterator lti_it;
4635 std::map< epmem_node_id, std::map< std::string, std::list< std::string > > >::iterator ep_it;
4636 std::map< std::string, std::list< std::string > >::iterator slot_it;
4637 std::list< std::string >::iterator val_it;
4639 for ( ep_it=ep.begin(); ep_it!=ep.end(); ep_it++ )
4644 lti_it = ltis.find( ep_it->first );
4645 if ( lti_it == ltis.end() )
4651 buf->append( lti_it->second );
4655 for ( slot_it=ep_it->second.begin(); slot_it!=ep_it->second.end(); slot_it++ )
4657 buf->append(
" ^" );
4658 buf->append( slot_it->first );
4660 for ( val_it=slot_it->second.begin(); val_it!=slot_it->second.end(); val_it++ )
4663 buf->append( *val_it );
4667 buf->append(
")\n" );
4690 buf->append(
"digraph epmem {\n" );
4701 std::map< epmem_node_id, std::string > stis;
4702 std::map< epmem_node_id, std::pair< std::string, std::string > > ltis;
4703 std::list< std::string > edges;
4704 std::map< epmem_node_id, std::string >::iterator sti_p;
4705 std::map< epmem_node_id, std::pair< std::string, std::string > >::iterator lti_p;
4711 std::string temp, temp2, temp3, temp4;
4715 bool val_is_short_term;
4720 temp.assign(
"ID_0" );
4721 stis.insert( std::make_pair< epmem_node_id, std::string >( 0, temp ) );
4740 temp.assign(
"ID_" );
4741 to_string( q0, temp2 );
4742 temp.append( temp2 );
4745 temp3.assign(
"ID_" );
4746 to_string( q1, temp2 );
4747 temp3.append( temp2 );
4750 if ( val_is_short_term )
4752 sti_p = stis.find( q1 );
4753 if ( sti_p == stis.end() )
4755 stis.insert( std::make_pair< epmem_node_id, std::string >( q1, temp3 ) );
4760 lti_p = ltis.find( q1 );
4762 if ( lti_p == ltis.end() )
4765 val_letter =
static_cast<char>( my_q->
column_int( 4 ) );
4766 to_string( val_letter, temp4 );
4767 val_num =
static_cast<uint64_t
>( my_q->
column_int( 5 ) );
4768 to_string( val_num, temp2 );
4769 temp4.append( temp2 );
4771 ltis.insert( std::make_pair<
epmem_node_id, std::pair< std::string, std::string > >( q1, std::make_pair< std::string, std::string >( temp3, temp4 ) ) );
4776 temp.append(
" -> " );
4777 temp.append( temp3 );
4780 temp.append(
" [ label=\"" );
4784 temp_i =
static_cast<int64_t
>( my_q->
column_int( 1 ) );
4785 to_string( temp_i, temp2 );
4790 to_string( temp_d, temp2 );
4794 temp2.assign( const_cast<char *>( reinterpret_cast<const char *>( my_q->
column_text( 1 ) ) ) );
4797 temp.append( temp2 );
4798 temp.append(
"\" ];\n" );
4800 edges.push_back( temp );
4809 buf->append(
"node [ shape = circle ];\n" );
4811 for ( sti_p=stis.begin(); sti_p!=stis.end(); sti_p++ )
4813 buf->append( sti_p->second );
4817 buf->append(
";\n" );
4822 buf->append(
"node [ shape = doublecircle ];\n" );
4824 for ( lti_p=ltis.begin(); lti_p!=ltis.end(); lti_p++ )
4826 buf->append( lti_p->second.first );
4827 buf->append(
" [ label=\"" );
4828 buf->append( lti_p->second.second );
4829 buf->append(
"\" ];\n" );
4832 buf->append(
"\n" );
4838 std::list< std::string >::iterator e_p;
4840 for ( e_p=edges.begin(); e_p!=edges.end(); e_p++ )
4842 buf->append( (*e_p) );
4855 std::list< std::string > edges;
4856 std::list< std::string > consts;
4858 std::string temp, temp2;
4876 temp.assign(
"ID_" );
4877 to_string( parent_id, temp2 );
4878 temp.append( temp2 );
4879 temp.append(
" -> C_" );
4880 to_string( child_id, temp2 );
4881 temp.append( temp2 );
4882 temp.append(
" [ label=\"" );
4885 switch ( attr_type )
4888 temp_i =
static_cast<int64_t
>( my_q->
column_int( 2 ) );
4889 to_string( temp_i, temp2 );
4894 to_string( temp_d, temp2 );
4898 temp2.assign( const_cast<char *>( reinterpret_cast<const char *>( my_q->
column_text( 2 ) ) ) );
4902 temp.append( temp2 );
4903 temp.append(
"\" ];\n" );
4904 edges.push_back( temp );
4906 temp.assign(
"C_" );
4907 to_string( child_id, temp2 );
4908 temp.append( temp2 );
4909 temp.append(
" [ label=\"" );
4912 switch ( value_type )
4915 temp_i =
static_cast<int64_t
>( my_q->
column_int( 3 ) );
4916 to_string( temp_i, temp2 );
4921 to_string( temp_d, temp2 );
4925 temp2.assign( const_cast<char *>( reinterpret_cast<const char *>( my_q->
column_text( 3 ) ) ) );
4929 temp.append( temp2 );
4930 temp.append(
"\" ];\n" );
4932 consts.push_back( temp );
4940 std::list< std::string >::iterator e_p;
4942 buf->append(
"node [ shape = plaintext ];\n" );
4944 for ( e_p=consts.begin(); e_p!=consts.end(); e_p++ )
4946 buf->append( (*e_p) );
4952 std::list< std::string >::iterator e_p;
4954 for ( e_p=edges.begin(); e_p!=edges.end(); e_p++ )
4956 buf->append( (*e_p) );
4964 buf->append(
"\n}\n" );
4987 bool new_memory =
false;
5041 void inline _epmem_respond_to_cmd_parse(
agent* my_agent,
epmem_wme_list* cmds,
bool& good_cue,
int& path,
epmem_time_id& retrieve,
Symbol*& next,
Symbol*& previous,
Symbol*& query,
Symbol*& neg_query,
epmem_time_list& prohibit,
epmem_time_id& before,
epmem_time_id& after,
epmem_symbol_set& currents,
soar_module::wme_set& cue_wmes )
5056 for ( epmem_wme_list::iterator w_p=cmds->begin(); w_p!=cmds->end(); w_p++ )
5058 cue_wmes.insert( (*w_p) );
5067 ( (*w_p)->value->ic.value > 0 ) )
5069 retrieve = (*w_p)->value->ic.value;
5082 next = (*w_p)->value;
5095 previous = (*w_p)->value;
5106 ( ( path == 0 ) || ( path == 3 ) ) &&
5110 query = (*w_p)->value;
5121 ( ( path == 0 ) || ( path == 3 ) ) &&
5122 ( neg_query == NULL ) )
5125 neg_query = (*w_p)->value;
5136 ( ( path == 0 ) || ( path == 3 ) ) )
5138 if ( ( before ==
EPMEM_MEMID_NONE ) || ( (*w_p)->value->ic.value < before ) )
5140 before = (*w_p)->value->ic.value;
5152 ( ( path == 0 ) || ( path == 3 ) ) )
5154 if ( after < (*w_p)->value->ic.value )
5156 after = (*w_p)->value->ic.value;
5168 ( ( path == 0 ) || ( path == 3 ) ) )
5170 prohibit.push_back( (*w_p)->value->ic.value );
5181 ( ( path == 0 ) || ( path == 3 ) ) )
5183 currents.insert( (*w_p)->value );
5199 if ( ( path == 3 ) && ( query == NULL ) )
5236 epmem_wme_list::iterator w_p;
5249 #ifdef USE_MEM_POOL_ALLOCATORS
5260 bool do_wm_phase =
false;
5262 while ( state != NULL )
5274 std::queue<Symbol *> syms;
5280 while ( !syms.empty() )
5283 parent_sym = syms.front();
5289 for ( w_p=wmes->begin(); w_p!=wmes->end(); w_p++ )
5301 syms.push( (*w_p)->value );
5335 if ( new_cue && wme_count )
5337 _epmem_respond_to_cmd_parse( my_agent, cmds, good_cue, path, retrieve, next, previous, query, neg_query, prohibit, before, after, currents, cue_wmes );
5343 retrieval_wmes.clear();
5355 else if ( path == 2 )
5382 else if ( path == 3 )
5384 epmem_process_query( my_agent, state, query, neg_query, prohibit, before, after, currents, cue_wmes, meta_wmes, retrieval_wmes );
5398 if ( !retrieval_wmes.empty() || !meta_wmes.empty() )
5405 soar_module::symbol_triple_list::iterator mw_it;
5407 for ( mw_it=retrieval_wmes.begin(); mw_it!=retrieval_wmes.end(); mw_it++ )
5415 retrieval_wmes.clear();
5417 for ( mw_it=meta_wmes.begin(); mw_it!=meta_wmes.end(); mw_it++ )
5465 #ifdef EPMEM_EXPERIMENT
5466 void inline _epmem_exp(
agent* my_agent )
5480 if ( !epmem_exp_timer )
5487 epmem_exp_timer->
reset();
5488 epmem_exp_timer->
start();
5489 epmem_dc_wme_adds = -1;
5491 epmem_exp_timer->
stop();
5492 c1 = epmem_exp_timer->
value();
5508 wme* queries_wme = queries_slot->
wmes;
5520 if ( reps_slot && output_slot && format_slot && commands_slot )
5522 wme* reps_wme = reps_slot->
wmes;
5523 wme* mod_wme = ( ( mod_slot )?( mod_slot->
wmes ):( NULL ) );
5524 wme* output_wme = output_slot->
wmes;
5525 wme* format_wme = format_slot->
wmes;
5526 wme* features_wme = ( ( features_slot )?( features_slot->
wmes ):( NULL ) );
5527 wme* commands_wme = commands_slot->
wmes;
5536 const char* output_fname = output_wme->
value->
sc.
name;
5537 bool format_csv = ( format_wme->
value == csv );
5538 std::list< std::pair< std::string, std::string > > output_contents;
5539 std::string temp_str, temp_str2;
5540 std::set< std::string > cmd_names;
5542 std::map< std::string, std::string > features;
5547 for (
wme* w=s->wmes; w; w=w->
next )
5552 features[ w->attr->sc.name ] = w->value->sc.name;
5564 for ( std::map< std::string, std::string >::iterator f_it=features.begin(); f_it!=features.end(); f_it++ )
5566 output_contents.push_back( std::make_pair< std::string, std::string >( f_it->first, f_it->second ) );
5572 output_contents.push_back( std::make_pair< std::string, std::string >(
"dc", temp_str ) );
5578 output_contents.push_back( std::make_pair< std::string, std::string >(
"episodes", temp_str ) );
5583 to_string( reps, temp_str );
5584 output_contents.push_back( std::make_pair< std::string, std::string >(
"reps", temp_str ) );
5590 output_contents.push_back( std::make_pair< std::string, std::string >(
"wmcurrent", temp_str ) );
5595 to_string( ( my_agent->
wme_addition_count - epmem_exp_state[ exp_state_wm_adds ] ), temp_str );
5596 output_contents.push_back( std::make_pair< std::string, std::string >(
"wmadds", temp_str ) );
5597 epmem_exp_state[ exp_state_wm_adds ] =
static_cast< int64_t
>( my_agent->
wme_addition_count );
5599 to_string( ( my_agent->
wme_removal_count - epmem_exp_state[ exp_state_wm_removes ] ), temp_str );
5600 output_contents.push_back( std::make_pair< std::string, std::string >(
"wmremoves", temp_str ) );
5601 epmem_exp_state[ exp_state_wm_removes ] =
static_cast< int64_t
>( my_agent->
wme_removal_count );
5606 to_string( epmem_dc_interval_inserts, temp_str );
5607 output_contents.push_back( std::make_pair< std::string, std::string >(
"dcintervalinserts", temp_str ) );
5609 to_string( epmem_dc_interval_removes, temp_str );
5610 output_contents.push_back( std::make_pair< std::string, std::string >(
"dcintervalremoves", temp_str ) );
5615 to_string( epmem_dc_wme_adds, temp_str );
5616 output_contents.push_back( std::make_pair< std::string, std::string >(
"dcwmeadds", temp_str ) );
5623 to_string( ( sqlite_mem - epmem_exp_state[ exp_state_sqlite_mem ] ), temp_str );
5624 output_contents.push_back( std::make_pair< std::string, std::string >(
"sqlitememadd", temp_str ) );
5625 epmem_exp_state[ exp_state_sqlite_mem ] = sqlite_mem;
5627 to_string( sqlite_mem, temp_str );
5628 output_contents.push_back( std::make_pair< std::string, std::string >(
"sqlitememcurrent", temp_str ) );
5633 to_string( c1, temp_str );
5635 output_contents.push_back( std::make_pair< std::string, std::string >(
"storage", temp_str ) );
5636 cmd_names.insert(
"storage" );
5642 output_contents.push_back( std::make_pair< std::string, std::string >( s->attr->sc.name,
"" ) );
5643 std::string searched =
"numsearched";
5644 searched.append(s->attr->sc.name);
5645 output_contents.push_back( std::make_pair< std::string, std::string >( searched ,
"" ) );
5650 if ( !epmem_exp_output )
5652 epmem_exp_output =
new std::ofstream( output_fname );
5656 for (
std::list< std::pair< std::string, std::string > >::iterator it=output_contents.begin(); it!=output_contents.end(); it++ )
5658 if ( it != output_contents.begin() )
5660 (*epmem_exp_output) <<
",";
5663 (*epmem_exp_output) <<
"\"" << it->first <<
"\"";
5666 (*epmem_exp_output) << std::endl;
5684 #ifdef USE_MEM_POOL_ALLOCATORS
5701 _epmem_respond_to_cmd_parse( my_agent, cmds, good_cue, path, retrieve, next, previous, query, neg_query, prohibit, before, after, currents, cue_wmes );
5704 if ( good_cue && ( path == 3 ) )
5709 epmem_exp_timer->
reset();
5710 epmem_exp_timer->
start();
5711 for ( int64_t i=1; i<=reps; i++ )
5713 epmem_process_query( my_agent, my_agent->
top_goal, query, neg_query, prohibit, before, after, currents, cue_wmes, meta_wmes, retrieval_wmes, 2 );
5715 if ( !retrieval_wmes.empty() || !meta_wmes.empty() )
5717 soar_module::symbol_triple_list::iterator mw_it;
5719 for ( mw_it=retrieval_wmes.begin(); mw_it!=retrieval_wmes.end(); mw_it++ )
5727 retrieval_wmes.clear();
5729 for ( mw_it=meta_wmes.begin(); mw_it!=meta_wmes.end(); mw_it++ )
5740 epmem_exp_timer->
stop();
5741 c_total = epmem_exp_timer->
value();
5746 to_string( c_total, temp_str );
5748 for (
std::list< std::pair< std::string, std::string > >::iterator oc_it=output_contents.begin(); oc_it!=output_contents.end(); oc_it++ )
5750 if ( oc_it->first.compare( s->attr->sc.name ) == 0 )
5752 oc_it->second.assign( temp_str );
5754 to_string( epmem_episodes_searched , temp_str );
5755 oc_it->second.assign( temp_str );
5759 cmd_names.insert( s->attr->sc.name );
5774 for (
std::list< std::pair< std::string, std::string > >::iterator it=output_contents.begin(); it!=output_contents.end(); it++ )
5776 if ( it != output_contents.begin() )
5778 (*epmem_exp_output) <<
",";
5781 (*epmem_exp_output) <<
"\"" << it->second <<
"\"";
5784 (*epmem_exp_output) << std::endl;
5788 for ( std::set< std::string >::iterator c_it=cmd_names.begin(); c_it!=cmd_names.end(); c_it++ )
5790 for (
std::list< std::pair< std::string, std::string > >::iterator it=output_contents.begin(); it!=output_contents.end(); it++ )
5792 if ( cmd_names.find( it->first ) == cmd_names.end() )
5794 if ( it->first.substr( 0, 11 ).compare(
"numsearched" ) == 0 )
5799 if ( it != output_contents.begin() )
5801 (*epmem_exp_output) <<
" ";
5803 if ( ( it->first.compare(
"reps" ) == 0 ) && ( c_it->compare(
"storage" ) == 0 ) )
5805 (*epmem_exp_output) << it->first <<
"=" <<
"1";
5809 (*epmem_exp_output) << it->first <<
"=" << it->second;
5812 else if ( c_it->compare( it->first ) == 0 )
5814 (*epmem_exp_output) <<
" command=" << it->first <<
" totalsec=" << it->second;
5815 if ( it->first.compare(
"storage" ) == 0 ) {
5816 (*epmem_exp_output) <<
" numsearched=0";
5820 (*epmem_exp_output) <<
" numsearched=" << it->second;
5826 (*epmem_exp_output) << std::endl;
5858 #ifndef EPMEM_EXPERIMENT
5866 #else // EPMEM_EXPERIMENT
5868 _epmem_exp( my_agent );
5871 #endif // EPMEM_EXPERIMENT
5879 bool return_val =
false;
5897 err->assign(
"Episodic database is not currently connected." );