Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

tempmem.c

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  file:  tempmem.c
00004  *
00005  * =======================================================================
00006  *  
00007  *             Temporary Memory and Slot routines for Soar 6
00008  *
00009  * see comments below and in soarkernel.h  
00010  *  
00011  * =======================================================================
00012  *
00013  * Copyright 1995-2003 Carnegie Mellon University,
00014  *                                                                               University of Michigan,
00015  *                                                                               University of Southern California/Information
00016  *                                                                               Sciences Institute. All rights reserved.
00017  *                                                                              
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions are met:
00020  *
00021  * 1.   Redistributions of source code must retain the above copyright notice,
00022  *              this list of conditions and the following disclaimer. 
00023  * 2.   Redistributions in binary form must reproduce the above copyright notice,
00024  *              this list of conditions and the following disclaimer in the documentation
00025  *              and/or other materials provided with the distribution. 
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE SOAR CONSORTIUM ``AS IS'' AND ANY EXPRESS OR
00028  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00029  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00030  * EVENT SHALL THE SOAR CONSORTIUM  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00031  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00032  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00033  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00034  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  * The views and conclusions contained in the software and documentation are
00038  * those of the authors and should not be interpreted as representing official
00039  * policies, either expressed or implied, of Carnegie Mellon University, the
00040  * University of Michigan, the University of Southern California/Information
00041  * Sciences Institute, or the Soar consortium.
00042  * =======================================================================
00043  */
00044 
00045 /* Debugging stuff:  #define DEBUG_SLOTS to get slot printouts */
00046 
00047 /* #define DEBUG_SLOTS */
00048 
00049 #include "soarkernel.h"
00050 
00051 /* **********************************************************************
00052 
00053                         Temporary Memory
00054 
00055 ********************************************************************** */
00056 
00057 /* ======================================================================
00058 
00059                         Slot Management Routines
00060 
00061    Find_slot() looks for an existing slot for a given id/attr pair, and
00062    returns it if found.  If no such slot exists, it returns NIL.
00063    Make_slot() looks for an existing slot for a given id/attr pair,
00064    returns it if found, and otherwise creates a new slot and returns it.
00065 
00066    Mark_slot_as_changed() is called by the preference manager whenever
00067    the preferences for a slot change.  This updates the list of
00068    changed_slots and highest_goal_whose_context_changed for use by the
00069    decider.
00070 ====================================================================== */
00071 
00072 slot *find_slot(Symbol * id, Symbol * attr)
00073 {
00074     slot *s;
00075 
00076     if (!id)
00077         return NIL;             /* fixes bug #135 kjh */
00078     for (s = id->id.slots; s != NIL; s = s->next)
00079         if (s->attr == attr)
00080             return s;
00081     return NIL;
00082 }
00083 
00084 wme *find_impasse_wme(Symbol * id, Symbol * attr)
00085 {
00086     wme *s;
00087 
00088     if (!id)
00089         return NIL;             /* fixes bug #135 kjh */
00090 
00091 #ifdef DEBUG_FIND_SLOT
00092 
00093     print_with_symbols("\nFind Slot '%y' in %y", attr, id);
00094 
00095     print("\nChecking the impasse_wmes");
00096     if (id->id.impasse_wmes) {
00097         for (s = id->id.impasse_wmes; s != NIL; s = s->next) {
00098             print_with_symbols("\n Found %y", s->attr);
00099             if (s->attr == attr) {
00100                 print("\nFound it\n");
00101 #else
00102 
00103     if (id->id.impasse_wmes) {
00104         for (s = id->id.impasse_wmes; s != NIL; s = s->next) {
00105             /*      print_with_symbols( "\n Found %y", s->attr ); */
00106             if (s->attr == attr) {
00107 #endif
00108 
00109                 return s;
00110             }
00111         }
00112     }
00113     return NULL;
00114 }
00115 
00116 slot *make_slot(Symbol * id, Symbol * attr)
00117 {
00118     slot *s;
00119     int i;
00120 
00121     for (s = id->id.slots; s != NIL; s = s->next)
00122         if (s->attr == attr)
00123             return s;
00124     allocate_with_pool(&current_agent(slot_pool), &s);
00125     insert_at_head_of_dll(id->id.slots, s, next, prev);
00126     if ((id->id.isa_goal) && (attr == current_agent(operator_symbol)))
00127         s->isa_context_slot = TRUE;
00128     else
00129         s->isa_context_slot = FALSE;
00130     s->changed = NIL;
00131     s->acceptable_preference_changed = NIL;
00132     s->id = id;
00133     s->attr = attr;
00134     symbol_add_ref(id);
00135     symbol_add_ref(attr);
00136     s->wmes = NIL;
00137     s->all_preferences = NIL;
00138     for (i = 0; i < NUM_PREFERENCE_TYPES; i++)
00139         s->preferences[i] = NIL;
00140     s->impasse_type = NONE_IMPASSE_TYPE;
00141     s->impasse_id = NIL;
00142     s->acceptable_preference_wmes = NIL;
00143     s->marked_for_possible_removal = FALSE;
00144     return s;
00145 }
00146 
00147 void mark_slot_as_changed(slot * s)
00148 {
00149     dl_cons *dc;
00150 
00151     if (s->isa_context_slot) {
00152         if (current_agent(highest_goal_whose_context_changed)) {
00153             if (s->id->id.level < current_agent(highest_goal_whose_context_changed)->id.level)
00154                 current_agent(highest_goal_whose_context_changed) = s->id;
00155         } else {
00156             current_agent(highest_goal_whose_context_changed) = s->id;
00157         }
00158         s->changed = (dl_cons *) s;     /* just make it nonzero */
00159     } else {
00160         if (!s->changed) {
00161             allocate_with_pool(&current_agent(dl_cons_pool), &dc);
00162             dc->item = s;
00163             s->changed = dc;
00164             insert_at_head_of_dll(current_agent(changed_slots), dc, next, prev);
00165         }
00166     }
00167 }
00168 
00169 /* -----------------------------------------------------------------
00170                       Slot Garbage Collection
00171 
00172    Old slots are garbage collected as follows:  whenever we notice that
00173    the last preference has been removed from a slot, we call
00174    mark_slot_for_possible_removal().  We don't deallocate the slot
00175    right away, because there might still be wmes in it, or we might
00176    be about to add a new preference to it (through some later action
00177    of the same production firing, for example).
00178 
00179    At the end of the phase, we call remove_garbage_slots(), which
00180    scans through each marked slot and garbage collects it if it has
00181    no wmes or preferences.
00182 ----------------------------------------------------------------- */
00183 
00184 void mark_slot_for_possible_removal(slot * s)
00185 {
00186     if (s->marked_for_possible_removal)
00187         return;
00188     s->marked_for_possible_removal = TRUE;
00189     push(s, current_agent(slots_for_possible_removal));
00190 }
00191 
00192 void remove_garbage_slots(void)
00193 {
00194     cons *c;
00195     slot *s;
00196 
00197     while (current_agent(slots_for_possible_removal)) {
00198         c = current_agent(slots_for_possible_removal);
00199         current_agent(slots_for_possible_removal) = current_agent(slots_for_possible_removal)->rest;
00200         s = c->first;
00201         free_cons(c);
00202 
00203         if (s->wmes || s->all_preferences) {
00204             /* --- don't deallocate it if it still has any wmes or preferences --- */
00205             s->marked_for_possible_removal = FALSE;
00206             continue;
00207         }
00208 
00209         /* --- deallocate the slot --- */
00210 #ifdef DEBUG_SLOTS
00211         print_with_symbols("\nDeallocate slot %y ^%y", s->id, s->attr);
00212 #endif
00213 
00214         if (s->changed && (!s->isa_context_slot)) {
00215             remove_from_dll(current_agent(changed_slots), s->changed, next, prev);
00216             free_with_pool(&current_agent(dl_cons_pool), s->changed);
00217         }
00218         remove_from_dll(s->id->id.slots, s, next, prev);
00219         if (s->id == NULL)
00220             print("ERROR!!!! in Garbage collection");
00221         else
00222             symbol_remove_ref(s->id);
00223         symbol_remove_ref(s->attr);
00224         free_with_pool(&current_agent(slot_pool), s);
00225     }
00226 }

Generated on Thu Dec 11 13:00:24 2003 for Soar Kernel by doxygen 1.3.5