Soar Kernel  9.3.2 08-06-12
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
symtab.cpp
Go to the documentation of this file.
1 #include <portability.h>
2 
3 /*************************************************************************
4  * PLEASE SEE THE FILE "license.txt" (INCLUDED WITH THIS SOFTWARE PACKAGE)
5  * FOR LICENSE AND COPYRIGHT INFORMATION.
6  *************************************************************************/
7 
8 /*************************************************************************
9  *
10  * file: symtab.cpp
11  *
12  * =======================================================================
13  *
14  * Symbol Table Routines for Soar 6
15  *
16  * Soar 6 uses five kinds of symbols: symbolic constants, integer
17  * constants, floating-point constants, identifiers, and variables.
18  * We use five resizable hash tables, one for each kind of symbol.
19  *
20  * "symbol" is typedef-ed as a union of the five kinds of symbol
21  * structures. Some fields common to all symbols are accessed via
22  * sym->common.field_name; fields particular to a certain kind of
23  * symbol are accessed via sym->var.field_name_on_variables, etc.
24  * See soarkernel.h for the Symbol structure definitions.
25  *
26  * =======================================================================
27  */
28 
29 /* Uncomment the following line to get symbol debugging printouts */
30 //#define DEBUG_SYMBOLS
31 
32 #include <stdlib.h>
33 
34 #include "symtab.h"
35 #include "mem.h"
36 #include "kernel.h"
37 #include "agent.h"
38 #include "production.h"
39 #include "init_soar.h"
40 #include "print.h"
41 #include "xml.h"
42 
43 #include <ctype.h>
44 
45 /* -------------------------------------------------------------------
46  Hash Functions
47 
48  Compress() takes a 32-bit hash value and compresses it down to a few
49  bits, xor-ing pieces of the 32-bit value to avoid throwing away bits
50  that might be important for the hash function to be effective.
51 
52  Hash_string() produces a hash value for a string of characters.
53 
54  Hash_xxx_raw_info() are the hash functions for the five kinds of
55  symbols. These functions operate on the basic info about the symbol
56  (i.e., the name, value, etc.). Hash_xxx(), on the other hand,
57  operate on the symbol table entries for the five kinds of symbols--
58  these routines are the callback hashing functions used by the
59  resizable hash table routines.
60 ------------------------------------------------------------------- */
61 
62 uint32_t compress (uint32_t h, short num_bits) {
63  uint32_t result;
64 
65  if (num_bits < 16) h = (h & 0xFFFF) ^ (h >> 16);
66  if (num_bits < 8) h = (h & 0xFF) ^ (h >> 8);
67  result = 0;
68  while (h) {
69  result ^= (h & masks_for_n_low_order_bits[num_bits]);
70  h = h >> num_bits;
71  }
72  return result;
73 }
74 
75 uint32_t hash_string (const char *s) { /* AGR 600 */
76  uint32_t h;
77 
78  h = 0;
79  while (*s != 0) {
80  h = ((h << 8) | (h >> 24)) ^ (*s);
81  s++;
82  }
83  return h;
84 }
85 
86 /* -----------------------------------------
87  Hashing symbols using their basic info
88 ----------------------------------------- */
89 
90 uint32_t hash_variable_raw_info (const char *name, short num_bits) {
91  return compress (hash_string(name), num_bits);
92 }
93 
95  uint64_t name_number,
96  short num_bits) {
97  return compress (static_cast<uint32_t>(name_number) ^ (static_cast<uint32_t>(name_letter) << 24), num_bits); // FIXME: cast from 64 to 32 bits
98 }
99 
100 uint32_t hash_sym_constant_raw_info (const char *name, short num_bits) {
101  return compress (hash_string(name), num_bits);
102 }
103 
104 uint32_t hash_int_constant_raw_info (int64_t value, short num_bits) {
105  return compress (static_cast<uint32_t>(value), num_bits);
106 }
107 
108 uint32_t hash_float_constant_raw_info (double value, short num_bits) {
109  return compress (static_cast<uint32_t>(value), num_bits);
110 }
111 
112 /* ---------------------------------------------------
113  Hashing symbols using their symbol table entries
114 --------------------------------------------------- */
115 
116 uint32_t hash_variable (void *item, short num_bits) {
117  variable *var;
118  var = static_cast<variable_struct *>(item);
119  return compress (hash_string(var->name),num_bits);
120 }
121 
122 uint32_t hash_identifier (void *item, short num_bits) {
123  identifier *id;
124  id = static_cast<identifier_struct *>(item);
125  return compress (static_cast<uint32_t>(id->name_number) ^ (static_cast<uint32_t>(id->name_letter) << 24), num_bits); // FIXME: cast from 64 to 32 bits
126 }
127 
128 uint32_t hash_sym_constant (void *item, short num_bits) {
129  sym_constant *sc;
130  sc = static_cast<sym_constant_struct *>(item);
131  return compress (hash_string(sc->name),num_bits);
132 }
133 
134 uint32_t hash_int_constant (void *item, short num_bits) {
135  int_constant *ic;
136  ic = static_cast<int_constant_struct *>(item);
137  return compress (static_cast<uint32_t>(ic->value),num_bits);
138 }
139 
140 uint32_t hash_float_constant (void *item, short num_bits) {
141  float_constant *fc;
142  fc = static_cast<float_constant_struct *>(item);
143  return compress (static_cast<uint32_t>(fc->value),num_bits);
144 }
145 
146 /* -------------------------------------------------------------------
147 
148  Basic Symbol Table Data Structures and Initialization
149 
150 ------------------------------------------------------------------- */
151 
152 //#define get_next_symbol_hash_id() (thisAgent->current_symbol_hash_id += 137)
154 {
155  return (thisAgent->current_symbol_hash_id += 137);
156 }
157 
158 void init_symbol_tables (agent* thisAgent) {
159  thisAgent->variable_hash_table = make_hash_table (thisAgent, 0, hash_variable);
160  thisAgent->identifier_hash_table = make_hash_table (thisAgent, 0, hash_identifier);
161  thisAgent->sym_constant_hash_table = make_hash_table (thisAgent, 0, hash_sym_constant);
162  thisAgent->int_constant_hash_table = make_hash_table (thisAgent, 0, hash_int_constant);
164 
165  init_memory_pool (thisAgent, &thisAgent->variable_pool, sizeof(variable), "variable");
166  init_memory_pool (thisAgent, &thisAgent->identifier_pool, sizeof(identifier), "identifier");
167  init_memory_pool (thisAgent, &thisAgent->sym_constant_pool, sizeof(sym_constant), "sym constant");
168  init_memory_pool (thisAgent, &thisAgent->int_constant_pool, sizeof(int_constant), "int constant");
169  init_memory_pool (thisAgent, &thisAgent->float_constant_pool, sizeof(float_constant),
170  "float constant");
171 
172  reset_id_counters( thisAgent );
173 }
174 
175 /* -------------------------------------------------------------------
176  Symbol Table Lookup and Symbol Creation Routines
177 
178  The find_xxx() routines look for an existing symbol and return it
179  if found; if no such symbol exists, they return NIL.
180 
181  The make_xxx() routines look for an existing symbol; if the find one,
182  they increment the reference count and return it. If no such symbol
183  exists, they create a new one, set the reference count to 1, and
184  return it.
185 
186  Note that rather than a make_identifier() routine, we have a
187  make_new_identifier() routine, which takes two arguments: the first
188  letter for the new identifier, and its initial goal_stack_level.
189  There is no way to force creation of an identifier with a particular
190  name letter/number combination like J37.
191 ------------------------------------------------------------------- */
192 
193 Symbol *find_variable (agent* thisAgent, const char *name) {
194  uint32_t hash_value;
195  Symbol *sym;
196 
197  hash_value = hash_variable_raw_info (name,thisAgent->variable_hash_table->log2size);
198  sym = reinterpret_cast<Symbol *>(*(thisAgent->variable_hash_table->buckets + hash_value));
199  for ( ; sym!=NIL; sym = sym->common.next_in_hash_table) {
200  if (!strcmp(sym->var.name,name)) return sym;
201  }
202  return NIL;
203 }
204 
205 Symbol *find_identifier (agent* thisAgent, char name_letter, uint64_t name_number) {
206  uint32_t hash_value;
207  Symbol *sym;
208 
209  hash_value = hash_identifier_raw_info (name_letter,name_number,
210  thisAgent->identifier_hash_table->log2size);
211  sym = reinterpret_cast<Symbol *>(*(thisAgent->identifier_hash_table->buckets + hash_value));
212  for ( ; sym!=NIL; sym = sym->common.next_in_hash_table) {
213  if ((name_letter==sym->id.name_letter) &&
214  (name_number==sym->id.name_number)) return sym;
215  }
216  return NIL;
217 }
218 
219 Symbol *find_sym_constant (agent* thisAgent, const char *name) {
220  uint32_t hash_value;
221  Symbol *sym;
222 
223  hash_value = hash_sym_constant_raw_info (name,
224  thisAgent->sym_constant_hash_table->log2size);
225  sym = reinterpret_cast<Symbol *>(*(thisAgent->sym_constant_hash_table->buckets + hash_value));
226  for ( ; sym!=NIL; sym = sym->common.next_in_hash_table) {
227  if (!strcmp(sym->sc.name,name)) return sym;
228  }
229  return NIL;
230 }
231 
232 Symbol *find_int_constant (agent* thisAgent, int64_t value) {
233  uint32_t hash_value;
234  Symbol *sym;
235 
236  hash_value = hash_int_constant_raw_info (value,
237  thisAgent->int_constant_hash_table->log2size);
238  sym = reinterpret_cast<Symbol *>(*(thisAgent->int_constant_hash_table->buckets + hash_value));
239  for ( ; sym!=NIL; sym = sym->common.next_in_hash_table) {
240  if (value==sym->ic.value) return sym;
241  }
242  return NIL;
243 }
244 
245 Symbol *find_float_constant (agent* thisAgent, double value) {
246  uint32_t hash_value;
247  Symbol *sym;
248 
249  hash_value = hash_float_constant_raw_info (value,
250  thisAgent->float_constant_hash_table->log2size);
251  sym = reinterpret_cast<Symbol *>(*(thisAgent->float_constant_hash_table->buckets + hash_value));
252  for ( ; sym!=NIL; sym = sym->common.next_in_hash_table) {
253  if (value==sym->fc.value) return sym;
254  }
255  return NIL;
256 }
257 
258 Symbol *make_variable (agent* thisAgent, const char *name) {
259  Symbol *sym;
260 
261  sym = find_variable(thisAgent, name);
262  if (sym) {
263  symbol_add_ref(sym);
264  } else {
265  allocate_with_pool (thisAgent, &thisAgent->variable_pool, &sym);
266  sym->common.symbol_type = VARIABLE_SYMBOL_TYPE;
267  sym->common.reference_count = 1;
268  sym->common.hash_id = get_next_symbol_hash_id(thisAgent);
269  sym->var.name = make_memory_block_for_string (thisAgent, name);
270  sym->var.gensym_number = 0;
271  sym->var.tc_num = 0;
273  add_to_hash_table (thisAgent, thisAgent->variable_hash_table, sym);
274 #ifdef DEBUG_SYMBOL_REFCOUNTS
275  char buf[64];
276  OutputDebugString(symbol_to_string(thisAgent, sym, FALSE, buf, 64));
277  OutputDebugString(":+ \n");
278 #endif // DEBUG_SYMBOL_REFCOUNTS
279  }
280  return sym;
281 }
282 
283 Symbol *make_new_identifier (agent* thisAgent, char name_letter, goal_stack_level level, uint64_t name_number) {
284  Symbol *sym;
285 
286  if (isalpha(name_letter)) {
287  if (islower(name_letter)) name_letter = static_cast<char>(toupper(name_letter));
288  } else {
289  name_letter = 'I';
290  }
291  allocate_with_pool (thisAgent, &thisAgent->identifier_pool, &sym);
292  sym->common.symbol_type = IDENTIFIER_SYMBOL_TYPE;
293  sym->common.reference_count = 1;
294  sym->common.hash_id = get_next_symbol_hash_id(thisAgent);
295  sym->id.name_letter = name_letter;
296 
297  // NLD: modified for long-term identifiers
298  if ( name_number == NIL )
299  {
300  name_number = thisAgent->id_counter[name_letter-'A']++;
301  }
302  else
303  {
304  uint64_t *current_number = &( thisAgent->id_counter[ name_letter - 'A' ] );
305  if ( name_number >= (*current_number) )
306  {
307  (*current_number) = ( name_number + 1 );
308  }
309  }
310  sym->id.name_number = name_number;
311 
312  sym->id.level = level;
313  sym->id.promotion_level = level;
314  sym->id.slots = NIL;
315  sym->id.isa_goal = FALSE;
316  sym->id.isa_impasse = FALSE;
317  sym->id.isa_operator = 0;
318  sym->id.link_count = 0;
319  sym->id.unknown_level = NIL;
321  sym->id.impasse_wmes = NIL;
322  sym->id.higher_goal = NIL;
323 /* REW: begin 09.15.96 */
324  sym->id.gds = NIL;
325 /* REW: end 09.15.96 */
326 /* REW: begin 08.20.97 */
328  sym->id.ms_o_assertions = NIL;
329  sym->id.ms_i_assertions = NIL;
330  sym->id.ms_retractions = NIL;
331 /* REW: end 08.20.97 */
332  sym->id.lower_goal = NIL;
333  sym->id.operator_slot = NIL;
335  sym->id.tc_num = 0;
337  sym->id.input_wmes = NIL;
338 
339  sym->id.rl_info = NIL;
340  sym->id.reward_header = NIL;
341 
342  sym->id.epmem_header = NIL;
343  sym->id.epmem_cmd_header = NIL;
344  sym->id.epmem_result_header = NIL;
346  sym->id.epmem_valid = NIL;
347  sym->id.epmem_time_wme = NIL;
348 
349  sym->id.smem_header = NIL;
350  sym->id.smem_cmd_header = NIL;
351  sym->id.smem_result_header = NIL;
352  sym->id.smem_lti = NIL;
354  sym->id.smem_valid = NIL;
355 
356 
357  add_to_hash_table (thisAgent, thisAgent->identifier_hash_table, sym);
358 #ifdef DEBUG_SYMBOL_REFCOUNTS
359  char buf[64];
360  OutputDebugString(symbol_to_string(thisAgent, sym, FALSE, buf, 64));
361  OutputDebugString(":+ \n");
362 #endif // DEBUG_SYMBOL_REFCOUNTS
363  return sym;
364 }
365 
366 Symbol *make_sym_constant (agent* thisAgent, char const*name) {
367  Symbol *sym;
368 
369  sym = find_sym_constant(thisAgent, name);
370  if (sym) {
371  symbol_add_ref(sym);
372  } else {
373  allocate_with_pool (thisAgent, &thisAgent->sym_constant_pool, &sym);
374  sym->common.symbol_type = SYM_CONSTANT_SYMBOL_TYPE;
375  sym->common.reference_count = 1;
376  sym->common.hash_id = get_next_symbol_hash_id(thisAgent);
377  sym->common.epmem_hash = 0;
378  sym->common.epmem_valid = 0;
379  sym->common.smem_hash = 0;
380  sym->common.smem_valid = 0;
381  sym->sc.name = make_memory_block_for_string (thisAgent, name);
382  sym->sc.production = NIL;
383  add_to_hash_table (thisAgent, thisAgent->sym_constant_hash_table, sym);
384 #ifdef DEBUG_SYMBOL_REFCOUNTS
385  char buf[64];
386  OutputDebugString(symbol_to_string(thisAgent, sym, FALSE, buf, 64));
387  OutputDebugString(":+ \n");
388 #endif // DEBUG_SYMBOL_REFCOUNTS
389  }
390  return sym;
391 }
392 
393 Symbol *make_int_constant (agent* thisAgent, int64_t value) {
394  Symbol *sym;
395 
396  sym = find_int_constant(thisAgent, value);
397  if (sym) {
398  symbol_add_ref(sym);
399  } else {
400  allocate_with_pool (thisAgent, &thisAgent->int_constant_pool, &sym);
401  sym->common.symbol_type = INT_CONSTANT_SYMBOL_TYPE;
402  sym->common.reference_count = 1;
403  sym->common.hash_id = get_next_symbol_hash_id(thisAgent);
404  sym->common.epmem_hash = 0;
405  sym->common.epmem_valid = 0;
406  sym->common.smem_hash = 0;
407  sym->common.smem_valid = 0;
408  sym->ic.value = value;
409  add_to_hash_table (thisAgent, thisAgent->int_constant_hash_table, sym);
410 #ifdef DEBUG_SYMBOL_REFCOUNTS
411  char buf[64];
412  OutputDebugString(symbol_to_string(thisAgent, sym, FALSE, buf, 64));
413  OutputDebugString(":+ \n");
414 #endif // DEBUG_SYMBOL_REFCOUNTS
415  }
416  return sym;
417 }
418 
419 Symbol *make_float_constant (agent* thisAgent, double value) {
420  Symbol *sym;
421 
422  sym = find_float_constant(thisAgent, value);
423  if (sym) {
424  symbol_add_ref(sym);
425  } else {
426  allocate_with_pool (thisAgent, &thisAgent->float_constant_pool, &sym);
427  sym->common.symbol_type = FLOAT_CONSTANT_SYMBOL_TYPE;
428  sym->common.reference_count = 1;
429  sym->common.hash_id = get_next_symbol_hash_id(thisAgent);
430  sym->common.epmem_hash = 0;
431  sym->common.epmem_valid = 0;
432  sym->common.smem_hash = 0;
433  sym->common.smem_valid = 0;
434  sym->fc.value = value;
435  add_to_hash_table (thisAgent, thisAgent->float_constant_hash_table, sym);
436 #ifdef DEBUG_SYMBOL_REFCOUNTS
437  char buf[64];
438  OutputDebugString(symbol_to_string(thisAgent, sym, FALSE, buf, 64));
439  OutputDebugString(":+ \n");
440 #endif // DEBUG_SYMBOL_REFCOUNTS
441  }
442  return sym;
443 }
444 
445 /* -------------------------------------------------------------------
446 
447  Deallocate Symbol
448 
449 ------------------------------------------------------------------- */
450 
451 void deallocate_symbol (agent* thisAgent, Symbol *sym) {
452 
453 #ifdef DEBUG_SYMBOLS
454  print_with_symbols (thisAgent, "\nDeallocating Symbol %y", sym);
455 #endif
456 
457  switch (sym->common.symbol_type) {
459  remove_from_hash_table (thisAgent, thisAgent->variable_hash_table, sym);
460  free_memory_block_for_string (thisAgent, sym->var.name);
461  free_with_pool (&thisAgent->variable_pool, sym);
462  break;
464  remove_from_hash_table (thisAgent, thisAgent->identifier_hash_table, sym);
465  free_with_pool (&thisAgent->identifier_pool, sym);
466  break;
468  remove_from_hash_table (thisAgent, thisAgent->sym_constant_hash_table, sym);
469  free_memory_block_for_string (thisAgent, sym->sc.name);
470  free_with_pool (&thisAgent->sym_constant_pool, sym);
471  break;
473  remove_from_hash_table (thisAgent, thisAgent->int_constant_hash_table, sym);
474  free_with_pool (&thisAgent->int_constant_pool, sym);
475  break;
477  remove_from_hash_table (thisAgent, thisAgent->float_constant_hash_table, sym);
478  free_with_pool (&thisAgent->float_constant_pool, sym);
479  break;
480  default:
481  { char msg[BUFFER_MSG_SIZE];
482  strncpy (msg, "Internal error: called deallocate_symbol on non-symbol.\n", BUFFER_MSG_SIZE);
483  msg[BUFFER_MSG_SIZE - 1] = 0; /* ensure null termination */
484  abort_with_fatal_error(thisAgent, msg);
485  }
486  }
487 }
488 
489 /* -------------------------------------------------------------------
490  Other Symbol Utilities
491 
492  Reset_id_counters() is called during an init-soar to reset the id
493  gensym numbers to 1. It first makes sure there are no existing
494  identifiers in the system--otherwise we might generate a second
495  identifier with the same name later on.
496 
497  Reset_id_and_variable_tc_numbers() resets the tc_num field of every
498  existing id and variable to 0.
499 
500  Reset_variable_gensym_numbers() resets the gensym_number field of
501  every existing variable to 0.
502 
503  Print_internal_symbols() just prints a list of all existing symbols.
504  (This is useful for debugging memory leaks.)
505 
506  Generate_new_sym_constant() is used to gensym new symbols that are
507  guaranteed to not already exist. It takes two arguments: "prefix"
508  (the desired prefix of the new symbol's name), and "counter" (a
509  pointer to a counter (uint64_t) that is incremented to produce
510  new gensym names).
511 ------------------------------------------------------------------- */
512 
513 Bool print_identifier_ref_info(agent* thisAgent, void* item, void* userdata) {
514  Symbol* sym;
515  char msg[256];
516  sym = static_cast<symbol_union *>(item);
517  FILE* f = reinterpret_cast<FILE*>(userdata);
518 
519  if ( sym->common.symbol_type == IDENTIFIER_SYMBOL_TYPE ) {
520  if ( sym->common.reference_count > 0 ) {
521 
522  if ( sym->id.smem_lti != NIL )
523  {
524  SNPRINTF( msg, 256,
525  "\t@%c%llu --> %llu\n",
526  sym->id.name_letter,
527  static_cast<long long unsigned>(sym->id.name_number),
528  static_cast<long long unsigned>(sym->common.reference_count));
529  }
530  else
531  {
532  SNPRINTF( msg, 256,
533  "\t%c%llu --> %llu\n",
534  sym->id.name_letter,
535  static_cast<long long unsigned>(sym->id.name_number),
536  static_cast<long long unsigned>(sym->common.reference_count));
537  }
538 
539  msg[255] = 0; /* ensure null termination */
540  print (thisAgent, msg);
541  xml_generate_warning(thisAgent, msg);
542 
543  if (f) {
544  fprintf(f, "%s", msg) ;
545  }
546  }
547  } else {
548  print (thisAgent, "\tERROR: HASHTABLE ITEM IS NOT AN IDENTIFIER!\n");
549  return TRUE;
550  }
551  return FALSE;
552 }
553 
554 bool reset_id_counters (agent* thisAgent) {
555  int i;
556 
557  if (thisAgent->identifier_hash_table->count != 0) {
558  // As long as all of the existing identifiers are long term identifiers (lti), there's no problem
559  uint64_t ltis = 0;
561  if (static_cast<uint64_t>(thisAgent->identifier_hash_table->count) != ltis) {
562  print (thisAgent, "Internal warning: wanted to reset identifier generator numbers, but\n");
563  print (thisAgent, "there are still some identifiers allocated. (Probably a memory leak.)\n");
564  print (thisAgent, "(Leaving identifier numbers alone.)\n");
565  xml_generate_warning(thisAgent, "Internal warning: wanted to reset identifier generator numbers, but\nthere are still some identifiers allocated. (Probably a memory leak.)\n(Leaving identifier numbers alone.)");
566 
567  /* RDF 01272003: Added this to improve the output from this error message */
568  //TODO: append this to previous XML string or generate separate output?
570 
571  // Also dump the ids to a txt file
572  FILE *ids = fopen("leaked-ids.txt", "w") ;
573  if (ids)
574  {
575  do_for_all_items_in_hash_table( thisAgent, thisAgent->identifier_hash_table, print_identifier_ref_info, reinterpret_cast<void*>(ids));
576  fclose(ids) ;
577  }
578 
579  return false;
580  }
581 
582  // Getting here means that there are still identifiers but that
583  // they are all long-term and (hopefully) exist only in production memory.
584  }
585  for (i=0; i<26; i++) thisAgent->id_counter[i]=1;
586 
587  if ( thisAgent->smem_db->get_status() == soar_module::connected )
588  {
589  smem_reset_id_counters( thisAgent );
590  }
591 
592  return true ;
593 }
594 
595 Bool reset_tc_num (agent* /*thisAgent*/, void *item, void*) {
596  Symbol *sym;
597 
598  sym = static_cast<symbol_union *>(item);
599  if (sym->common.symbol_type==IDENTIFIER_SYMBOL_TYPE) sym->id.tc_num = 0;
600  else if (sym->common.symbol_type==VARIABLE_SYMBOL_TYPE) sym->var.tc_num = 0;
601  return FALSE;
602 }
603 
607 }
608 
609 Bool reset_gensym_number (agent* /*thisAgent*/, void *item, void*) {
610  Symbol *sym;
611 
612  sym = static_cast<symbol_union *>(item);
613  sym->var.gensym_number = 0;
614  return FALSE;
615 }
616 
619 }
620 
621 Bool print_sym (agent* thisAgent, void *item, void*) {
622  print_string (thisAgent, symbol_to_string (thisAgent, static_cast<symbol_union *>(item), TRUE, NIL, 0));
623  print_string (thisAgent, "\n");
624  return FALSE;
625 }
626 
627 void print_internal_symbols (agent* thisAgent) {
628  print_string (thisAgent, "\n--- Symbolic Constants: ---\n");
630  print_string (thisAgent, "\n--- Integer Constants: ---\n");
632  print_string (thisAgent, "\n--- Floating-Point Constants: ---\n");
634  print_string (thisAgent, "\n--- Identifiers: ---\n");
636  print_string (thisAgent, "\n--- Variables: ---\n");
638 }
639 
640 Symbol *generate_new_sym_constant (agent* thisAgent, const char *prefix, uint64_t* counter) {
641 #define GENERATE_NEW_SYM_CONSTANT_BUFFER_SIZE 2000 /* that ought to be long enough! */
643  Symbol *New;
644 
645  while (TRUE) {
646  SNPRINTF (name,GENERATE_NEW_SYM_CONSTANT_BUFFER_SIZE, "%s%lu", prefix, static_cast<long unsigned int>((*counter)++));
648  if (! find_sym_constant (thisAgent, name)) break;
649  }
650  New = make_sym_constant (thisAgent, name);
651  return New;
652 }
653 
654 /* --------------------------------------------------------------------
655 
656  Predefined Symbols
657 
658 -------------------------------------------------------------------- */
659 
660 void create_predefined_symbols (agent* thisAgent) {
661  thisAgent->problem_space_symbol = make_sym_constant (thisAgent, "problem-space");
662  thisAgent->state_symbol = make_sym_constant (thisAgent, "state");
663  thisAgent->operator_symbol = make_sym_constant (thisAgent, "operator");
664  thisAgent->superstate_symbol = make_sym_constant (thisAgent, "superstate");
665  thisAgent->io_symbol = make_sym_constant (thisAgent, "io");
666  thisAgent->object_symbol = make_sym_constant (thisAgent, "object");
667  thisAgent->attribute_symbol = make_sym_constant (thisAgent, "attribute");
668  thisAgent->impasse_symbol = make_sym_constant (thisAgent, "impasse");
669  thisAgent->choices_symbol = make_sym_constant (thisAgent, "choices");
670  thisAgent->none_symbol = make_sym_constant (thisAgent, "none");
671  thisAgent->constraint_failure_symbol = make_sym_constant (thisAgent, "constraint-failure");
672  thisAgent->no_change_symbol = make_sym_constant (thisAgent, "no-change");
673  thisAgent->multiple_symbol = make_sym_constant (thisAgent, "multiple");
674 
675  // SBW 5/07
676  thisAgent->item_count_symbol = make_sym_constant (thisAgent, "item-count");
677 
678  // NLD 11/11
679  thisAgent->non_numeric_count_symbol = make_sym_constant( thisAgent, "non-numeric-count" );
680 
681  thisAgent->conflict_symbol = make_sym_constant (thisAgent, "conflict");
682  thisAgent->tie_symbol = make_sym_constant (thisAgent, "tie");
683  thisAgent->item_symbol = make_sym_constant (thisAgent, "item");
684  thisAgent->non_numeric_symbol = make_sym_constant (thisAgent, "non-numeric");
685  thisAgent->quiescence_symbol = make_sym_constant (thisAgent, "quiescence");
686  thisAgent->t_symbol = make_sym_constant (thisAgent, "t");
687  thisAgent->nil_symbol = make_sym_constant (thisAgent, "nil");
688  thisAgent->type_symbol = make_sym_constant (thisAgent, "type");
689  thisAgent->goal_symbol = make_sym_constant (thisAgent, "goal");
690  thisAgent->name_symbol = make_sym_constant (thisAgent, "name");
691 
692  thisAgent->ts_context_variable = make_variable (thisAgent, "<ts>");
693  thisAgent->to_context_variable = make_variable (thisAgent, "<to>");
694  thisAgent->sss_context_variable = make_variable (thisAgent, "<sss>");
695  thisAgent->sso_context_variable = make_variable (thisAgent, "<sso>");
696  thisAgent->ss_context_variable = make_variable (thisAgent, "<ss>");
697  thisAgent->so_context_variable = make_variable (thisAgent, "<so>");
698  thisAgent->s_context_variable = make_variable (thisAgent, "<s>");
699  thisAgent->o_context_variable = make_variable (thisAgent, "<o>");
700 
701  /* REW: begin 10.24.97 */
702  thisAgent->wait_symbol = make_variable (thisAgent, "wait");
703  /* REW: end 10.24.97 */
704 
705  /* RPM 9/06 begin */
706  thisAgent->input_link_symbol = make_sym_constant(thisAgent, "input-link");
707  thisAgent->output_link_symbol = make_sym_constant(thisAgent, "output-link");
708  /* RPM 9/06 end */
709 
710  thisAgent->rl_sym_reward_link = make_sym_constant( thisAgent, "reward-link" );
711  thisAgent->rl_sym_reward = make_sym_constant( thisAgent, "reward" );
712  thisAgent->rl_sym_value = make_sym_constant( thisAgent, "value" );
713 
714  thisAgent->epmem_sym = make_sym_constant( thisAgent, "epmem" );
715  thisAgent->epmem_sym_cmd = make_sym_constant( thisAgent, "command" );
716  thisAgent->epmem_sym_result = make_sym_constant( thisAgent, "result" );
717 
718  thisAgent->epmem_sym_retrieved = make_sym_constant( thisAgent, "retrieved" );
719  thisAgent->epmem_sym_status = make_sym_constant( thisAgent, "status" );
720  thisAgent->epmem_sym_match_score = make_sym_constant( thisAgent, "match-score" );
721  thisAgent->epmem_sym_cue_size = make_sym_constant( thisAgent, "cue-size" );
722  thisAgent->epmem_sym_normalized_match_score = make_sym_constant( thisAgent, "normalized-match-score" );
723  thisAgent->epmem_sym_match_cardinality = make_sym_constant( thisAgent, "match-cardinality" );
724  thisAgent->epmem_sym_memory_id = make_sym_constant( thisAgent, "memory-id" );
725  thisAgent->epmem_sym_present_id = make_sym_constant( thisAgent, "present-id" );
726  thisAgent->epmem_sym_no_memory = make_sym_constant( thisAgent, "no-memory" );
727  thisAgent->epmem_sym_graph_match = make_sym_constant( thisAgent, "graph-match" );
728  thisAgent->epmem_sym_graph_match_mapping = make_sym_constant( thisAgent, "mapping" );
729  thisAgent->epmem_sym_graph_match_mapping_node = make_sym_constant( thisAgent, "node" );
730  thisAgent->epmem_sym_graph_match_mapping_cue = make_sym_constant( thisAgent, "cue" );
731  thisAgent->epmem_sym_success = make_sym_constant( thisAgent, "success" );
732  thisAgent->epmem_sym_failure = make_sym_constant( thisAgent, "failure" );
733  thisAgent->epmem_sym_bad_cmd = make_sym_constant( thisAgent, "bad-cmd" );
734 
735  thisAgent->epmem_sym_retrieve = make_sym_constant( thisAgent, "retrieve" );
736  thisAgent->epmem_sym_next = make_sym_constant( thisAgent, "next" );
737  thisAgent->epmem_sym_prev = make_sym_constant( thisAgent, "previous" );
738  thisAgent->epmem_sym_query = make_sym_constant( thisAgent, "query" );
739  thisAgent->epmem_sym_negquery = make_sym_constant( thisAgent, "neg-query" );
740  thisAgent->epmem_sym_before = make_sym_constant( thisAgent, "before" );
741  thisAgent->epmem_sym_after = make_sym_constant( thisAgent, "after" );
742  thisAgent->epmem_sym_prohibit = make_sym_constant( thisAgent, "prohibit" );
743  thisAgent->epmem_sym_current = make_sym_constant( thisAgent, "current" );
744  thisAgent->epmem_sym_yes = make_sym_constant( thisAgent, "yes" );
745  thisAgent->epmem_sym_no = make_sym_constant( thisAgent, "no" );
746 
747 
748  thisAgent->smem_sym = make_sym_constant( thisAgent, "smem" );
749  thisAgent->smem_sym_cmd = make_sym_constant( thisAgent, "command" );
750  thisAgent->smem_sym_result = make_sym_constant( thisAgent, "result" );
751 
752  thisAgent->smem_sym_retrieved = make_sym_constant( thisAgent, "retrieved" );
753  thisAgent->smem_sym_status = make_sym_constant( thisAgent, "status" );
754  thisAgent->smem_sym_success = make_sym_constant( thisAgent, "success" );
755  thisAgent->smem_sym_failure = make_sym_constant( thisAgent, "failure" );
756  thisAgent->smem_sym_bad_cmd = make_sym_constant( thisAgent, "bad-cmd" );
757 
758  thisAgent->smem_sym_retrieve = make_sym_constant( thisAgent, "retrieve" );
759  thisAgent->smem_sym_query = make_sym_constant( thisAgent, "query" );
760  thisAgent->smem_sym_negquery = make_sym_constant( thisAgent, "neg-query" );
761  thisAgent->smem_sym_prohibit = make_sym_constant( thisAgent, "prohibit" );
762  thisAgent->smem_sym_store = make_sym_constant( thisAgent, "store" );
763 }
764 
765 void release_helper(agent* thisAgent, Symbol** sym) {
766  symbol_remove_ref(thisAgent,*sym);
767  *sym = 0;
768 }
769 
771  release_helper(thisAgent,&(thisAgent->problem_space_symbol));
772  release_helper(thisAgent,&(thisAgent->state_symbol));
773  release_helper(thisAgent,&(thisAgent->operator_symbol));
774  release_helper(thisAgent,&(thisAgent->superstate_symbol));
775  release_helper(thisAgent,&(thisAgent->io_symbol));
776  release_helper(thisAgent,&(thisAgent->object_symbol));
777  release_helper(thisAgent,&(thisAgent->attribute_symbol));
778  release_helper(thisAgent,&(thisAgent->impasse_symbol));
779  release_helper(thisAgent,&(thisAgent->choices_symbol));
780  release_helper(thisAgent,&(thisAgent->none_symbol));
781  release_helper(thisAgent,&(thisAgent->constraint_failure_symbol));
782  release_helper(thisAgent,&(thisAgent->no_change_symbol));
783  release_helper(thisAgent,&(thisAgent->multiple_symbol));
784  release_helper(thisAgent,&(thisAgent->conflict_symbol));
785  release_helper(thisAgent,&(thisAgent->tie_symbol));
786  release_helper(thisAgent,&(thisAgent->item_symbol));
787  release_helper(thisAgent,&(thisAgent->non_numeric_symbol));
788  release_helper(thisAgent,&(thisAgent->quiescence_symbol));
789  release_helper(thisAgent,&(thisAgent->t_symbol));
790  release_helper(thisAgent,&(thisAgent->nil_symbol));
791  release_helper(thisAgent,&(thisAgent->type_symbol));
792  release_helper(thisAgent,&(thisAgent->goal_symbol));
793  release_helper(thisAgent,&(thisAgent->name_symbol));
794 
795  release_helper(thisAgent,&(thisAgent->ts_context_variable));
796  release_helper(thisAgent,&(thisAgent->to_context_variable));
797  release_helper(thisAgent,&(thisAgent->sss_context_variable));
798  release_helper(thisAgent,&(thisAgent->sso_context_variable));
799  release_helper(thisAgent,&(thisAgent->ss_context_variable));
800  release_helper(thisAgent,&(thisAgent->so_context_variable));
801  release_helper(thisAgent,&(thisAgent->s_context_variable));
802  release_helper(thisAgent,&(thisAgent->o_context_variable));
803 
804  // SBW 5/07
805  release_helper(thisAgent,&(thisAgent->item_count_symbol));
806 
807  // NLD 11/11
808  release_helper(thisAgent,&(thisAgent->non_numeric_count_symbol));
809 
810  /* REW: begin 10.24.97 */
811  release_helper(thisAgent,&(thisAgent->wait_symbol));
812  /* REW: end 10.24.97 */
813 
814  /* RPM 9/06 begin */
815  release_helper(thisAgent,&(thisAgent->input_link_symbol));
816  release_helper(thisAgent,&(thisAgent->output_link_symbol));
817  /* RPM 9/06 end */
818 
819  release_helper( thisAgent, &( thisAgent->rl_sym_reward_link ) );
820  release_helper( thisAgent, &( thisAgent->rl_sym_reward ) );
821  release_helper( thisAgent, &( thisAgent->rl_sym_value ) );
822 
823  release_helper( thisAgent, &( thisAgent->epmem_sym ) );
824  release_helper( thisAgent, &( thisAgent->epmem_sym_cmd ) );
825  release_helper( thisAgent, &( thisAgent->epmem_sym_result ) );
826 
827  release_helper( thisAgent, &( thisAgent->epmem_sym_retrieved ) );
828  release_helper( thisAgent, &( thisAgent->epmem_sym_status ) );
829  release_helper( thisAgent, &( thisAgent->epmem_sym_match_score ) );
830  release_helper( thisAgent, &( thisAgent->epmem_sym_cue_size ) );
831  release_helper( thisAgent, &( thisAgent->epmem_sym_normalized_match_score ) );
832  release_helper( thisAgent, &( thisAgent->epmem_sym_match_cardinality ) );
833  release_helper( thisAgent, &( thisAgent->epmem_sym_memory_id ) );
834  release_helper( thisAgent, &( thisAgent->epmem_sym_present_id ) );
835  release_helper( thisAgent, &( thisAgent->epmem_sym_no_memory ) );
836  release_helper( thisAgent, &( thisAgent->epmem_sym_graph_match ) );
837  release_helper( thisAgent, &( thisAgent->epmem_sym_graph_match_mapping ) );
838  release_helper( thisAgent, &( thisAgent->epmem_sym_graph_match_mapping_node ) );
839  release_helper( thisAgent, &( thisAgent->epmem_sym_graph_match_mapping_cue ) );
840  release_helper( thisAgent, &( thisAgent->epmem_sym_success ) );
841  release_helper( thisAgent, &( thisAgent->epmem_sym_failure ) );
842  release_helper( thisAgent, &( thisAgent->epmem_sym_bad_cmd ) );
843 
844  release_helper( thisAgent, &( thisAgent->epmem_sym_retrieve ) );
845  release_helper( thisAgent, &( thisAgent->epmem_sym_next ) );
846  release_helper( thisAgent, &( thisAgent->epmem_sym_prev ) );
847  release_helper( thisAgent, &( thisAgent->epmem_sym_query ) );
848  release_helper( thisAgent, &( thisAgent->epmem_sym_negquery ) );
849  release_helper( thisAgent, &( thisAgent->epmem_sym_before ) );
850  release_helper( thisAgent, &( thisAgent->epmem_sym_after ) );
851  release_helper( thisAgent, &( thisAgent->epmem_sym_prohibit ) );
852  release_helper( thisAgent, &( thisAgent->epmem_sym_current ) );
853  release_helper( thisAgent, &( thisAgent->epmem_sym_yes ) );
854  release_helper( thisAgent, &( thisAgent->epmem_sym_no ) );
855 
856  release_helper( thisAgent, &( thisAgent->smem_sym ) );
857  release_helper( thisAgent, &( thisAgent->smem_sym_cmd ) );
858  release_helper( thisAgent, &( thisAgent->smem_sym_result ) );
859 
860  release_helper( thisAgent, &( thisAgent->smem_sym_retrieved ) );
861  release_helper( thisAgent, &( thisAgent->smem_sym_status ) );
862  release_helper( thisAgent, &( thisAgent->smem_sym_success ) );
863  release_helper( thisAgent, &( thisAgent->smem_sym_failure ) );
864  release_helper( thisAgent, &( thisAgent->smem_sym_bad_cmd ) );
865 
866  release_helper( thisAgent, &( thisAgent->smem_sym_retrieve ) );
867  release_helper( thisAgent, &( thisAgent->smem_sym_query ) );
868  release_helper( thisAgent, &( thisAgent->smem_sym_negquery ) );
869  release_helper( thisAgent, &( thisAgent->smem_sym_prohibit ) );
870  release_helper( thisAgent, &( thisAgent->smem_sym_store ) );
871 }