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
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include "soarkernel.h"
00060
00061
00062 #define NEW_DECISION 0
00063 #define SAME_LEVEL 1
00064 #define HIGHER_LEVEL 2
00065 #define LOWER_LEVEL 3
00066 #define NIL_GOAL_RETRACTIONS 4
00067
00068
00069
00070 extern void remove_wmes_for_context_slot(slot * s);
00071 extern void remove_existing_context_and_descendents(Symbol * goal);
00072 extern byte type_of_existing_impasse(Symbol * goal);
00073 extern Symbol *attribute_of_existing_impasse(Symbol * goal);
00074 extern byte run_preference_semantics_for_consistency_check(slot * s, preference ** result_candidates);
00075
00076 void remove_operator_if_necessary(slot * s, wme * w);
00077 bool decision_consistent_with_current_preferences(Symbol * goal, slot * s);
00078 void remove_current_decision(slot * s);
00079 bool check_context_slot_decisions(goal_stack_level level);
00080
00081
00082
00083 extern void print_assertion(ms_change * msc);
00084 extern void print_retraction(ms_change * msc);
00085 void initialize_consistency_calculations_for_new_decision();
00086 void determine_highest_active_production_level_in_stack_apply();
00087 void determine_highest_active_production_level_in_stack_propose();
00088 bool goal_stack_consistent_through_goal(Symbol * goal);
00089 bool i_activity_at_goal(Symbol * goal);
00090 bool minor_quiescence_at_goal(Symbol * goal);
00091 int active_production_type_at_goal(Symbol * goal);
00092 Symbol *highest_active_goal_propose();
00093 Symbol *highest_active_goal_apply();
00094
00095
00096 void remove_operator_if_necessary(slot * s, wme * w)
00097 {
00098
00099
00100 #ifndef NO_TIMING_STUFF
00101 #ifdef DETAILED_TIMING_STATS
00102 start_timer(¤t_agent(start_gds_tv));
00103 #endif
00104 #endif
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 if (s->wmes) {
00145 if (s->wmes->value == w->value) {
00146
00147 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00148
00149 if (current_agent(sysparams)[TRACE_OPERAND2_REMOVALS_SYSPARAM]) {
00150 print("\n REMOVING: Operator from context slot (proposal no longer matches): ");
00151 print_wme(w);
00152 }
00153 #endif
00154 remove_wmes_for_context_slot(s);
00155 if (s->id->id.lower_goal)
00156 remove_existing_context_and_descendents(s->id->id.lower_goal);
00157 }
00158 }
00159
00160
00161 #ifndef NO_TIMING_STUFF
00162 #ifdef DETAILED_TIMING_STATS
00163 stop_timer(¤t_agent(start_gds_tv), ¤t_agent(gds_cpu_time[current_agent(current_phase)]));
00164 #endif
00165 #endif
00166
00167 }
00168
00169
00170
00171
00172
00173
00174 bool decision_consistent_with_current_preferences(Symbol * goal, slot * s)
00175 {
00176 byte current_impasse_type, new_impasse_type;
00177 Symbol *current_impasse_attribute;
00178 wme *current_operator;
00179 preference *candidates, *cand;
00180 bool operator_in_slot, goal_is_impassed;
00181
00182 #ifdef DEBUG_CONSISTENCY_CHECK
00183 if (s->isa_context_slot) {
00184 print(" slot (s) isa context slot: ");
00185 print_with_symbols(" Slot Identifier [%y] and attribute [%y]\n", s->id, s->attr);
00186 }
00187
00188 print(" s->impasse_type: %d\n", s->impasse_type);
00189 if (s->impasse_id)
00190 print(" Impasse ID is set (non-NIL)\n");
00191 #endif
00192
00193
00194 if (goal->id.operator_slot->wmes) {
00195
00196 current_operator = goal->id.operator_slot->wmes;
00197 operator_in_slot = TRUE;
00198 } else {
00199
00200 current_operator = NIL;
00201 operator_in_slot = FALSE;
00202 }
00203
00204 if (goal->id.lower_goal) {
00205
00206 goal_is_impassed = TRUE;
00207 current_impasse_type = type_of_existing_impasse(goal);
00208 current_impasse_attribute = attribute_of_existing_impasse(goal);
00209 #ifdef DEBUG_CONSISTENCY_CHECK
00210 print(" Goal is impassed: Impasse type: %d: ", current_impasse_type);
00211 print_with_symbols(" Impasse attribute: [%y]\n", current_impasse_attribute);
00212 #endif
00213
00214 if ((operator_in_slot) && (current_impasse_type == NO_CHANGE_IMPASSE_TYPE)) {
00215
00216
00217
00218
00219
00220
00221
00222 #ifdef DEBUG_CONSISTENCY_CHECK
00223 print(" This is an operator no-change impasse.\n");
00224 #endif
00225 current_impasse_type = NONE_IMPASSE_TYPE;
00226 }
00227 } else {
00228 goal_is_impassed = FALSE;
00229 current_impasse_type = NONE_IMPASSE_TYPE;
00230 current_impasse_attribute = NIL;
00231 #ifdef DEBUG_CONSISTENCY_CHECK
00232 print(" Goal is not impassed: ");
00233 #endif
00234 }
00235
00236
00237 new_impasse_type = run_preference_semantics_for_consistency_check(s, &candidates);
00238
00239 #ifdef DEBUG_CONSISTENCY_CHECK
00240 print(" Impasse Type returned by run preference semantics: %d\n", new_impasse_type);
00241
00242 for (cand = candidates; cand; cand = cand->next) {
00243 print(" Preference for slot:");
00244 print_preference(cand);
00245 }
00246
00247 for (cand = candidates; cand; cand = cand->next_candidate) {
00248 print("\n Candidate for slot:");
00249 print_preference(cand);
00250 }
00251 #endif
00252
00253 if (current_impasse_type != new_impasse_type) {
00254
00255 #ifdef DEBUG_CONSISTENCY_CHECK
00256 print
00257 (" Impasse types are different: Returning FALSE, preferences are not consistent with prior decision.\n");
00258 #endif
00259 return FALSE;
00260 }
00261
00262
00263
00264 switch (new_impasse_type) {
00265
00266 case NONE_IMPASSE_TYPE:
00267
00268
00269
00270
00271
00272
00273 if (operator_in_slot) {
00274 #ifdef DEBUG_CONSISTENCY_CHECK
00275 print(" There is a WME in the operator slot:");
00276 print_wme(current_operator);
00277 #endif
00278
00279
00280
00281 for (cand = candidates; cand; cand = cand->next_candidate) {
00282 if (current_operator->value == cand->value) {
00283 #ifdef DEBUG_CONSISTENCY_CHECK
00284 print_with_symbols(" Operator slot ID [%y] and candidate ID [%y] are the same.\n",
00285 current_operator->value, cand->value);
00286 #endif
00287 return TRUE;
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00296 return FALSE;
00297
00298
00299
00300
00301 } else {
00302 if (goal->id.lower_goal) {
00303 if (goal->id.lower_goal->id.isa_impasse)
00304 print("This goal is an impasse\n");
00305 print(" No Impasse Needed but Impasse exists: remove impasse now\n");
00306 print("\n\n *************This should never be executed*******************\n\n");
00307 return FALSE;
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318 print("\n\n *************This should never be executed*******************\n\n");
00319 return TRUE;
00320 break;
00321
00322 case CONSTRAINT_FAILURE_IMPASSE_TYPE:
00323 #ifdef DEBUG_CONSISTENCY_CHECK
00324 print(" Constraint Failure Impasse: Returning TRUE\n");
00325 #endif
00326 return TRUE;
00327 break;
00328
00329 case CONFLICT_IMPASSE_TYPE:
00330 #ifdef DEBUG_CONSISTENCY_CHECK
00331 print(" Conflict Impasse: Returning TRUE\n");
00332 #endif
00333 return TRUE;
00334 break;
00335
00336 case TIE_IMPASSE_TYPE:
00337 #ifdef DEBUG_CONSISTENCY_CHECK
00338 print(" Tie Impasse: Returning TRUE\n");
00339 #endif
00340 return TRUE;
00341 break;
00342
00343 case NO_CHANGE_IMPASSE_TYPE:
00344 #ifdef DEBUG_CONSISTENCY_CHECK
00345 print(" No change Impasse: Returning TRUE\n");
00346 #endif
00347 return TRUE;
00348 break;
00349 }
00350
00351 print("\n After switch................");
00352 print("\n\n *************This should never be executed*******************\n\n");
00353 return TRUE;
00354
00355 }
00356
00357 void remove_current_decision(slot * s)
00358 {
00359
00360 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00361
00362 if (!s->wmes)
00363 if (current_agent(sysparams)[TRACE_OPERAND2_REMOVALS_SYSPARAM])
00364 print_with_symbols("\n REMOVING CONTEXT SLOT: Slot Identifier [%y] and attribute [%y]\n", s->id,
00365 s->attr);
00366
00367 if (s->id)
00368 if (current_agent(sysparams)[TRACE_OPERAND2_REMOVALS_SYSPARAM])
00369 print_with_symbols("\n Decision for goal [%y] is inconsistent. Replacing it with....\n", s->id);
00370
00371 #endif
00372
00373
00374 remove_wmes_for_context_slot(s);
00375
00376
00377 if (s->id->id.lower_goal)
00378 remove_existing_context_and_descendents(s->id->id.lower_goal);
00379
00380 do_buffered_wm_and_ownership_changes();
00381
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 bool check_context_slot_decisions(goal_stack_level level)
00393 {
00394 Symbol *goal;
00395 slot *s;
00396
00397 #ifdef DEBUG_CONSISTENCY_CHECK
00398 if (current_agent(highest_goal_whose_context_changed))
00399 print_with_symbols(" Highest goal with changed context: [%y]\n",
00400 current_agent(highest_goal_whose_context_changed));
00401 #endif
00402
00403
00404
00405
00406 for (goal = current_agent(highest_goal_whose_context_changed); goal && goal->id.level <= level;
00407 goal = goal->id.lower_goal) {
00408
00409 #ifdef DEBUG_CONSISTENCY_CHECK
00410 print_with_symbols(" Looking at goal [%y] to see if its preferences have changed\n", goal);
00411 #endif
00412 s = goal->id.operator_slot;
00413
00414 if ((goal->id.lower_goal) || (s->wmes)) {
00415
00416 #ifdef DEBUG_CONSISTENCY_CHECK
00417 print
00418 (" This is a goal that either has subgoals or, if the bottom goal, has an operator in the slot\n");
00419 #endif
00420 if (s->changed) {
00421 #ifdef DEBUG_CONSISTENCY_CHECK
00422 print(" This goal's preferences have changed.\n");
00423 #endif
00424 if (!decision_consistent_with_current_preferences(goal, s)) {
00425 #ifdef DEBUG_CONSISTENCY_CHECK
00426 print_with_symbols
00427 (" The current preferences indicate that the decision at [%y] needs to be removed.\n", goal);
00428 #endif
00429
00430 remove_current_decision(s);
00431 return FALSE;
00432 break;
00433 }
00434 }
00435 }
00436 #ifdef DEBUG_CONSISTENCY_CHECK
00437 else {
00438 printf(" This is a bottom goal with no operator in the slot\n");
00439 }
00440 #endif
00441 }
00442
00443 return TRUE;
00444 }
00445
00446
00447
00448 bool i_activity_at_goal(Symbol * goal)
00449 {
00450
00451
00452
00453 if (goal->id.ms_i_assertions)
00454 return TRUE;
00455
00456 if (goal->id.ms_retractions)
00457 return TRUE;
00458
00459
00460 return FALSE;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469 bool minor_quiescence_at_goal(Symbol * goal)
00470 {
00471
00472 if ((current_agent(FIRING_TYPE) == IE_PRODS) && (!i_activity_at_goal(goal)))
00473
00474 return TRUE;
00475 else
00476 return FALSE;
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 Symbol *highest_active_goal_propose()
00490 {
00491
00492 Symbol *goal;
00493
00494 for (goal = current_agent(top_goal); goal; goal = goal->id.lower_goal) {
00495
00496 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00497
00498 print("In highest_active_goal_propose:\n");
00499 if (goal->id.ms_i_assertions)
00500 print_assertion(goal->id.ms_i_assertions);
00501 if (goal->id.ms_retractions)
00502 print_retraction(goal->id.ms_retractions);
00503 #endif
00504
00505
00506 if ((goal->id.ms_i_assertions) || (goal->id.ms_retractions))
00507 return goal;
00508 }
00509
00510
00511
00512
00513
00514
00515
00516 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00517 print("WARNING: Returning NIL active goal because only NIL goal retractions are active.");
00518 #endif
00519 if (current_agent(nil_goal_retractions))
00520 return NIL;
00521 {
00522 char msg[MESSAGE_SIZE];
00523 strncpy(msg, "\n consistency.c: Error: Unable to find an active goal when not at quiescence.\n", MESSAGE_SIZE);
00524 msg[MESSAGE_SIZE - 1] = 0;
00525 abort_with_fatal_error(msg);
00526 }
00527 return NIL;
00528 }
00529
00530 Symbol *highest_active_goal_apply()
00531 {
00532
00533 Symbol *goal;
00534
00535 for (goal = current_agent(top_goal); goal; goal = goal->id.lower_goal) {
00536
00537 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00538
00539 print("In highest_active_goal_apply :\n");
00540 if (goal->id.ms_i_assertions)
00541 print_assertion(goal->id.ms_i_assertions);
00542 if (goal->id.ms_o_assertions)
00543 print_assertion(goal->id.ms_o_assertions);
00544 if (goal->id.ms_retractions)
00545 print_retraction(goal->id.ms_retractions);
00546 #endif
00547
00548
00549 if ((goal->id.ms_i_assertions) || (goal->id.ms_o_assertions)
00550 || (goal->id.ms_retractions))
00551 return goal;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00561 print("WARNING: Returning NIL active goal because only NIL goal retractions are active.");
00562 #endif
00563 if (current_agent(nil_goal_retractions))
00564 return NIL;
00565 {
00566 char msg[MESSAGE_SIZE];
00567 strncpy(msg, "\nconsistency.c: Error: Unable to find an active goal when not at quiescence.\n", MESSAGE_SIZE);
00568 msg[MESSAGE_SIZE - 1] = 0;
00569 abort_with_fatal_error(msg);
00570 }
00571 return NIL;
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 int active_production_type_at_goal(Symbol * goal)
00585 {
00586
00587 if (i_activity_at_goal(goal))
00588 return IE_PRODS;
00589 else
00590 return PE_PRODS;
00591 }
00592
00593
00594
00595 bool goal_stack_consistent_through_goal(Symbol * goal)
00596 {
00597 bool test;
00598
00599 #ifndef NO_TIMING_STUFF
00600 #ifdef DETAILED_TIMING_STATS
00601 start_timer(¤t_agent(start_gds_tv));
00602 #endif
00603 #endif
00604
00605 #ifdef DEBUG_CONSISTENCY_CHECK
00606 print("\nStart: CONSISTENCY CHECK at level %d\n", goal->id.level);
00607
00608
00609 if (current_agent(highest_goal_whose_context_changed)) {
00610 print_with_symbols("current_agent(highest_goal_whose_context_changed) = [%y]\n",
00611 current_agent(highest_goal_whose_context_changed));
00612 } else {
00613 print("Evidently, nothing has changed: not checking slots\n");
00614 }
00615 #endif
00616
00617 test = check_context_slot_decisions(goal->id.level);
00618
00619 #ifdef DEBUG_CONSISTENCY_CHECK
00620 print("\nEnd: CONSISTENCY CHECK\n");
00621 #endif
00622
00623 #ifdef DETAILED_TIMING_STATS
00624 stop_timer(¤t_agent(start_gds_tv), ¤t_agent(gds_cpu_time[current_agent(current_phase)]));
00625 #endif
00626
00627 return test;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636 void initialize_consistency_calculations_for_new_decision()
00637 {
00638
00639 Symbol *goal;
00640
00641 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00642 print("\nInitialize consistency calculations for new decision.\n");
00643 #endif
00644
00645
00646 current_agent(active_level) = 0;
00647 current_agent(active_goal) = NIL;
00648
00649
00650 for (goal = current_agent(top_goal); goal; goal = goal->id.lower_goal)
00651 goal->id.saved_firing_type = NO_SAVED_PRODS;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 void determine_highest_active_production_level_in_stack_apply()
00669 {
00670
00671 Symbol *goal;
00672 int level_change_type, diff;
00673
00674 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00675 if (current_agent(sysparams)[TRACE_PHASES_SYSPARAM])
00676 print("\n--- Application Phase ---\n");
00677 #endif
00678
00679 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00680 print("\nDetermining the highest active level in the stack....\n");
00681 #endif
00682
00683 if (!any_assertions_or_retractions_ready()) {
00684
00685 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00686 print("\n(Full) Quiescence has been reached...going to decision\n");
00687 #endif
00688
00689
00690
00691
00692
00693
00694
00695
00696 if (minor_quiescence_at_goal(current_agent(bottom_goal))) {
00697 goal_stack_consistent_through_goal(current_agent(bottom_goal));
00698 }
00699
00700
00701
00702 current_agent(current_phase) = OUTPUT_PHASE;
00703 return;
00704 }
00705
00706
00707
00708
00709
00710 if (current_agent(e_cycles_this_d_cycle) >= (unsigned long) (current_agent(sysparams)[MAX_ELABORATIONS_SYSPARAM])) {
00711 if (current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM])
00712 print("\nWarning: reached max-elaborations; proceeding to decision phase.");
00713 current_agent(current_phase) = OUTPUT_PHASE;
00714 return;
00715 }
00716
00717
00718 current_agent(previous_active_goal) = current_agent(active_goal);
00719 current_agent(previous_active_level) = current_agent(active_level);
00720
00721
00722 current_agent(active_goal) = highest_active_goal_apply();
00723 if (current_agent(active_goal))
00724 current_agent(active_level) = current_agent(active_goal)->id.level;
00725 else
00726 current_agent(active_level) = 0;
00727
00728 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00729 print("\nHighest level of activity is....%d", current_agent(active_level));
00730 print("\n Previous level of activity is....%d", current_agent(previous_active_level));
00731 #endif
00732
00733 if (!current_agent(active_goal))
00734
00735 level_change_type = NIL_GOAL_RETRACTIONS;
00736 else if (current_agent(previous_active_level) == 0)
00737 level_change_type = NEW_DECISION;
00738 else {
00739 diff = current_agent(active_level) - current_agent(previous_active_level);
00740 if (diff == 0)
00741 level_change_type = SAME_LEVEL;
00742 else if (diff > 0)
00743 level_change_type = LOWER_LEVEL;
00744 else
00745 level_change_type = HIGHER_LEVEL;
00746 }
00747
00748 switch (level_change_type) {
00749 case NIL_GOAL_RETRACTIONS:
00750 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00751 print("\nOnly NIL goal retractions are active");
00752 #endif
00753 current_agent(FIRING_TYPE) = IE_PRODS;
00754 current_agent(current_phase) = PREFERENCE_PHASE;
00755 break;
00756
00757 case NEW_DECISION:
00758 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00759 print("\nThis is a new decision....");
00760 #endif
00761 current_agent(FIRING_TYPE) = active_production_type_at_goal(current_agent(active_goal));
00762
00763
00764
00765 current_agent(current_phase) = PREFERENCE_PHASE;
00766 break;
00767
00768 case LOWER_LEVEL:
00769 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00770 print("\nThe level is lower than the previous level....");
00771 #endif
00772
00773 if (minor_quiescence_at_goal(current_agent(previous_active_goal))) {
00774 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00775 print("\nMinor quiescence at level %d", current_agent(previous_active_level));
00776 #endif
00777 if (!goal_stack_consistent_through_goal(current_agent(previous_active_goal))) {
00778 current_agent(current_phase) = OUTPUT_PHASE;
00779 break;
00780 }
00781 }
00782
00783
00784
00785 goal = current_agent(active_goal);
00786
00787 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00788 if (goal->id.saved_firing_type == IE_PRODS)
00789 print("\nSaved production type: IE _PRODS");
00790 if (goal->id.saved_firing_type == PE_PRODS)
00791 print("\nSaved production type: PE _PRODS");
00792 if (goal->id.saved_firing_type == NO_SAVED_PRODS)
00793 print("\nSaved production type: NONE");
00794 #endif
00795
00796 if (goal->id.saved_firing_type != NO_SAVED_PRODS) {
00797 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00798 print("\nRestoring production type from previous processing at this level");
00799 #endif
00800 current_agent(FIRING_TYPE) = goal->id.saved_firing_type;
00801 current_agent(current_phase) = DETERMINE_LEVEL_PHASE;
00802 break;
00803 }
00804
00805
00806 current_agent(FIRING_TYPE) = active_production_type_at_goal(current_agent(active_goal));
00807 current_agent(current_phase) = PREFERENCE_PHASE;
00808 break;
00809
00810 case SAME_LEVEL:
00811 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00812 print("\nThe level is the same as the previous level....");
00813 #endif
00814 if (minor_quiescence_at_goal(current_agent(active_goal))) {
00815 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00816 print("\nMinor quiescence at level %d", current_agent(active_level));
00817 #endif
00818 if (!goal_stack_consistent_through_goal(current_agent(active_goal))) {
00819 current_agent(current_phase) = OUTPUT_PHASE;
00820 break;
00821 }
00822 }
00823
00824 current_agent(FIRING_TYPE) = active_production_type_at_goal(current_agent(active_goal));
00825 current_agent(current_phase) = PREFERENCE_PHASE;
00826 break;
00827
00828 case HIGHER_LEVEL:
00829 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00830 print("\nThe level is higher than the previous level....");
00831 #endif
00832
00833 goal = current_agent(previous_active_goal);
00834 goal->id.saved_firing_type = current_agent(FIRING_TYPE);
00835
00836 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00837 if (goal->id.saved_firing_type == IE_PRODS)
00838 print("\n Saving current firing type as IE_PRODS");
00839 else if (goal->id.saved_firing_type == PE_PRODS)
00840 print("\n Saving current firing type as PE_PRODS");
00841 else if (goal->id.saved_firing_type == NO_SAVED_PRODS)
00842 print("\n Saving current firing type as NO_SAVED_PRODS");
00843 else
00844 print("\n Unknown SAVED firing type???????");
00845 #endif
00846
00847
00848
00849
00850 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00851 print("\nMinor quiescence at level %d", current_agent(active_level));
00852 #endif
00853 if (!goal_stack_consistent_through_goal(current_agent(active_goal))) {
00854 current_agent(current_phase) = OUTPUT_PHASE;
00855 break;
00856 }
00857
00858
00859
00860 current_agent(FIRING_TYPE) = active_production_type_at_goal(current_agent(active_goal));
00861 current_agent(current_phase) = PREFERENCE_PHASE;
00862 break;
00863 }
00864
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 void determine_highest_active_production_level_in_stack_propose()
00886 {
00887
00888 Symbol *goal;
00889 int level_change_type, diff;
00890
00891 #ifndef TRACE_CONTEXT_DECISIONS_ONLY
00892 if (current_agent(sysparams)[TRACE_PHASES_SYSPARAM])
00893 print("\n--- Proposal Phase ---\n");
00894 #endif
00895
00896 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00897 print("\n(Propose) Determining the highest active level in the stack....\n");
00898 #endif
00899
00900
00901
00902
00903 if (!(current_agent(ms_retractions) || current_agent(ms_i_assertions))) {
00904
00905
00906 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00907 print("\n Propose Phase Quiescence has been reached...going to decision\n");
00908 #endif
00909
00910
00911
00912 goal_stack_consistent_through_goal(current_agent(bottom_goal));
00913
00914
00915 current_agent(current_phase) = DECISION_PHASE;
00916 return;
00917 }
00918
00919
00920
00921
00922
00923 if (current_agent(e_cycles_this_d_cycle) >= (unsigned long) (current_agent(sysparams)[MAX_ELABORATIONS_SYSPARAM])) {
00924 if (current_agent(sysparams)[PRINT_WARNINGS_SYSPARAM])
00925 print("\nWarning: reached max-elaborations; proceeding to decision phase.");
00926 current_agent(current_phase) = DECISION_PHASE;
00927 return;
00928 }
00929
00930
00931
00932
00933
00934 current_agent(previous_active_goal) = current_agent(active_goal);
00935 current_agent(previous_active_level) = current_agent(active_level);
00936
00937
00938 current_agent(active_goal) = highest_active_goal_propose();
00939 if (current_agent(active_goal))
00940 current_agent(active_level) = current_agent(active_goal)->id.level;
00941 else
00942 current_agent(active_level) = 0;
00943
00944 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00945 print("\nHighest level of activity is....%d", current_agent(active_level));
00946 print("\n Previous level of activity is....%d", current_agent(previous_active_level));
00947 #endif
00948
00949 if (!current_agent(active_goal))
00950
00951 level_change_type = NIL_GOAL_RETRACTIONS;
00952 else if (current_agent(previous_active_level) == 0)
00953 level_change_type = NEW_DECISION;
00954 else {
00955 diff = current_agent(active_level) - current_agent(previous_active_level);
00956 if (diff == 0)
00957 level_change_type = SAME_LEVEL;
00958 else if (diff > 0)
00959 level_change_type = LOWER_LEVEL;
00960 else
00961 level_change_type = HIGHER_LEVEL;
00962 }
00963
00964 switch (level_change_type) {
00965 case NIL_GOAL_RETRACTIONS:
00966 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00967 print("\nOnly NIL goal retractions are active");
00968 #endif
00969 current_agent(FIRING_TYPE) = IE_PRODS;
00970 current_agent(current_phase) = PREFERENCE_PHASE;
00971 break;
00972
00973 case NEW_DECISION:
00974 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00975 print("\nThis is a new decision....");
00976 #endif
00977 current_agent(FIRING_TYPE) = IE_PRODS;
00978 current_agent(current_phase) = PREFERENCE_PHASE;
00979 break;
00980
00981 case LOWER_LEVEL:
00982 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00983 print("\nThe level is lower than the previous level....");
00984 #endif
00985
00986
00987 if (!goal_stack_consistent_through_goal(current_agent(previous_active_goal))) {
00988 current_agent(current_phase) = DECISION_PHASE;
00989 break;
00990 }
00991
00992
00993 current_agent(FIRING_TYPE) = IE_PRODS;
00994 current_agent(current_phase) = PREFERENCE_PHASE;
00995 break;
00996
00997 case SAME_LEVEL:
00998 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
00999 print("\nThe level is the same as the previous level....");
01000 #endif
01001 current_agent(FIRING_TYPE) = IE_PRODS;
01002 current_agent(current_phase) = PREFERENCE_PHASE;
01003 break;
01004
01005 case HIGHER_LEVEL:
01006 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
01007 print("\nThe level is higher than the previous level....");
01008 #endif
01009
01010 goal = current_agent(previous_active_goal);
01011 goal->id.saved_firing_type = current_agent(FIRING_TYPE);
01012
01013 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
01014 if (goal->id.saved_firing_type == IE_PRODS)
01015 print("\n Saving current firing type as IE_PRODS");
01016 else if (goal->id.saved_firing_type == PE_PRODS)
01017 print("\n Saving current firing type as PE_PRODS");
01018 else if (goal->id.saved_firing_type == NO_SAVED_PRODS)
01019 print("\n Saving current firing type as NO_SAVED_PRODS");
01020 else
01021 print("\n Unknown SAVED firing type???????");
01022 #endif
01023
01024
01025
01026
01027 #ifdef DEBUG_DETERMINE_LEVEL_PHASE
01028 print("\nMinor quiescence at level %d", current_agent(active_level));
01029 #endif
01030 if (!goal_stack_consistent_through_goal(current_agent(active_goal))) {
01031 current_agent(current_phase) = DECISION_PHASE;
01032 break;
01033 }
01034
01035
01036
01037
01038 current_agent(FIRING_TYPE) = IE_PRODS;
01039 current_agent(current_phase) = PREFERENCE_PHASE;
01040 break;
01041 }
01042
01043 }
01044
01045