00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "soarkernel.h"
00051
00052 extern void filtered_print_wme_add(wme * w);
00053 extern void filtered_print_wme_remove(wme * w);
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 void reset_wme_timetags(void)
00084 {
00085 if (current_agent(num_existing_wmes) != 0) {
00086 print("Internal warning: wanted to reset wme timetag generator, but\n");
00087 print("there are still some wmes allocated. (Probably a memory leak.)\n");
00088 print("(Leaving timetag numbers alone.)\n");
00089 return;
00090 }
00091 current_agent(current_wme_timetag) = 1;
00092 }
00093
00094 wme *make_wme(Symbol * id, Symbol * attr, Symbol * value, bool acceptable)
00095 {
00096 wme *w;
00097
00098 current_agent(num_existing_wmes)++;
00099 allocate_with_pool(¤t_agent(wme_pool), &w);
00100 w->id = id;
00101 w->attr = attr;
00102 w->value = value;
00103 symbol_add_ref(id);
00104 symbol_add_ref(attr);
00105 symbol_add_ref(value);
00106 w->acceptable = acceptable;
00107 w->timetag = current_agent(current_wme_timetag)++;
00108 w->reference_count = 0;
00109 w->preference = NIL;
00110 w->output_link = NIL;
00111 w->grounds_tc = 0;
00112 w->potentials_tc = 0;
00113 w->locals_tc = 0;
00114
00115
00116
00117
00118
00119 w->gds = NIL;
00120
00121
00122 return w;
00123 }
00124
00125
00126
00127 void add_wme_to_wm(wme * w)
00128 {
00129 push(w, current_agent(wmes_to_add));
00130 if (w->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE) {
00131 post_link_addition(w->id, w->value);
00132 if (w->attr == current_agent(operator_symbol))
00133 w->value->id.isa_operator++;
00134 }
00135 }
00136
00137 void remove_wme_from_wm(wme * w)
00138 {
00139 push(w, current_agent(wmes_to_remove));
00140 if (w->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE) {
00141 post_link_removal(w->id, w->value);
00142 if (w->attr == current_agent(operator_symbol))
00143 w->value->id.isa_operator--;
00144 }
00145
00146
00147
00148
00149 if (w->gds) {
00150 fast_remove_from_dll(w->gds->wmes_in_gds, w, wme, gds_next, gds_prev);
00151
00152 if (!w->gds->wmes_in_gds) {
00153 free_memory(w->gds, MISCELLANEOUS_MEM_USAGE);
00154
00155 }
00156 }
00157
00158 }
00159
00160 void remove_wme_list_from_wm(wme * w)
00161 {
00162 wme *next_w;
00163
00164 while (w) {
00165 next_w = w->next;
00166 remove_wme_from_wm(w);
00167 w = next_w;
00168 }
00169 }
00170
00171 void do_buffered_wm_changes(void)
00172 {
00173 cons *c, *next_c;
00174 wme *w;
00175 #ifndef NO_TIMING_STUFF
00176 #ifdef DETAILED_TIMING_STATS
00177 struct timeval start_tv;
00178 #endif
00179 #endif
00180
00181
00182 if (!current_agent(wmes_to_add) && !current_agent(wmes_to_remove))
00183 return;
00184
00185
00186 inform_output_module_of_wm_changes(current_agent(wmes_to_add), current_agent(wmes_to_remove));
00187
00188
00189
00190 soar_invoke_callbacks(soar_agent, WM_CHANGES_CALLBACK, (soar_call_data) NULL);
00191
00192
00193 #ifndef NO_TIMING_STUFF
00194 #ifdef DETAILED_TIMING_STATS
00195 start_timer(&start_tv);
00196 #endif
00197 #endif
00198 for (c = current_agent(wmes_to_add); c != NIL; c = c->rest)
00199 add_wme_to_rete(c->first);
00200 for (c = current_agent(wmes_to_remove); c != NIL; c = c->rest)
00201 remove_wme_from_rete(c->first);
00202 #ifndef NO_TIMING_STUFF
00203 #ifdef DETAILED_TIMING_STATS
00204 stop_timer(&start_tv, ¤t_agent(match_cpu_time[current_agent(current_phase)]));
00205 #endif
00206 #endif
00207
00208
00209 for (c = current_agent(wmes_to_add); c != NIL; c = next_c) {
00210 next_c = c->rest;
00211 w = c->first;
00212
00213 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00214
00215 if (current_agent(sysparams)[TRACE_WM_CHANGES_SYSPARAM]) {
00216
00217
00218
00219 filtered_print_wme_add(w);
00220 }
00221 #endif
00222
00223 wme_add_ref(w);
00224 free_cons(c);
00225 current_agent(wme_addition_count)++;
00226 }
00227 for (c = current_agent(wmes_to_remove); c != NIL; c = next_c) {
00228 next_c = c->rest;
00229 w = c->first;
00230
00231 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00232
00233 if (current_agent(sysparams)[TRACE_WM_CHANGES_SYSPARAM]) {
00234
00235
00236
00237 filtered_print_wme_remove(w);
00238 }
00239 #endif
00240
00241 wme_remove_ref(w);
00242 free_cons(c);
00243 current_agent(wme_removal_count)++;
00244 }
00245 current_agent(wmes_to_add) = NIL;
00246 current_agent(wmes_to_remove) = NIL;
00247 }
00248
00249 void deallocate_wme(wme * w)
00250 {
00251 #ifdef DEBUG_WMES
00252 print_with_symbols("\nDeallocate wme: ");
00253 print_wme(w);
00254 #endif
00255 symbol_remove_ref(w->id);
00256 symbol_remove_ref(w->attr);
00257 symbol_remove_ref(w->value);
00258 free_with_pool(¤t_agent(wme_pool), w);
00259 current_agent(num_existing_wmes)--;
00260 }
00261
00262 Symbol *find_name_of_object(Symbol * object)
00263 {
00264 slot *s;
00265
00266 if (object->common.symbol_type != IDENTIFIER_SYMBOL_TYPE)
00267 return NIL;
00268 s = find_slot(object, current_agent(name_symbol));
00269 if (!s)
00270 return NIL;
00271 if (!s->wmes)
00272 return NIL;
00273 return s->wmes->value;
00274 }