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

init_soar.c

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  file:  init_soar.c
00004  *
00005  * =======================================================================
00006  *  Routines for initializing Soar, signal handling (ctrl-c interrupt),
00007  *  exiting Soar (cleanup and error msgs), setting sysparams, and
00008  *  the core routines for "running" Soar (do_one_top_level_phase, etc.)
00009  * =======================================================================
00010  *
00011  * Copyright 1995-2003 Carnegie Mellon University,
00012  *                                                                               University of Michigan,
00013  *                                                                               University of Southern California/Information
00014  *                                                                               Sciences Institute. All rights reserved.
00015  *                                                                              
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions are met:
00018  *
00019  * 1.   Redistributions of source code must retain the above copyright notice,
00020  *              this list of conditions and the following disclaimer. 
00021  * 2.   Redistributions in binary form must reproduce the above copyright notice,
00022  *              this list of conditions and the following disclaimer in the documentation
00023  *              and/or other materials provided with the distribution. 
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE SOAR CONSORTIUM ``AS IS'' AND ANY EXPRESS OR
00026  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00027  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00028  * EVENT SHALL THE SOAR CONSORTIUM  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00029  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00030  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00032  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00034  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  * The views and conclusions contained in the software and documentation are
00036  * those of the authors and should not be interpreted as representing official
00037  * policies, either expressed or implied, of Carnegie Mellon University, the
00038  * University of Michigan, the University of Southern California/Information
00039  * Sciences Institute, or the Soar consortium.
00040  * =======================================================================
00041  */
00042 
00043 #include "soarkernel.h"
00044 #include <signal.h>             /* used for control-c handler */
00045 
00046 #if !defined(__SC__) && !defined(THINK_C) && !defined(WIN32) && !defined(MACINTOSH)
00047 #include <sys/time.h>           /* used for timing stuff */
00048 #include <sys/resource.h>       /* used for timing stuff */
00049 #endif                          /* !__SC__ && !THINK_C && !WIN32 */
00050 
00051 /* REW: begin 08.20.97   these defined in consistency.c  */
00052 extern void determine_highest_active_production_level_in_stack();
00053 extern void determine_highest_active_production_level_in_stack_apply();
00054 extern void determine_highest_active_production_level_in_stack_propose();
00055 extern void initialize_consistency_calculations_for_new_decision();
00056 
00057 /* REW: end   08.20.97 */
00058 
00059 int soar_agent_ids[MAX_SIMULTANEOUS_AGENTS];
00060 soar_global_callback_array soar_global_callbacks;
00061 unsigned long soar_global_callback_error;
00062 
00063 #if (defined(REAL_TIME_BEHAVIOR) || defined(ATTENTION_LAPSE))
00064 /* RMJ; just a temporary variable, but we don't want to
00065       reallocate it every time we process a phase, so we make it global
00066       and allocate memory for it in init_soar() (init agent.c) */
00067 struct timeval *current_real_time;
00068 #endif
00069 
00070 #ifdef ATTENTION_LAPSE
00071 /* RMJ; just a temporary variable, but we don't want to
00072       reallocate it every time we process a phase, so we make it global */
00073 long lapse_duration;
00074 #endif
00075 
00076 /* ===================================================================
00077 
00078                             Exiting Soar
00079 
00080    Exit_soar() and abort_with_fatal_error(msg) both terminate Soar, closing
00081    the log file before exiting.  Abort_with_fatal_error(msg) also prints  
00082    an error message and tries to write a file before exiting.
00083 =================================================================== */
00084 
00085 void just_before_exit_soar(void)
00086 {
00087     cons *c;
00088 
00089     /* 
00090      * This function should now deal with multiple agents
00091      * as well as no agents.
00092      */
00093     for (c = all_soar_agents; c != NULL; c = c->rest) {
00094         soar_invoke_callbacks((agent *) c->first, SYSTEM_TERMINATION_CALLBACK, (soar_call_data) TRUE);
00095 
00096         if (((agent *) c->first)->logging_to_file)
00097             stop_log_file();
00098     }
00099 }
00100 
00101 void exit_soar(void)
00102 {
00103 
00104     just_before_exit_soar();
00105     exit(0);
00106 
00107 }
00108 
00109 void abort_with_fatal_error(char *msg)
00110 {
00111     FILE *f;
00112 
00113     print("%s", msg);
00114     print("Soar cannot recover from this error.  Aborting...\n");
00115     fprintf(stderr, "%s", msg);
00116     fprintf(stderr, "Soar cannot recover from this error.  Aborting...\n");
00117     f = fopen("soarerror", "w");
00118     fprintf(f, "%s", msg);
00119     fprintf(f, "Soar cannot recover from this error.  Aborting...\n");
00120     fclose(f);
00121 
00122     soar_invoke_callbacks(soar_agent, SYSTEM_TERMINATION_CALLBACK, (soar_call_data) FALSE);
00123 
00124     if (current_agent(logging_to_file))
00125         stop_log_file();
00126 
00127     sys_abort();
00128 
00129 }
00130 
00131 #ifdef REAL_TIME_BEHAVIOR
00132 /* RMJ */
00133 void init_real_time(void)
00134 {
00135     current_agent(real_time_tracker) = (struct timeval *) malloc(sizeof(struct timeval));
00136     timerclear(current_agent(real_time_tracker));
00137     current_agent(real_time_idling) = FALSE;
00138     current_real_time = (struct timeval *) malloc(sizeof(struct timeval));
00139 }
00140 #endif
00141 
00142 #ifdef ATTENTION_LAPSE
00143 /* RMJ */
00144 
00145 void wake_from_attention_lapse(void)
00146 {
00147     /* Set tracker to last time we woke up */
00148     start_timer(current_agent(attention_lapse_tracker));
00149     current_agent(attention_lapsing) = FALSE;
00150 }
00151 
00152 void init_attention_lapse(void)
00153 {
00154     current_agent(attention_lapse_tracker) = (struct timeval *) malloc(sizeof(struct timeval));
00155     wake_from_attention_lapse();
00156 #ifndef REAL_TIME_BEHAVIOR
00157     current_real_time = (struct timeval *) malloc(sizeof(struct timeval));
00158 #endif
00159 }
00160 
00161 void start_attention_lapse(long duration)
00162 {
00163     /* Set tracker to time we should wake up */
00164     start_timer(current_agent(attention_lapse_tracker));
00165     current_agent(attention_lapse_tracker)->tv_usec += 1000 * duration;
00166     if (current_agent(attention_lapse_tracker)->tv_usec >= 1000000) {
00167         current_agent(attention_lapse_tracker)->tv_sec += current_agent(attention_lapse_tracker)->tv_usec / 1000000;
00168         current_agent(attention_lapse_tracker)->tv_usec %= 1000000;
00169     }
00170     current_agent(attention_lapsing) = TRUE;
00171 }
00172 
00173 #endif
00174 
00175 /* ===================================================================
00176    
00177                             Sysparams
00178 
00179 =================================================================== */
00180 
00181 void init_sysparams(void)
00182 {
00183     int i;
00184 
00185     for (i = 0; i < HIGHEST_SYSPARAM_NUMBER + 1; i++)
00186         current_agent(sysparams)[i] = 0;
00187 
00188     /* --- set all params to zero, except the following: --- */
00189     current_agent(sysparams)[TRACE_CONTEXT_DECISIONS_SYSPARAM] = TRUE;
00190 
00191 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00192 
00193     current_agent(sysparams)[TRACE_FIRINGS_OF_CHUNKS_SYSPARAM] = TRUE;
00194     current_agent(sysparams)[TRACE_FIRINGS_WME_TRACE_TYPE_SYSPARAM] = NONE_WME_TRACE;
00195     current_agent(sysparams)[TRACE_CHUNK_NAMES_SYSPARAM] = TRUE;
00196     current_agent(sysparams)[TRACE_JUSTIFICATION_NAMES_SYSPARAM] = TRUE;
00197 
00198 #endif
00199     current_agent(sysparams)[TRACE_LOADING_SYSPARAM] = TRUE;    /* KJC 8/96 */
00200 
00201     current_agent(sysparams)[MAX_ELABORATIONS_SYSPARAM] = 100;
00202     current_agent(sysparams)[MAX_CHUNKS_SYSPARAM] = 50;
00203 
00204     current_agent(sysparams)[RESPOND_TO_LOAD_ERRORS_SYSPARAM] = TRUE;
00205 
00206 #ifdef ATTENTION_LAPSE
00207     /* RMJ */
00208     current_agent(sysparams)[ATTENTION_LAPSE_ON_SYSPARAM] = FALSE;
00209 #endif                          /* ATTENTION_LAPSE */
00210 
00211     current_agent(sysparams)[LEARNING_ON_SYSPARAM] = TRUE;
00212     current_agent(sysparams)[LEARNING_ONLY_SYSPARAM] = FALSE;   /* AGR MVL1 */
00213     current_agent(sysparams)[LEARNING_EXCEPT_SYSPARAM] = FALSE; /* KJC 8/96 */
00214     current_agent(sysparams)[LEARNING_ALL_GOALS_SYSPARAM] = TRUE;
00215     current_agent(sysparams)[USER_SELECT_MODE_SYSPARAM] = USER_SELECT_RANDOM;
00216     current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM] = TRUE;
00217     current_agent(sysparams)[PRINT_ALIAS_SYSPARAM] = TRUE;      /* AGR 627 */
00218     current_agent(sysparams)[EXPLAIN_SYSPARAM] = FALSE; /* KJC 7/96 */
00219     current_agent(sysparams)[USE_LONG_CHUNK_NAMES] = TRUE;      /* kjh(B14) */
00220     current_agent(sysparams)[TRACE_OPERAND2_REMOVALS_SYSPARAM] = FALSE;
00221 }
00222 
00223 /* ===================================================================
00224    
00225                      Adding and Removing Pwatchs
00226 
00227    Productions_being_traced is a (consed) list of all productions
00228    on which a pwatch has been set.  Pwatchs are added/removed via
00229    calls to add_pwatch() and remove_pwatch().
00230 =================================================================== */
00231 /* list of production structures */
00232 
00233 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00234 
00235 void add_pwatch(production * prod)
00236 {
00237     if (prod->trace_firings)
00238         return;
00239     prod->trace_firings = TRUE;
00240     push(prod, current_agent(productions_being_traced));
00241 }
00242 
00243 production *prod_to_remove_pwatch_of;
00244 
00245 bool remove_pwatch_test_fn(cons * c)
00246 {
00247     return (bool) (c->first == prod_to_remove_pwatch_of);
00248 }
00249 
00250 void remove_pwatch(production * prod)
00251 {
00252     if (!prod->trace_firings)
00253         return;
00254     prod->trace_firings = FALSE;
00255     prod_to_remove_pwatch_of = prod;
00256     free_list(extract_list_elements(&current_agent(productions_being_traced), remove_pwatch_test_fn));
00257 }
00258 
00259 #endif
00260 
00261 /* ===================================================================
00262    
00263                          Reinitializing Soar
00264 
00265    Reset_statistics() resets all the statistics (except the firing counts
00266    on each individual production).  Reinitialize_soar() does all the 
00267    work for an init-soar.
00268 =================================================================== */
00269 
00270 void reset_production_firing_counts(void)
00271 {
00272     int t;
00273     production *p;
00274 
00275     for (t = 0; t < NUM_PRODUCTION_TYPES; t++) {
00276         for (p = current_agent(all_productions_of_type)[t]; p != NIL; p = p->next)
00277             p->firing_count = 0;
00278     }
00279 }
00280 
00281 void reset_statistics(void)
00282 {
00283 
00284     current_agent(d_cycle_count) = 0;
00285     current_agent(e_cycle_count) = 0;
00286     current_agent(e_cycles_this_d_cycle) = 0;
00287     current_agent(chunks_this_d_cycle) = 0;
00288     current_agent(production_firing_count) = 0;
00289     current_agent(wme_addition_count) = 0;
00290     current_agent(wme_removal_count) = 0;
00291     current_agent(max_wm_size) = 0;
00292     current_agent(cumulative_wm_size) = 0.0;
00293     current_agent(num_wm_sizes_accumulated) = 0;
00294 /* REW: begin 09.15.96 */
00295     current_agent(pe_cycle_count) = 0;
00296     current_agent(pe_cycles_this_d_cycle) = 0;
00297 /* REW: end   09.15.96 */
00298 
00299     reset_production_firing_counts();
00300 
00301 #ifndef NO_TIMING_STUFF
00302     reset_timer(&current_agent(total_cpu_time));
00303 
00304 /* REW: begin 28.07.96 */
00305 
00306     reset_timer(&current_agent(total_kernel_time));
00307 
00308     reset_timer(&current_agent(input_function_cpu_time));
00309     reset_timer(&current_agent(output_function_cpu_time));
00310 
00311 #ifndef KERNEL_TIME_ONLY
00312 
00313     reset_timer(&current_agent(decision_cycle_phase_timers[INPUT_PHASE]));
00314     reset_timer(&current_agent(decision_cycle_phase_timers[DETERMINE_LEVEL_PHASE]));
00315     reset_timer(&current_agent(decision_cycle_phase_timers[PREFERENCE_PHASE]));
00316     reset_timer(&current_agent(decision_cycle_phase_timers[WM_PHASE]));
00317     reset_timer(&current_agent(decision_cycle_phase_timers[OUTPUT_PHASE]));
00318     reset_timer(&current_agent(decision_cycle_phase_timers[DECISION_PHASE]));
00319 
00320     reset_timer(&current_agent(monitors_cpu_time[INPUT_PHASE]));
00321     reset_timer(&current_agent(monitors_cpu_time[DETERMINE_LEVEL_PHASE]));
00322     reset_timer(&current_agent(monitors_cpu_time[PREFERENCE_PHASE]));
00323     reset_timer(&current_agent(monitors_cpu_time[WM_PHASE]));
00324     reset_timer(&current_agent(monitors_cpu_time[OUTPUT_PHASE]));
00325     reset_timer(&current_agent(monitors_cpu_time[DECISION_PHASE]));
00326 
00327 #ifdef DETAILED_TIMING_STATS
00328     reset_timer(&current_agent(match_cpu_time[INPUT_PHASE]));
00329     reset_timer(&current_agent(match_cpu_time[DETERMINE_LEVEL_PHASE]));
00330     reset_timer(&current_agent(match_cpu_time[PREFERENCE_PHASE]));
00331     reset_timer(&current_agent(match_cpu_time[WM_PHASE]));
00332     reset_timer(&current_agent(match_cpu_time[OUTPUT_PHASE]));
00333     reset_timer(&current_agent(match_cpu_time[DECISION_PHASE]));
00334 
00335     reset_timer(&current_agent(ownership_cpu_time[INPUT_PHASE]));
00336     reset_timer(&current_agent(ownership_cpu_time[DETERMINE_LEVEL_PHASE]));
00337     reset_timer(&current_agent(ownership_cpu_time[PREFERENCE_PHASE]));
00338     reset_timer(&current_agent(ownership_cpu_time[WM_PHASE]));
00339     reset_timer(&current_agent(ownership_cpu_time[OUTPUT_PHASE]));
00340     reset_timer(&current_agent(ownership_cpu_time[DECISION_PHASE]));
00341 
00342     reset_timer(&current_agent(chunking_cpu_time[INPUT_PHASE]));
00343     reset_timer(&current_agent(chunking_cpu_time[DETERMINE_LEVEL_PHASE]));
00344     reset_timer(&current_agent(chunking_cpu_time[PREFERENCE_PHASE]));
00345     reset_timer(&current_agent(chunking_cpu_time[WM_PHASE]));
00346     reset_timer(&current_agent(chunking_cpu_time[OUTPUT_PHASE]));
00347     reset_timer(&current_agent(chunking_cpu_time[DECISION_PHASE]));
00348 
00349 /* REW: begin 11.25.96 */
00350     reset_timer(&current_agent(total_gds_time));
00351 
00352     reset_timer(&current_agent(gds_cpu_time[INPUT_PHASE]));
00353     reset_timer(&current_agent(gds_cpu_time[DETERMINE_LEVEL_PHASE]));
00354     reset_timer(&current_agent(gds_cpu_time[PREFERENCE_PHASE]));
00355     reset_timer(&current_agent(gds_cpu_time[WM_PHASE]));
00356     reset_timer(&current_agent(gds_cpu_time[OUTPUT_PHASE]));
00357     reset_timer(&current_agent(gds_cpu_time[DECISION_PHASE]));
00358 /* REW: end   11.25.96 */
00359 #endif
00360 #endif
00361 #ifdef DC_HISTOGRAM
00362     {
00363         int i;
00364         for (i = 0; i < current_agent(dc_histogram_sz); i++) {
00365             reset_timer(&current_agent(dc_histogram_tv)[i]);
00366         }
00367     }
00368 #endif                          /* DC_HISTOGRAM */
00369 #ifdef KT_HISTOGRAM
00370     {
00371         int i;
00372         for (i = 0; i < current_agent(kt_histogram_sz); i++) {
00373             reset_timer(&current_agent(kt_histogram_tv)[i]);
00374         }
00375     }
00376 #endif                          /* KT_HISTOGRAM */
00377 
00378 #endif
00379 /* REW: end 28.07.96 */
00380 #ifdef COUNT_KERNEL_TIMER_STOPS
00381     current_agent(kernelTimerStops) = 0;
00382     current_agent(nonKernelTimerStops) = 0;
00383 #endif
00384 
00385 }
00386 
00387 /* ===================================================================
00388    
00389                             Running Soar
00390 
00391    Do_one_top_level_phase() runs Soar one top-level phase.  Note that
00392    this does not start/stop the total_cpu_time timer--the caller must
00393    do this.
00394 
00395    Each of the following routines runs Soar for a certain duration,
00396    or until stop_soar gets set to TRUE.
00397      - Run_forever() runs Soar forever.
00398      - Run_for_n_phases() runs Soar for a given number (n) of top-level
00399        phases.  (If n==-1, it runs forever.)
00400      - Run_for_n_elaboration_cycles() runs Soar for a given number (n)
00401        of elaboration cycles.  (Here, decision phase is counted as
00402        an elaboration cycle.)  (If n==-1, it runs forever.)
00403      - Run_for_n_decision_cycles() runs Soar for a given number (n) of
00404        decision cycles.  (If n==-1, it runs forever.)
00405      - Run_for_n_selections_of_slot (long n, Symbol *attr_of_slot): this
00406        runs Soar until the nth time a selection is made for a given
00407        type of slot.  Attr_of_slot should be either state_symbol or 
00408        operator_symbol.
00409      - Run_for_n_selections_of_slot_at_level (long n, Symbol *attr_of_slot,
00410        goal_stack_level level):  this runs Soar for n selections of the
00411        given slot at the given level, or until the goal stack is popped
00412        so that level no longer exists.
00413 =================================================================== */
00414 
00415 void do_one_top_level_phase(void)
00416 {
00417 
00418     if (current_agent(system_halted)) {
00419         print("\nSystem halted.  Use (init-soar) before running Soar again.");
00420         current_agent(stop_soar) = TRUE;
00421         current_agent(reason_for_stopping) = "System halted.";
00422         return;
00423     }
00424 
00425     if (!current_agent(top_goal)) {
00426         create_top_goal();
00427         if (current_agent(sysparams)[TRACE_CONTEXT_DECISIONS_SYSPARAM]) {
00428             print_string("\n");
00429             print_lowest_slot_in_context_stack();
00430         }
00431         current_agent(current_phase) = INPUT_PHASE;
00432 
00433 #ifndef SOAR_8_ONLY
00434         if (current_agent(operand2_mode))
00435 #endif
00436             /*
00437              * SW 112999 was:
00438              * current_agent(d_cycle_count)++;
00439              */
00440             increment_current_agent_d_cycle_count;
00441 #ifdef DC_HISTOGRAM
00442         /*  SW NOTE
00443          *  I beleive this is executed for the very first decision cycle only.
00444          *  Assuming this holds true, then this should be right.  We start
00445          *  the dc_histogram timer here, and we will stop it every 
00446          *  dc_histogram_freq decision cycles when dc_histogram_now is TRUE
00447          *  when it is stopped (at the end of OUTPUT) it will also be restarted
00448          *  thus, we only need to bootstrap for the 1st dc.
00449          */
00450         start_timer(&current_agent(start_dc_tv));
00451 #endif
00452 
00453     }
00454 
00455     switch (current_agent(current_phase)) {
00456 
00457     case INPUT_PHASE:
00458 #ifdef REAL_TIME_BEHAVIOR
00459         /* RMJ; For real-time behavior, don't start any new decision phase
00460            until the specified "artificial" time step has passed */
00461         start_timer(current_real_time);
00462         if (timercmp(current_real_time, current_agent(real_time_tracker), <)) {
00463             if (!(current_agent(real_time_idling))) {
00464                 current_agent(real_time_idling) = TRUE;
00465                 if (current_agent(sysparams)[TRACE_PHASES_SYSPARAM]) {
00466                     print("\n--- Real-time Idle Phase ---\n");
00467                 }
00468             }
00469             break;
00470         }
00471 
00472         /* Artificial time delay has passed.  Reset new delay and start the
00473            decision phase with input */
00474         current_agent(real_time_tracker)->tv_sec = current_real_time->tv_sec;
00475         current_agent(real_time_tracker)->tv_usec =
00476             current_real_time->tv_usec + 1000 * current_agent(sysparams)[REAL_TIME_SYSPARAM];
00477         if (current_agent(real_time_tracker)->tv_usec >= 1000000) {
00478             current_agent(real_time_tracker)->tv_sec += current_agent(real_time_tracker)->tv_usec / 1000000;
00479             current_agent(real_time_tracker)->tv_usec %= 1000000;
00480         }
00481         current_agent(real_time_idling) = FALSE;
00482 #endif
00483 
00484 #ifdef ATTENTION_LAPSE
00485         /* RMJ; decide whether to start or finish an attentional lapse */
00486         if (current_agent(sysparams)[ATTENTION_LAPSE_ON_SYSPARAM]) {
00487             if (current_agent(attention_lapsing)) {
00488                 /* If lapsing, is it time to stop? */
00489                 start_timer(current_real_time);
00490                 if (timercmp(current_real_time, current_agent(attention_lapse_tracker), >)) {
00491                     wake_from_attention_lapse();
00492                 }
00493             } else {
00494                 /* If not lapsing, should we start? */
00495                 lapse_duration = init_lapse_duration(current_agent(attention_lapse_tracker));
00496                 if (lapse_duration > 0) {
00497                     start_attention_lapse(lapse_duration);
00498                 }
00499             }
00500         }
00501 #endif
00502 
00503 #ifndef KERNEL_TIME_ONLY
00504 #ifndef NO_TIMING_STUFF         /* REW: begin 28.07.96 */
00505         start_timer(&current_agent(start_phase_tv));
00506 #endif
00507 #endif
00508 
00509         /* for Operand2 mode using the new decision cycle ordering,
00510            we need to do some initialization in the INPUT PHASE, which
00511            now comes first.  e_cycles are also zeroed before the APPLY Phase.
00512          */
00513 #ifndef SOAR_8_ONLY
00514         if (current_agent(operand2_mode) == TRUE) {
00515 #endif
00516             current_agent(chunks_this_d_cycle) = 0;
00517             current_agent(e_cycles_this_d_cycle) = 0;
00518 #ifndef SOAR_8_ONLY
00519         }
00520 #endif
00521 
00522 #ifndef FEW_CALLBACKS
00523 
00524         if (current_agent(e_cycles_this_d_cycle) == 0) {
00525             soar_invoke_callbacks(soar_agent, BEFORE_DECISION_CYCLE_CALLBACK, (soar_call_data) NULL);
00526         }
00527 #endif
00528 
00529 #ifndef DONT_DO_IO_CYCLES
00530 
00531         if (current_agent(input_cycle_flag) == TRUE) {  /* AGR REW1 */
00532 
00533 #ifndef FEW_CALLBACKS
00534 
00535             soar_invoke_callbacks(soar_agent, BEFORE_INPUT_PHASE_CALLBACK, (soar_call_data) NULL);
00536 #endif
00537 
00538             /* SW : 120199 timer bug fix */
00539 #ifndef NO_TIMING_STUFF
00540 #ifndef KERNEL_TIME_ONLY
00541             stop_timer(&current_agent(start_phase_tv),
00542                        &current_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00543 #endif
00544             stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
00545             start_timer(&current_agent(start_kernel_tv));
00546 #endif
00547             /* SW : 120199 end */
00548 
00549             do_input_cycle();
00550 
00551             /* SW : 120199 timer bug fix */
00552 #ifndef NO_TIMING_STUFF
00553             stop_timer(&current_agent(start_kernel_tv), &current_agent(input_function_cpu_time));
00554             start_timer(&current_agent(start_kernel_tv));
00555 #ifndef KERNEL_TIME_ONLY
00556             start_timer(&current_agent(start_phase_tv));
00557 #endif
00558 #endif
00559             /* SW : 120199 end */
00560 
00561 #ifndef FEW_CALLBACKS
00562             soar_invoke_callbacks(soar_agent, AFTER_INPUT_PHASE_CALLBACK, (soar_call_data) NULL);
00563 #endif
00564             if (current_agent(input_period))
00565                 current_agent(input_cycle_flag) = FALSE;
00566         }
00567         /* AGR REW1 this line and 1 previous line */
00568 #endif                          /* DONT_DO_IO_CYCLES */
00569 
00570         /* REW: begin 09.15.96 */
00571 #ifndef SOAR_8_ONLY
00572         if (current_agent(operand2_mode) == TRUE) {
00573 #endif
00574             /* REW: begin 05.05.97 */
00575             current_agent(current_phase) = DETERMINE_LEVEL_PHASE;
00576             current_agent(FIRING_TYPE) = IE_PRODS;
00577             /* Pref and WM are now done twice: for propose and apply.
00578                We always need to know which "superphase" we are in. */
00579             current_agent(applyPhase) = FALSE;
00580             /* We now do input only once per decision so we can 'prime' the
00581                decision for a new round of production firings at the end of
00582                the input phase */
00583             initialize_consistency_calculations_for_new_decision();
00584             /* REW: end   05.05.97 */
00585 #ifndef SOAR_8_ONLY
00586         } else {
00587             if (any_assertions_or_retractions_ready())
00588                 current_agent(current_phase) = PREFERENCE_PHASE;
00589             else
00590                 current_agent(current_phase) = DECISION_PHASE;
00591         }
00592 #endif
00593 
00594         /* REW: end   09.15.96 */
00595 
00596         /* SW : 120199 timer bug fix */
00597         /* REW: begin 28.07.96 */
00598 #ifndef KERNEL_TIME_ONLY
00599 #ifndef NO_TIMING_STUFF
00600         stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[INPUT_PHASE]));
00601 #endif
00602 #endif
00603         /* REW: end 28.07.96 */
00604         /* SW 120199 End */
00605 
00606         break;
00607 
00608     case DETERMINE_LEVEL_PHASE:
00609 
00610 #ifndef NO_TIMING_STUFF
00611 #ifndef KERNEL_TIME_ONLY
00612         start_timer(&current_agent(start_phase_tv));
00613 #endif
00614 #endif
00615 
00616         /* Still need to register callbacks for both before and after
00617            the determine_level procedure call. */
00618 
00619         if (current_agent(applyPhase))
00620             determine_highest_active_production_level_in_stack_apply();
00621         else
00622             determine_highest_active_production_level_in_stack_propose();
00623 #ifndef NO_TIMING_STUFF
00624 #ifndef KERNEL_TIME_ONLY
00625         stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[DETERMINE_LEVEL_PHASE]));
00626 #endif
00627 #endif
00628 
00629         break;
00630 
00631     case PREFERENCE_PHASE:
00632 
00633         /* REW: begin 28.07.96 */
00634 #ifndef NO_TIMING_STUFF
00635 #ifndef KERNEL_TIME_ONLY
00636         start_timer(&current_agent(start_phase_tv));
00637 #endif
00638 #endif
00639         /* REW: end 28.07.96 */
00640 
00641 #ifndef FEW_CALLBACKS
00642         soar_invoke_callbacks(soar_agent, BEFORE_PREFERENCE_PHASE_CALLBACK, (soar_call_data) NULL);
00643 #endif
00644         do_preference_phase();
00645 
00646 #ifndef FEW_CALLBACKS
00647         soar_invoke_callbacks(soar_agent, AFTER_PREFERENCE_PHASE_CALLBACK, (soar_call_data) NULL);
00648 #endif
00649         current_agent(current_phase) = WM_PHASE;
00650 
00651         /* REW: begin 28.07.96 */
00652 #ifndef NO_TIMING_STUFF
00653 #ifndef KERNEL_TIME_ONLY
00654         stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[PREFERENCE_PHASE]));
00655 #endif
00656 #endif
00657         /* REW: end 28.07.96 */
00658 
00659 #ifndef SOAR_8_ONLY
00660         if (current_agent(operand2_mode) == FALSE)
00661             break;
00662 #endif
00663         /* if we're in Soar8, then go right to WM_PHASE without stopping */
00664 
00665     case WM_PHASE:
00666         /* REW: begin 28.07.96 */
00667 #ifndef NO_TIMING_STUFF
00668 #ifndef KERNEL_TIME_ONLY
00669         start_timer(&current_agent(start_phase_tv));
00670 #endif
00671 #endif
00672         /* REW: end 28.07.96 */
00673 
00674 #ifndef FEW_CALLBACKS
00675         soar_invoke_callbacks(soar_agent, BEFORE_WM_PHASE_CALLBACK, (soar_call_data) NULL);
00676 #endif
00677         do_working_memory_phase();
00678 
00679 #ifndef FEW_CALLBACKS
00680         soar_invoke_callbacks(soar_agent, AFTER_WM_PHASE_CALLBACK, (soar_call_data) NULL);
00681 #endif
00682 
00683 #ifndef SOAR_8_ONLY
00684         if (current_agent(operand2_mode) == TRUE) {
00685 #endif
00686             /* KJC - New Order: Always follow WM PHASE with DETERMINE_LEVEL_PHASE */
00687             current_agent(current_phase) = DETERMINE_LEVEL_PHASE;
00688 
00689             /* Update accounting.  Moved here by KJC 10-02-98 */
00690             current_agent(e_cycle_count)++;
00691             current_agent(e_cycles_this_d_cycle)++;
00692 
00693             if (current_agent(FIRING_TYPE) == PE_PRODS) {
00694                 /* Keep track of each pe_phase for reporting in stats */
00695                 current_agent(pe_cycle_count)++;
00696                 current_agent(pe_cycles_this_d_cycle)++;
00697             }
00698 #ifndef SOAR_8_ONLY
00699         }
00700 #endif
00701         /* REW: end   10.29.97 */
00702 
00703         else
00704 
00705             current_agent(current_phase) = OUTPUT_PHASE;
00706 
00707         /* REW: begin 28.07.96 */
00708 #ifndef NO_TIMING_STUFF
00709 #ifndef KERNEL_TIME_ONLY
00710         stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[WM_PHASE]));
00711 #endif
00712 #endif
00713         /* REW: end 28.07.96 */
00714         break;
00715 
00716     case OUTPUT_PHASE:
00717         /* REW: begin 28.07.96 */
00718 #ifndef NO_TIMING_STUFF
00719 #ifndef KERNEL_TIME_ONLY
00720         start_timer(&current_agent(start_phase_tv));
00721 #endif
00722 #endif
00723         /* REW: end 28.07.96 */
00724 
00725 #ifndef FEW_CALLBACKS
00726         soar_invoke_callbacks(soar_agent, BEFORE_OUTPUT_PHASE_CALLBACK, (soar_call_data) NULL);
00727 #endif
00728 
00729 #ifndef DONT_DO_IO_CYCLES
00730 
00731         /* REW: begin 28.07.96 */
00732 #ifndef NO_TIMING_STUFF
00733 #ifndef KERNEL_TIME_ONLY
00734         stop_timer(&current_agent(start_phase_tv),
00735                    &current_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00736 #endif
00737         stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
00738         start_timer(&current_agent(start_kernel_tv));
00739 #endif
00740         /* REW: end 28.07.96 */
00741 
00742         do_output_cycle();
00743 
00744         /* REW: begin 28.07.96 */
00745 #ifndef NO_TIMING_STUFF
00746         stop_timer(&current_agent(start_kernel_tv), &current_agent(output_function_cpu_time));
00747         start_timer(&current_agent(start_kernel_tv));
00748 #ifndef KERNEL_TIME_ONLY
00749         start_timer(&current_agent(start_phase_tv));
00750 #endif
00751 #endif
00752 
00753 #endif                          /* DONT_DO_IO_CYCLES */
00754 
00755         /* REW: end 28.07.96 */
00756 
00757 #ifndef FEW_CALLBACKS
00758         soar_invoke_callbacks(soar_agent, AFTER_OUTPUT_PHASE_CALLBACK, (soar_call_data) NULL);
00759 #endif
00760 
00761         /* REW: begin 09.15.96 */
00762 #ifndef SOAR_8_ONLY
00763         if (current_agent(operand2_mode) == TRUE) {
00764 #endif
00765             /* After each OUTPUT_PHASE in Operand2/Waterfall, always return to the 
00766                DETERMINE_LEVEL_PHASE */
00767             /* changed to INPUT LEVEL. KJC 10-04-98 */
00768             current_agent(current_phase) = INPUT_PHASE;
00769 
00770 #ifdef DC_HISTOGRAM
00771             if (current_agent(dc_histogram_now)) {
00772                 /* We check this value /before/ incrementing the d_cycle_count
00773                  * because we want to know when we have /finished/ the dc
00774                  * which is amultiple of dc_histogram_freq.
00775                  * now, we store that value, restart the timer, and incr the d.c. count
00776                  */
00777                 stop_timer(&current_agent(start_dc_tv),
00778                            &current_agent(dc_histogram_tv)[(current_agent(d_cycle_count) /
00779                                                             current_agent(dc_histogram_freq)) - 1]);
00780                 start_timer(&current_agent(start_dc_tv));
00781                 current_agent(dc_histogram_now) = FALSE;
00782             }
00783 #endif                          /* DC_HISTOGRAM */
00784 
00785             /*
00786              * SW 112999 was:
00787              * current_agent(d_cycle_count)++;
00788              */
00789             increment_current_agent_d_cycle_count;
00790 
00791             /* timers stopped KJC 10-04-98 */
00792 #ifndef NO_TIMING_STUFF
00793 #ifndef KERNEL_TIME_ONLY
00794             stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[OUTPUT_PHASE]));
00795 #endif
00796 #endif
00797             break;
00798 
00799 #ifndef SOAR_8_ONLY
00800         }
00801 #endif
00802         /* REW: end 09.15.96 */
00803 
00804         /* otherwise we're in Soar7 mode ...  */
00805 
00806         current_agent(e_cycle_count)++;
00807         current_agent(e_cycles_this_d_cycle)++;
00808 
00809         /* MVP 6-8-94 */
00810         if (current_agent(e_cycles_this_d_cycle) >= (unsigned long) current_agent(sysparams)[MAX_ELABORATIONS_SYSPARAM]) {
00811             if (current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM])
00812                 print("\nWarning: reached max-elaborations; proceeding to decision phase.");
00813             current_agent(current_phase) = DECISION_PHASE;
00814         } else
00815             current_agent(current_phase) = INPUT_PHASE;
00816 
00817         /* REW: begin 28.07.96 */
00818 #ifndef NO_TIMING_STUFF
00819 #ifndef KERNEL_TIME_ONLY
00820         stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[OUTPUT_PHASE]));
00821 #endif
00822 #endif
00823         /* REW: end 28.07.96 */
00824         break;
00825 
00826     case DECISION_PHASE:
00827         /* REW: begin 28.07.96 */
00828 #ifndef NO_TIMING_STUFF
00829 #ifndef KERNEL_TIME_ONLY
00830         start_timer(&current_agent(start_phase_tv));
00831 #endif
00832 #endif
00833         /* REW: end 28.07.96 */
00834 
00835         /* d_cycle_count moved to input phase for Soar 8 new decision cycle */
00836 #ifndef SOAR_8_ONLY
00837         if (current_agent(operand2_mode) == FALSE) {
00838             /*
00839              * SW 11299 was:
00840              * current_agent(d_cycle_count)++;
00841              */
00842             increment_current_agent_d_cycle_count;
00843         }
00844 #endif
00845 
00846 /* AGR REW1 begin */
00847         if (!current_agent(input_period))
00848             current_agent(input_cycle_flag) = TRUE;
00849         else if ((current_agent(d_cycle_count) % current_agent(input_period)) == 0)
00850             current_agent(input_cycle_flag) = TRUE;
00851 
00852 #ifndef FEW_CALLBACKS
00853 /* AGR REW1 end */
00854         soar_invoke_callbacks(soar_agent, BEFORE_DECISION_PHASE_CALLBACK, (soar_call_data) NULL);
00855 #endif
00856         do_decision_phase();
00857 
00858 #ifndef NO_ADP_CALLBACK
00859         soar_invoke_callbacks(soar_agent, AFTER_DECISION_PHASE_CALLBACK, (soar_call_data) NULL);
00860 #endif
00861 
00862 #ifndef NO_ADC_CALLBACK
00863         soar_invoke_callbacks(soar_agent, AFTER_DECISION_CYCLE_CALLBACK, (soar_call_data) NULL);
00864 #endif
00865 
00866         if (current_agent(sysparams)[TRACE_CONTEXT_DECISIONS_SYSPARAM]) {
00867 
00868             /* 
00869                The following statement was previously used only in conjunction
00870                with the TCL interface, however, the new formating is valid
00871                for all Soar8 derivitives, and thus we will use this,
00872                as opposed to the next (commented out) block.
00873                081699 SW
00874              */
00875             print_string("\n");
00876 
00877             /* Unnecessary as of 081699 SW change */
00878             /*
00879                if(current_agent(printer_output_column) != 1)
00880                print_string ("\n");
00881              */
00882 
00883             print_lowest_slot_in_context_stack();
00884         }
00885 #ifndef SOAR_8_ONLY
00886         if (current_agent(operand2_mode) == FALSE) {
00887             current_agent(chunks_this_d_cycle) = 0;
00888         }
00889 #endif
00890 
00891         current_agent(e_cycles_this_d_cycle) = 0;
00892         current_agent(current_phase) = INPUT_PHASE;
00893 
00894         /* REW: begin 09.15.96 */
00895 #ifndef SOAR_8_ONLY
00896         if (current_agent(operand2_mode) == TRUE) {
00897 #endif
00898 
00899 #ifdef AGRESSIVE_ONC
00900             /* test for ONC, if TRUE, generate substate and go to OUTPUT */
00901             if ((current_agent(ms_o_assertions) == NIL) && (current_agent(bottom_goal)->id.operator_slot->wmes != NIL)) {
00902 
00903 #ifndef FEW_CALLBACKS
00904                 soar_invoke_callbacks(soar_agent, BEFORE_DECISION_PHASE_CALLBACK, (soar_call_data) NULL);
00905 #endif
00906                 do_decision_phase();
00907 
00908 #ifndef FEW_CALLBACKS
00909                 soar_invoke_callbacks(soar_agent, AFTER_DECISION_PHASE_CALLBACK, (soar_call_data) NULL);
00910 #endif
00911 
00912                 if (current_agent(sysparams)[TRACE_CONTEXT_DECISIONS_SYSPARAM]) {
00913                     /* 
00914                        The following statement was previously used only in conjunction
00915                        with the TCL interface, however, the new formating is valid
00916                        for all Soar8 derivitives, and thus we will use this,
00917                        as opposed to the next (commented out) block.
00918                        081699 SW
00919                      */
00920                     print_string("\n");
00921 
00922                     /* Unneeded as of 081699 SW changes */
00923                     /*
00924                        if(current_agent(printer_output_column) != 1) print_string ("\n");
00925                      */
00926 
00927                     print_lowest_slot_in_context_stack();
00928                 }
00929 
00930                 /* set phase to OUTPUT */
00931                 current_agent(current_phase) = OUTPUT_PHASE;
00932 
00933                 /* REW: begin 28.07.96 */
00934 #ifndef NO_TIMING_STUFF
00935 #ifndef KERNEL_TIME_ONLY
00936                 stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[DECISION_PHASE]));
00937 #endif
00938 #endif
00939                 /* REW: end 28.07.96 */
00940 
00941                 break;
00942 
00943             } else
00944 /* end AGRESSIVE_ONC    */
00945 #endif
00946 
00947             {
00948                 /* print("\nSetting next phase to APPLY following a decision...."); */
00949                 current_agent(applyPhase) = TRUE;
00950                 current_agent(FIRING_TYPE) = PE_PRODS;
00951                 current_agent(current_phase) = DETERMINE_LEVEL_PHASE;
00952                 /* 'prime' the cycle for a new round of production firings 
00953                    in the APPLY (pref/wm) phase */
00954                 initialize_consistency_calculations_for_new_decision();
00955             }
00956 #ifndef SOAR_8_ONLY
00957         }
00958 #endif
00959 
00960         /* REW: begin 28.07.96 */
00961 #if !defined(NO_TIMING_STUFF) && !defined(KERNEL_TIME_ONLY)
00962         stop_timer(&current_agent(start_phase_tv), &current_agent(decision_cycle_phase_timers[DECISION_PHASE]));
00963 #endif
00964         /* REW: end 28.07.96 */
00965 
00966         break;                  /* end DECISION phase */
00967 
00968     }                           /* end switch stmt for current_phase */
00969 
00970     /* --- update WM size statistics --- */
00971     if (current_agent(num_wmes_in_rete) > current_agent(max_wm_size))
00972         current_agent(max_wm_size) = current_agent(num_wmes_in_rete);
00973     current_agent(cumulative_wm_size) += current_agent(num_wmes_in_rete);
00974     current_agent(num_wm_sizes_accumulated)++;
00975 
00976     if (current_agent(system_halted)) {
00977         current_agent(stop_soar) = TRUE;
00978         current_agent(reason_for_stopping) = "System halted.";
00979 
00980         soar_invoke_callbacks(soar_agent, AFTER_HALT_SOAR_CALLBACK, (soar_call_data) NULL);
00981     }
00982 
00983     if (current_agent(stop_soar)) {
00984 
00985         /* (voigtjr)
00986            this old test is nonsense, it compares pointers:
00987 
00988            if (current_agent(reason_for_stopping) != "")
00989 
00990            what really should happen here is reason_for_stopping should be
00991            set to NULL in the cases where nothing should be printed, instead 
00992            of being assigned a pointer to a zero length (NULL) string, then
00993            we could simply say:
00994 
00995            if (current_agent(reason_for_stopping)) 
00996          */
00997         if (current_agent(reason_for_stopping)) {
00998             if (strcmp(current_agent(reason_for_stopping), "") != 0) {
00999                 print("\n%s", current_agent(reason_for_stopping));
01000             }
01001         }
01002     }
01003 }
01004 
01005 void run_forever(void)
01006 {
01007 #ifndef NO_TIMING_STUFF
01008     start_timer(&current_agent(start_total_tv));
01009     start_timer(&current_agent(start_kernel_tv));
01010 #endif
01011     current_agent(stop_soar) = FALSE;
01012     current_agent(reason_for_stopping) = "";
01013     while (!current_agent(stop_soar)) {
01014         do_one_top_level_phase();
01015     }
01016 #ifndef NO_TIMING_STUFF
01017     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01018     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01019 #endif
01020 }
01021 
01022 void run_for_n_phases(long n)
01023 {
01024     if (n == -1) {
01025         run_forever();
01026         return;
01027     }
01028     if (n < -1)
01029         return;
01030 #ifndef NO_TIMING_STUFF
01031     start_timer(&current_agent(start_total_tv));
01032     start_timer(&current_agent(start_kernel_tv));
01033 #endif
01034     current_agent(stop_soar) = FALSE;
01035     current_agent(reason_for_stopping) = "";
01036     while (!current_agent(stop_soar) && n) {
01037         do_one_top_level_phase();
01038         n--;
01039     }
01040 #ifndef NO_TIMING_STUFF
01041     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01042     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01043 #endif
01044 }
01045 
01046 void run_for_n_elaboration_cycles(long n)
01047 {
01048     long e_cycles_at_start, d_cycles_at_start, elapsed_cycles;
01049 
01050     if (n == -1) {
01051         run_forever();
01052         return;
01053     }
01054     if (n < -1)
01055         return;
01056 #ifndef NO_TIMING_STUFF
01057     start_timer(&current_agent(start_total_tv));
01058     start_timer(&current_agent(start_kernel_tv));
01059 #endif
01060     current_agent(stop_soar) = FALSE;
01061     current_agent(reason_for_stopping) = "";
01062     e_cycles_at_start = current_agent(e_cycle_count);
01063     d_cycles_at_start = current_agent(d_cycle_count);
01064     /* need next line or runs only the input phase for "d 1" after init-soar */
01065 #ifndef SOAR_8_ONLY
01066     if (current_agent(operand2_mode) && (d_cycles_at_start == 0))
01067 #else
01068     if (d_cycles_at_start == 0)
01069 #endif
01070         d_cycles_at_start++;
01071     while (!current_agent(stop_soar)) {
01072         elapsed_cycles = (current_agent(d_cycle_count) - d_cycles_at_start) +
01073             (current_agent(e_cycle_count) - e_cycles_at_start);
01074         if (n == elapsed_cycles)
01075             break;
01076         do_one_top_level_phase();
01077     }
01078 #ifndef NO_TIMING_STUFF
01079     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01080     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01081 #endif
01082 }
01083 
01084 void run_for_n_modifications_of_output(long n)
01085 {
01086     bool was_output_phase;
01087     long count = 0;
01088 
01089     if (n == -1) {
01090         run_forever();
01091         return;
01092     }
01093     if (n < -1)
01094         return;
01095 #ifndef NO_TIMING_STUFF
01096     start_timer(&current_agent(start_total_tv));
01097     start_timer(&current_agent(start_kernel_tv));
01098 #endif
01099     current_agent(stop_soar) = FALSE;
01100     current_agent(reason_for_stopping) = "";
01101 
01102     while (!current_agent(stop_soar) && n) {
01103         was_output_phase = (bool) (current_agent(current_phase) == OUTPUT_PHASE);
01104         do_one_top_level_phase();
01105 
01106         if (was_output_phase) {
01107             if (current_agent(output_link_changed)) {
01108 
01109                 n--;
01110             } else {
01111                 count++;
01112             }
01113         }
01114         if (count > 15) {
01115             current_agent(stop_soar) = TRUE;
01116             current_agent(reason_for_stopping) = "exceeded 15 cycles with no output";
01117         }
01118     }
01119 #ifndef NO_TIMING_STUFF
01120     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01121     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01122 #endif
01123 }
01124 
01125 void run_for_n_decision_cycles(long n)
01126 {
01127     long d_cycles_at_start;
01128 
01129     if (n == -1) {
01130         run_forever();
01131         return;
01132     }
01133     if (n < -1)
01134         return;
01135 #ifndef NO_TIMING_STUFF
01136     start_timer(&current_agent(start_total_tv));
01137     start_timer(&current_agent(start_kernel_tv));
01138 #endif
01139     current_agent(stop_soar) = FALSE;
01140     current_agent(reason_for_stopping) = "";
01141     d_cycles_at_start = current_agent(d_cycle_count);
01142     /* need next line or runs only the input phase for "d 1" after init-soar */
01143 #ifndef SOAR_8_ONLY
01144     if (current_agent(operand2_mode) && (d_cycles_at_start == 0))
01145 #else
01146     if (d_cycles_at_start == 0)
01147 #endif
01148         d_cycles_at_start++;
01149     while (!current_agent(stop_soar)) {
01150         if (n == (long) (current_agent(d_cycle_count) - d_cycles_at_start))
01151             break;
01152         do_one_top_level_phase();
01153     }
01154 #ifndef NO_TIMING_STUFF
01155     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01156     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01157 #endif
01158 }
01159 
01160 Symbol *attr_of_slot_just_decided(void)
01161 {
01162     if (current_agent(bottom_goal)->id.operator_slot->wmes)
01163         return current_agent(operator_symbol);
01164     return current_agent(state_symbol);
01165 }
01166 
01167 void run_for_n_selections_of_slot(long n, Symbol * attr_of_slot)
01168 {
01169     long count;
01170     bool was_decision_phase;
01171 
01172     if (n == -1) {
01173         run_forever();
01174         return;
01175     }
01176     if (n < -1)
01177         return;
01178 #ifndef NO_TIMING_STUFF
01179     start_timer(&current_agent(start_total_tv));
01180     start_timer(&current_agent(start_kernel_tv));
01181 #endif
01182     current_agent(stop_soar) = FALSE;
01183     current_agent(reason_for_stopping) = "";
01184     count = 0;
01185     while (!current_agent(stop_soar) && (count < n)) {
01186         was_decision_phase = (bool) (current_agent(current_phase) == DECISION_PHASE);
01187         do_one_top_level_phase();
01188         if (was_decision_phase)
01189             if (attr_of_slot_just_decided() == attr_of_slot)
01190                 count++;
01191     }
01192 #ifndef NO_TIMING_STUFF
01193     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01194     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01195 #endif
01196 }
01197 
01198 void run_for_n_selections_of_slot_at_level(long n, Symbol * attr_of_slot, goal_stack_level level)
01199 {
01200     long count;
01201     bool was_decision_phase;
01202 
01203     if (n == -1) {
01204         run_forever();
01205         return;
01206     }
01207     if (n < -1)
01208         return;
01209 #ifndef NO_TIMING_STUFF
01210     start_timer(&current_agent(start_total_tv));
01211     start_timer(&current_agent(start_kernel_tv));
01212 #endif
01213     current_agent(stop_soar) = FALSE;
01214     current_agent(reason_for_stopping) = "";
01215     count = 0;
01216     while (!current_agent(stop_soar) && (count < n)) {
01217         was_decision_phase = (bool) (current_agent(current_phase) == DECISION_PHASE);
01218         do_one_top_level_phase();
01219         if (was_decision_phase) {
01220             if (current_agent(bottom_goal)->id.level < level)
01221                 break;
01222             if (current_agent(bottom_goal)->id.level == level) {
01223                 if (attr_of_slot_just_decided() == attr_of_slot)
01224                     count++;
01225             }
01226         }
01227     }
01228 #ifndef NO_TIMING_STUFF
01229     stop_timer(&current_agent(start_total_tv), &current_agent(total_cpu_time));
01230     stop_timer(&current_agent(start_kernel_tv), &current_agent(total_kernel_time));
01231 #endif
01232 }
01233 
01234 /* ===================================================================
01235 
01236                      Print the Startup Banner
01237 
01238 =================================================================== */
01239 
01240 char *soar_news_string = "\
01241 General questions and topics for discussion should be sent to\n\
01242 soar-group@umich.edu. Bug reports should be sent to soar-bugs@umich.edu\n\
01243 The current bug-list may be obtained by sending mail to\n\
01244 soar-bugs@umich.edu with the Subject: line \"bug list\".\n\
01245 The Soar Home Page URL is:  http://ai.eecs.umich.edu/soar\n\
01246 \n\
01247 Copyright (c) 1995-1999 Carnegie Mellon University,\n\
01248                          University of Michigan,\n\
01249                          University of Southern California/Information\n\
01250                          Sciences Institute.  All rights reserved.\n\
01251 The Soar consortium proclaims this software is in the public domain, and\n\
01252 is made available AS IS.  Carnegie Mellon University, The University of \n\
01253 Michigan, and The University of Southern California/Information Sciences \n\
01254 Institute make no warranties about the software or its performance,\n\
01255 implied or otherwise.\n\
01256 \n\
01257 Type \"help\" for information on various topics.\n\
01258 Type \"quit\" to exit Soar.  Use ctrl-c to stop a Soar run.\n\
01259 Type \"soarnews\" to repeat this information.\n\
01260 Type \"version\" for Soar version information.\
01261 ";
01262 
01263 void print_startup_banner(void)
01264 {
01265     print(soar_version_string);
01266     print(soar_news_string);
01267 }
01268 
01269 /* ===================================================================
01270    
01271              Loading the Initialization File ".init.soar"
01272 
01273    This routine looks for a file ".init.soar" in either the current
01274    directory or $HOME, and if found, loads it.
01275 =================================================================== */
01276 
01277 extern char *getenv();
01278 
01279 int terminate_soar(void)
01280 {
01281     /* Shouldn't we free *all* agents here? */
01282     free((void *) soar_agent);
01283 
01284     exit_soar();
01285     return 0;                   /* unreachable, but without it, gcc -Wall warns here */
01286 }

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