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 #include "soarkernel.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 preference *make_preference(byte type, Symbol * id, Symbol * attr, Symbol * value, Symbol * referent)
00065 {
00066 preference *p;
00067
00068 allocate_with_pool(¤t_agent(preference_pool), &p);
00069 p->type = type;
00070 p->in_tm = FALSE;
00071 p->o_supported = FALSE;
00072 p->on_goal_list = FALSE;
00073 p->reference_count = 0;
00074 p->id = id;
00075 p->attr = attr;
00076 p->value = value;
00077 p->referent = referent;
00078 p->slot = NIL;
00079 p->next_clone = NIL;
00080 p->prev_clone = NIL;
00081
00082 #ifdef DEBUG_PREFS
00083 print("\nAllocating preference at 0x%8x: ", (unsigned long) p);
00084 print_preference(p);
00085 #endif
00086
00087 return p;
00088
00089
00090
00091 }
00092
00093
00094
00095
00096
00097 void deallocate_preference(preference * pref)
00098 {
00099
00100 #ifdef DEBUG_PREFS
00101 print("\nDeallocating preference at 0x%8x: ", (unsigned long) pref);
00102 print_preference(pref);
00103 if (pref->reference_count != 0) {
00104 char msg[MESSAGE_SIZE];
00105 strncpy(msg, "prefmem.c: Internal Error: Deallocating preference with ref. count != 0\n", MESSAGE_SIZE);
00106 msg[MESSAGE_SIZE - 1] = 0;
00107 abort_with_fatal_error(msg);
00108 }
00109 #endif
00110
00111 #ifdef NO_TOP_JUST
00112
00113 if (pref->on_goal_list)
00114 remove_from_dll(pref->match_goal->id.preferences_from_goal, pref, all_of_goal_next, all_of_goal_prev);
00115
00116
00117 if (pref->inst) {
00118 remove_from_dll(pref->inst->preferences_generated, pref, inst_next, inst_prev);
00119 possibly_deallocate_instantiation(pref->inst);
00120 }
00121 #else
00122
00123
00124 if (pref->on_goal_list)
00125 remove_from_dll(pref->inst->match_goal->id.preferences_from_goal, pref, all_of_goal_next, all_of_goal_prev);
00126
00127
00128 remove_from_dll(pref->inst->preferences_generated, pref, inst_next, inst_prev);
00129 possibly_deallocate_instantiation(pref->inst);
00130
00131 #endif
00132
00133
00134 symbol_remove_ref(pref->id);
00135 symbol_remove_ref(pref->attr);
00136 symbol_remove_ref(pref->value);
00137 if (preference_is_binary(pref->type))
00138 symbol_remove_ref(pref->referent);
00139
00140
00141 free_with_pool(¤t_agent(preference_pool), pref);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 bool possibly_deallocate_preference_and_clones(preference * pref)
00152 {
00153 preference *clone, *next;
00154
00155 if (pref->reference_count)
00156 return FALSE;
00157 for (clone = pref->next_clone; clone != NIL; clone = clone->next_clone)
00158 if (clone->reference_count)
00159 return FALSE;
00160 for (clone = pref->prev_clone; clone != NIL; clone = clone->prev_clone)
00161 if (clone->reference_count)
00162 return FALSE;
00163
00164
00165 clone = pref->next_clone;
00166 while (clone) {
00167 next = clone->next_clone;
00168 deallocate_preference(clone);
00169 clone = next;
00170 }
00171 clone = pref->prev_clone;
00172 while (clone) {
00173 next = clone->prev_clone;
00174 deallocate_preference(clone);
00175 clone = next;
00176 }
00177
00178
00179 deallocate_preference(pref);
00180
00181 return TRUE;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 bool remove_preference_from_clones(preference * pref)
00191 {
00192 preference *any_clone;
00193
00194 any_clone = NIL;
00195 if (pref->next_clone) {
00196 any_clone = pref->next_clone;
00197 pref->next_clone->prev_clone = pref->prev_clone;
00198 }
00199 if (pref->prev_clone) {
00200 any_clone = pref->prev_clone;
00201 pref->prev_clone->next_clone = pref->next_clone;
00202 }
00203 pref->next_clone = pref->prev_clone = NIL;
00204 if (any_clone)
00205 possibly_deallocate_preference_and_clones(any_clone);
00206 if (!pref->reference_count) {
00207 deallocate_preference(pref);
00208 return TRUE;
00209 } else {
00210 return FALSE;
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219 void add_preference_to_tm(preference * pref)
00220 {
00221 slot *s;
00222 preference *p2;
00223
00224 #ifdef DEBUG_PREFS
00225 print("\nAdd preference at 0x%8x: ", (unsigned long) pref);
00226 print_preference(pref);
00227 #endif
00228
00229 s = make_slot(pref->id, pref->attr);
00230 pref->slot = s;
00231
00232 insert_at_head_of_dll(s->all_preferences, pref, all_of_slot_next, all_of_slot_prev);
00233
00234
00235
00236
00237 #ifdef NO_TOP_JUST
00238
00239
00240
00241 if (!s->preferences[pref->type]) {
00242
00243 insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev);
00244 } else if (s->preferences[pref->type]->match_goal_level >= pref->match_goal_level) {
00245
00246 insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev);
00247 } else {
00248
00249 for (p2 = s->preferences[pref->type]; p2->next != NIL; p2 = p2->next)
00250 if (p2->next->match_goal_level >= pref->match_goal_level)
00251 break;
00252
00253 pref->next = p2->next;
00254 pref->prev = p2;
00255 p2->next = pref;
00256 if (pref->next)
00257 pref->next->prev = pref;
00258 }
00259
00260 #else
00261
00262 if (!s->preferences[pref->type]) {
00263
00264 insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev);
00265 } else if (s->preferences[pref->type]->inst->match_goal_level >= pref->inst->match_goal_level) {
00266
00267 insert_at_head_of_dll(s->preferences[pref->type], pref, next, prev);
00268 } else {
00269
00270 for (p2 = s->preferences[pref->type]; p2->next != NIL; p2 = p2->next)
00271 if (p2->next->inst->match_goal_level >= pref->inst->match_goal_level)
00272 break;
00273
00274 pref->next = p2->next;
00275 pref->prev = p2;
00276 p2->next = pref;
00277 if (pref->next)
00278 pref->next->prev = pref;
00279 }
00280
00281 #endif
00282
00283
00284 pref->in_tm = TRUE;
00285 preference_add_ref(pref);
00286 mark_slot_as_changed(s);
00287
00288
00289 if (pref->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00290 post_link_addition(pref->id, pref->value);
00291 if (preference_is_binary(pref->type))
00292 if (pref->referent->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00293 post_link_addition(pref->id, pref->referent);
00294
00295
00296
00297 if ((s->isa_context_slot) &&
00298 ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE)))
00299 mark_context_slot_as_acceptable_preference_changed(s);
00300 }
00301
00302
00303
00304
00305
00306 void remove_preference_from_tm(preference * pref)
00307 {
00308 slot *s;
00309
00310 s = pref->slot;
00311
00312 #ifdef DEBUG_PREFS
00313 print("\nRemove preference at 0x%8x: ", (unsigned long) pref);
00314 print_preference(pref);
00315 #endif
00316
00317
00318 remove_from_dll(s->all_preferences, pref, all_of_slot_next, all_of_slot_prev);
00319 remove_from_dll(s->preferences[pref->type], pref, next, prev);
00320
00321
00322 pref->in_tm = FALSE;
00323 pref->slot = NIL;
00324 mark_slot_as_changed(s);
00325
00326
00327
00328 if ((s->isa_context_slot) &&
00329 ((pref->type == ACCEPTABLE_PREFERENCE_TYPE) || (pref->type == REQUIRE_PREFERENCE_TYPE)))
00330 mark_context_slot_as_acceptable_preference_changed(s);
00331
00332
00333 if (pref->value->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00334 post_link_removal(pref->id, pref->value);
00335 if (preference_is_binary(pref->type))
00336 if (pref->referent->common.symbol_type == IDENTIFIER_SYMBOL_TYPE)
00337 post_link_removal(pref->id, pref->referent);
00338
00339
00340 preference_remove_ref(pref);
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 void process_o_rejects_and_deallocate_them(preference * o_rejects)
00354 {
00355 preference *pref, *next_pref, *p, *next_p;
00356 slot *s;
00357
00358 for (pref = o_rejects; pref != NIL; pref = pref->next) {
00359 preference_add_ref(pref);
00360
00361
00362 #ifdef DEBUG_PREFS
00363 print("\nO-reject posted at 0x%8x: ", (unsigned long) pref);
00364 print_preference(pref);
00365 #endif
00366 }
00367
00368 pref = o_rejects;
00369 while (pref) {
00370 next_pref = pref->next;
00371 s = find_slot(pref->id, pref->attr);
00372 if (s) {
00373
00374 p = s->all_preferences;
00375 while (p) {
00376 next_p = p->all_of_slot_next;
00377 if (p->value == pref->value)
00378 remove_preference_from_tm(p);
00379 p = next_p;
00380 }
00381 }
00382 preference_remove_ref(pref);
00383 pref = next_pref;
00384 }
00385 }