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 #define _ENGINE_SOURCE_
00046
00047 #include <stdio.h>
00048 #define _STDIO_INCLUDED_
00049 #include <string.h>
00050
00051 #include "setup.h"
00052
00053 #if DEFRULE_CONSTRUCT
00054
00055 #include "agenda.h"
00056 #include "argacces.h"
00057 #include "constant.h"
00058 #include "envrnmnt.h"
00059 #include "factmngr.h"
00060 #include "inscom.h"
00061 #include "memalloc.h"
00062 #include "modulutl.h"
00063 #include "prccode.h"
00064 #include "prcdrfun.h"
00065 #include "proflfun.h"
00066 #include "reteutil.h"
00067 #include "retract.h"
00068 #include "router.h"
00069 #include "ruledlt.h"
00070 #include "sysdep.h"
00071 #include "utility.h"
00072 #include "watch.h"
00073
00074 #include "engine.h"
00075
00076
00077
00078
00079
00080 static struct activation *NextActivationToFire(void *);
00081 static struct defmodule *RemoveFocus(void *,struct defmodule *);
00082 static void DeallocateEngineData(void *);
00083
00084
00085
00086
00087 globle void InitializeEngine(
00088 void *theEnv)
00089 {
00090 AllocateEnvironmentData(theEnv,ENGINE_DATA,sizeof(struct engineData),DeallocateEngineData);
00091
00092 EngineData(theEnv)->IncrementalResetFlag = TRUE;
00093
00094 #if DEBUGGING_FUNCTIONS
00095 AddWatchItem(theEnv,"statistics",0,&EngineData(theEnv)->WatchStatistics,20,NULL,NULL);
00096 AddWatchItem(theEnv,"focus",0,&EngineData(theEnv)->WatchFocus,0,NULL,NULL);
00097 #endif
00098 }
00099
00100
00101
00102
00103
00104 static void DeallocateEngineData(
00105 void *theEnv)
00106 {
00107 struct focus *tmpPtr, *nextPtr;
00108
00109 DeallocateCallList(theEnv,EngineData(theEnv)->ListOfRunFunctions);
00110
00111 tmpPtr = EngineData(theEnv)->CurrentFocus;
00112 while (tmpPtr != NULL)
00113 {
00114 nextPtr = tmpPtr->next;
00115 rtn_struct(theEnv,focus,tmpPtr);
00116 tmpPtr = nextPtr;
00117 }
00118 }
00119
00120
00121
00122
00123 #if ALLOW_ENVIRONMENT_GLOBALS
00124 globle long long Run(
00125 long long runLimit)
00126 {
00127 return EnvRun(GetCurrentEnvironment(),runLimit);
00128 }
00129 #endif
00130
00131
00132
00133
00134 globle long long EnvRun(
00135 void *theEnv,
00136 long long runLimit)
00137 {
00138 long long rulesFired = 0;
00139 DATA_OBJECT result;
00140 struct callFunctionItem *theRunFunction;
00141 #if DEBUGGING_FUNCTIONS
00142 unsigned long maxActivations = 0, sumActivations = 0;
00143 #if DEFTEMPLATE_CONSTRUCT
00144 unsigned long maxFacts = 0, sumFacts = 0;
00145 #endif
00146 #if OBJECT_SYSTEM
00147 unsigned long maxInstances = 0, sumInstances = 0;
00148 #endif
00149 double endTime, startTime = 0.0;
00150 unsigned long tempValue;
00151 #endif
00152 unsigned short i;
00153 struct patternEntity *theMatchingItem;
00154 struct partialMatch *theBasis;
00155 ACTIVATION *theActivation;
00156 char *ruleFiring;
00157 #if PROFILING_FUNCTIONS
00158 struct profileFrameInfo profileFrame;
00159 #endif
00160 struct trackedMemory *theTM;
00161
00162
00163
00164
00165
00166 if (EngineData(theEnv)->AlreadyRunning) return(0);
00167 EngineData(theEnv)->AlreadyRunning = TRUE;
00168
00169
00170
00171
00172
00173 #if DEBUGGING_FUNCTIONS
00174 if (EngineData(theEnv)->WatchStatistics)
00175 {
00176 #if DEFTEMPLATE_CONSTRUCT
00177 maxFacts = GetNumberOfFacts(theEnv);
00178 sumFacts = maxFacts;
00179 #endif
00180 #if OBJECT_SYSTEM
00181 maxInstances = GetGlobalNumberOfInstances(theEnv);
00182 sumInstances = maxInstances;
00183 #endif
00184 maxActivations = GetNumberOfActivations(theEnv);
00185 sumActivations = maxActivations;
00186 startTime = gentime();
00187 }
00188 #endif
00189
00190
00191
00192
00193
00194 if (EvaluationData(theEnv)->CurrentEvaluationDepth == 0) SetHaltExecution(theEnv,FALSE);
00195 EngineData(theEnv)->HaltRules = FALSE;
00196
00197 #if DEVELOPER
00198 EngineData(theEnv)->leftToRightComparisons = 0;
00199 EngineData(theEnv)->rightToLeftComparisons = 0;
00200 EngineData(theEnv)->leftToRightSucceeds = 0;
00201 EngineData(theEnv)->rightToLeftSucceeds = 0;
00202 EngineData(theEnv)->leftToRightLoops = 0;
00203 EngineData(theEnv)->rightToLeftLoops = 0;
00204 EngineData(theEnv)->findNextConflictingComparisons = 0;
00205 EngineData(theEnv)->betaHashListSkips = 0;
00206 EngineData(theEnv)->betaHashHTSkips = 0;
00207 EngineData(theEnv)->unneededMarkerCompare = 0;
00208 #endif
00209
00210
00211
00212
00213
00214
00215 theActivation = NextActivationToFire(theEnv);
00216 while ((theActivation != NULL) &&
00217 (runLimit != 0) &&
00218 (EvaluationData(theEnv)->HaltExecution == FALSE) &&
00219 (EngineData(theEnv)->HaltRules == FALSE))
00220 {
00221
00222
00223
00224
00225
00226 DetachActivation(theEnv,theActivation);
00227 theTM = AddTrackedMemory(theEnv,theActivation,sizeof(struct activation));
00228 ruleFiring = EnvGetActivationName(theEnv,theActivation);
00229 theBasis = (struct partialMatch *) GetActivationBasis(theActivation);
00230 EngineData(theEnv)->ExecutingRule = (struct defrule *) GetActivationRule(theActivation);
00231
00232
00233
00234
00235
00236 rulesFired++;
00237 if (runLimit > 0) { runLimit--; }
00238
00239
00240
00241
00242
00243
00244 #if DEBUGGING_FUNCTIONS
00245 if (EngineData(theEnv)->ExecutingRule->watchFiring)
00246 {
00247 char printSpace[60];
00248
00249 gensprintf(printSpace,"FIRE %4lld ",rulesFired);
00250 EnvPrintRouter(theEnv,WTRACE,printSpace);
00251 EnvPrintRouter(theEnv,WTRACE,ruleFiring);
00252 EnvPrintRouter(theEnv,WTRACE,": ");
00253 PrintPartialMatch(theEnv,WTRACE,theBasis);
00254 EnvPrintRouter(theEnv,WTRACE,"\n");
00255 }
00256 #endif
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 theBasis->marker = NULL;
00269 theBasis->busy = TRUE;
00270
00271 EngineData(theEnv)->GlobalLHSBinds = theBasis;
00272 EngineData(theEnv)->GlobalRHSBinds = NULL;
00273
00274
00275
00276
00277
00278
00279
00280 for (i = 0; i < theBasis->bcount; i++)
00281 {
00282 if (theBasis->binds[i].gm.theMatch == NULL) continue;
00283 theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem;
00284 if (theMatchingItem != NULL)
00285 { (*theMatchingItem->theInfo->incrementBasisCount)(theEnv,theMatchingItem); }
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 EngineData(theEnv)->TheLogicalJoin = EngineData(theEnv)->ExecutingRule->logicalJoin;
00296
00297 if (EngineData(theEnv)->TheLogicalJoin != NULL)
00298 {
00299 EngineData(theEnv)->TheLogicalBind = FindLogicalBind(EngineData(theEnv)->TheLogicalJoin,EngineData(theEnv)->GlobalLHSBinds);
00300 EngineData(theEnv)->TheLogicalBind->busy = TRUE;
00301 }
00302 else
00303 { EngineData(theEnv)->TheLogicalBind = NULL; }
00304
00305 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00306 SetEvaluationError(theEnv,FALSE);
00307 EngineData(theEnv)->ExecutingRule->executing = TRUE;
00308
00309 #if PROFILING_FUNCTIONS
00310 StartProfile(theEnv,&profileFrame,
00311 &EngineData(theEnv)->ExecutingRule->header.usrData,
00312 ProfileFunctionData(theEnv)->ProfileConstructs);
00313 #endif
00314
00315 EvaluateProcActions(theEnv,EngineData(theEnv)->ExecutingRule->header.whichModule->theModule,
00316 EngineData(theEnv)->ExecutingRule->actions,EngineData(theEnv)->ExecutingRule->localVarCnt,
00317 &result,NULL);
00318
00319 #if PROFILING_FUNCTIONS
00320 EndProfile(theEnv,&profileFrame);
00321 #endif
00322
00323 EngineData(theEnv)->ExecutingRule->executing = FALSE;
00324 SetEvaluationError(theEnv,FALSE);
00325 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00326 EngineData(theEnv)->TheLogicalJoin = NULL;
00327
00328 if (EngineData(theEnv)->TheLogicalBind != NULL)
00329 {
00330 EngineData(theEnv)->TheLogicalBind->busy = FALSE;
00331 EngineData(theEnv)->TheLogicalBind = NULL;
00332 }
00333
00334
00335
00336
00337
00338 #if DEBUGGING_FUNCTIONS
00339 if ((EvaluationData(theEnv)->HaltExecution) || (EngineData(theEnv)->HaltRules && EngineData(theEnv)->ExecutingRule->watchFiring))
00340 #else
00341 if ((EvaluationData(theEnv)->HaltExecution) || (EngineData(theEnv)->HaltRules))
00342 #endif
00343
00344 {
00345 PrintErrorID(theEnv,"PRCCODE",4,FALSE);
00346 EnvPrintRouter(theEnv,WERROR,"Execution halted during the actions of defrule ");
00347 EnvPrintRouter(theEnv,WERROR,ruleFiring);
00348 EnvPrintRouter(theEnv,WERROR,".\n");
00349 }
00350
00351
00352
00353
00354
00355
00356 theBasis->busy = FALSE;
00357
00358 for (i = 0; i < (theBasis->bcount); i++)
00359 {
00360 if (theBasis->binds[i].gm.theMatch == NULL) continue;
00361 theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem;
00362 if (theMatchingItem != NULL)
00363 { (*theMatchingItem->theInfo->decrementBasisCount)(theEnv,theMatchingItem); }
00364 }
00365
00366
00367
00368
00369
00370 RemoveTrackedMemory(theEnv,theTM);
00371 RemoveActivation(theEnv,theActivation,FALSE,FALSE);
00372
00373
00374
00375
00376
00377
00378 FlushGarbagePartialMatches(theEnv);
00379
00380
00381
00382
00383
00384
00385 PeriodicCleanup(theEnv,FALSE,TRUE);
00386
00387
00388
00389
00390
00391 #if DEBUGGING_FUNCTIONS
00392 if (EngineData(theEnv)->WatchStatistics)
00393 {
00394 #if DEFTEMPLATE_CONSTRUCT
00395 tempValue = GetNumberOfFacts(theEnv);
00396 if (tempValue > maxFacts) maxFacts = tempValue;
00397 sumFacts += tempValue;
00398 #endif
00399 #if OBJECT_SYSTEM
00400 tempValue = GetGlobalNumberOfInstances(theEnv);
00401 if (tempValue > maxInstances) maxInstances = tempValue;
00402 sumInstances += tempValue;
00403 #endif
00404 tempValue = GetNumberOfActivations(theEnv);
00405 if (tempValue > maxActivations) maxActivations = tempValue;
00406 sumActivations += tempValue;
00407 }
00408 #endif
00409
00410
00411
00412
00413
00414 if (EnvGetSalienceEvaluation(theEnv) == EVERY_CYCLE) EnvRefreshAgenda(theEnv,NULL);
00415
00416
00417
00418
00419
00420
00421 for (theRunFunction = EngineData(theEnv)->ListOfRunFunctions;
00422 theRunFunction != NULL;
00423 theRunFunction = theRunFunction->next)
00424 {
00425 SetEnvironmentCallbackContext(theEnv,theRunFunction->context);
00426 if (theRunFunction->environmentAware)
00427 { (*theRunFunction->func)(theEnv); }
00428 else
00429 { ((void (*)(void))(*theRunFunction->func))(); }
00430 }
00431
00432
00433
00434
00435
00436
00437
00438 if (ProcedureFunctionData(theEnv)->ReturnFlag == TRUE)
00439 { RemoveFocus(theEnv,EngineData(theEnv)->ExecutingRule->header.whichModule->theModule); }
00440 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
00441
00442
00443
00444
00445
00446 theActivation = (struct activation *) NextActivationToFire(theEnv);
00447
00448
00449
00450
00451
00452 if (theActivation != NULL)
00453 {
00454 if (((struct defrule *) GetActivationRule(theActivation))->afterBreakpoint)
00455 {
00456 EngineData(theEnv)->HaltRules = TRUE;
00457 EnvPrintRouter(theEnv,WDIALOG,"Breaking on rule ");
00458 EnvPrintRouter(theEnv,WDIALOG,EnvGetActivationName(theEnv,theActivation));
00459 EnvPrintRouter(theEnv,WDIALOG,".\n");
00460 }
00461 }
00462 }
00463
00464
00465
00466
00467
00468 if (rulesFired == 0)
00469 {
00470 for (theRunFunction = EngineData(theEnv)->ListOfRunFunctions;
00471 theRunFunction != NULL;
00472 theRunFunction = theRunFunction->next)
00473 {
00474 if (theRunFunction->environmentAware)
00475 { (*theRunFunction->func)(theEnv); }
00476 else
00477 { ((void (*)(void))(*theRunFunction->func))(); }
00478 }
00479 }
00480
00481
00482
00483
00484
00485
00486 if (runLimit == rulesFired)
00487 { EnvPrintRouter(theEnv,WDIALOG,"rule firing limit reached\n"); }
00488
00489
00490
00491
00492
00493 EngineData(theEnv)->ExecutingRule = NULL;
00494 EngineData(theEnv)->HaltRules = FALSE;
00495
00496
00497
00498
00499
00500 #if DEBUGGING_FUNCTIONS
00501 if (EngineData(theEnv)->WatchStatistics)
00502 {
00503 char printSpace[60];
00504
00505 endTime = gentime();
00506
00507 PrintLongInteger(theEnv,WDIALOG,rulesFired);
00508 EnvPrintRouter(theEnv,WDIALOG," rules fired");
00509
00510 #if (! GENERIC)
00511 if (startTime != endTime)
00512 {
00513 EnvPrintRouter(theEnv,WDIALOG," Run time is ");
00514 PrintFloat(theEnv,WDIALOG,endTime - startTime);
00515 EnvPrintRouter(theEnv,WDIALOG," seconds.\n");
00516 PrintFloat(theEnv,WDIALOG,(double) rulesFired / (endTime - startTime));
00517 EnvPrintRouter(theEnv,WDIALOG," rules per second.\n");
00518 }
00519 else
00520 { EnvPrintRouter(theEnv,WDIALOG,"\n"); }
00521 #endif
00522
00523 #if DEFTEMPLATE_CONSTRUCT
00524 gensprintf(printSpace,"%ld mean number of facts (%ld maximum).\n",
00525 (long) (((double) sumFacts / (rulesFired + 1)) + 0.5),
00526 maxFacts);
00527 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00528 #endif
00529
00530 #if OBJECT_SYSTEM
00531 gensprintf(printSpace,"%ld mean number of instances (%ld maximum).\n",
00532 (long) (((double) sumInstances / (rulesFired + 1)) + 0.5),
00533 maxInstances);
00534 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00535 #endif
00536
00537 gensprintf(printSpace,"%ld mean number of activations (%ld maximum).\n",
00538 (long) (((double) sumActivations / (rulesFired + 1)) + 0.5),
00539 maxActivations);
00540 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00541
00542 #if DEVELOPER
00543 gensprintf(printSpace,"%9ld left to right comparisons.\n",
00544 EngineData(theEnv)->leftToRightComparisons);
00545 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00546
00547 gensprintf(printSpace,"%9ld left to right succeeds.\n",
00548 EngineData(theEnv)->leftToRightSucceeds);
00549 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00550
00551 gensprintf(printSpace,"%9ld left to right loops.\n",
00552 EngineData(theEnv)->leftToRightLoops);
00553 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00554
00555 gensprintf(printSpace,"%9ld right to left comparisons.\n",
00556 EngineData(theEnv)->rightToLeftComparisons);
00557 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00558
00559 gensprintf(printSpace,"%9ld right to left succeeds.\n",
00560 EngineData(theEnv)->rightToLeftSucceeds);
00561 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00562
00563 gensprintf(printSpace,"%9ld right to left loops.\n",
00564 EngineData(theEnv)->rightToLeftLoops);
00565 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00566
00567 gensprintf(printSpace,"%9ld find next conflicting comparisons.\n",
00568 EngineData(theEnv)->findNextConflictingComparisons);
00569 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00570
00571 gensprintf(printSpace,"%9ld beta hash list skips.\n",
00572 EngineData(theEnv)->betaHashListSkips);
00573 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00574
00575 gensprintf(printSpace,"%9ld beta hash hash table skips.\n",
00576 EngineData(theEnv)->betaHashHTSkips);
00577 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00578
00579 gensprintf(printSpace,"%9ld unneeded marker compare.\n",
00580 EngineData(theEnv)->unneededMarkerCompare);
00581 EnvPrintRouter(theEnv,WDIALOG,printSpace);
00582
00583 #endif
00584 }
00585 #endif
00586
00587
00588
00589
00590
00591
00592 if (EngineData(theEnv)->CurrentFocus != NULL)
00593 {
00594 if (EngineData(theEnv)->CurrentFocus->theModule != ((struct defmodule *) EnvGetCurrentModule(theEnv)))
00595 { EnvSetCurrentModule(theEnv,(void *) EngineData(theEnv)->CurrentFocus->theModule); }
00596 }
00597
00598
00599
00600
00601
00602 EngineData(theEnv)->AlreadyRunning = FALSE;
00603 return(rulesFired);
00604 }
00605
00606
00607
00608
00609
00610 static struct activation *NextActivationToFire(
00611 void *theEnv)
00612 {
00613 struct activation *theActivation;
00614 struct defmodule *theModule;
00615
00616
00617
00618
00619
00620
00621 if (EngineData(theEnv)->CurrentFocus == NULL)
00622 {
00623 theModule = (struct defmodule *) EnvFindDefmodule(theEnv,"MAIN");
00624 EnvFocus(theEnv,theModule);
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634 theActivation = EngineData(theEnv)->CurrentFocus->theDefruleModule->agenda;
00635 while ((theActivation == NULL) && (EngineData(theEnv)->CurrentFocus != NULL))
00636 {
00637 if (EngineData(theEnv)->CurrentFocus != NULL) EnvPopFocus(theEnv);
00638 if (EngineData(theEnv)->CurrentFocus != NULL) theActivation = EngineData(theEnv)->CurrentFocus->theDefruleModule->agenda;
00639 }
00640
00641
00642
00643
00644
00645 return(theActivation);
00646 }
00647
00648
00649
00650
00651
00652 static struct defmodule *RemoveFocus(
00653 void *theEnv,
00654 struct defmodule *theModule)
00655 {
00656 struct focus *tempFocus,*prevFocus, *nextFocus;
00657 int found = FALSE;
00658 int currentFocusRemoved = FALSE;
00659
00660
00661
00662
00663
00664
00665 if (EngineData(theEnv)->CurrentFocus == NULL) return(NULL);
00666
00667
00668
00669
00670
00671
00672 prevFocus = NULL;
00673 tempFocus = EngineData(theEnv)->CurrentFocus;
00674 while ((tempFocus != NULL) && (! found))
00675 {
00676 if (tempFocus->theModule == theModule)
00677 {
00678 found = TRUE;
00679
00680 nextFocus = tempFocus->next;
00681 rtn_struct(theEnv,focus,tempFocus);
00682 tempFocus = nextFocus;
00683
00684 if (prevFocus == NULL)
00685 {
00686 currentFocusRemoved = TRUE;
00687 EngineData(theEnv)->CurrentFocus = tempFocus;
00688 }
00689 else
00690 { prevFocus->next = tempFocus; }
00691 }
00692 else
00693 {
00694 prevFocus = tempFocus;
00695 tempFocus = tempFocus->next;
00696 }
00697 }
00698
00699
00700
00701
00702
00703
00704 if (! found) return(EngineData(theEnv)->CurrentFocus->theModule);
00705
00706
00707
00708
00709
00710
00711 #if DEBUGGING_FUNCTIONS
00712 if (EngineData(theEnv)->WatchFocus)
00713 {
00714 EnvPrintRouter(theEnv,WTRACE,"<== Focus ");
00715 EnvPrintRouter(theEnv,WTRACE,ValueToString(theModule->name));
00716
00717 if ((EngineData(theEnv)->CurrentFocus != NULL) && currentFocusRemoved)
00718 {
00719 EnvPrintRouter(theEnv,WTRACE," to ");
00720 EnvPrintRouter(theEnv,WTRACE,ValueToString(EngineData(theEnv)->CurrentFocus->theModule->name));
00721 }
00722
00723 EnvPrintRouter(theEnv,WTRACE,"\n");
00724 }
00725 #endif
00726
00727
00728
00729
00730
00731
00732
00733 if ((EngineData(theEnv)->CurrentFocus != NULL) && currentFocusRemoved)
00734 { EnvSetCurrentModule(theEnv,(void *) EngineData(theEnv)->CurrentFocus->theModule); }
00735 EngineData(theEnv)->FocusChanged = TRUE;
00736
00737
00738
00739
00740
00741
00742 return(theModule);
00743 }
00744
00745
00746
00747
00748 globle void *EnvPopFocus(
00749 void *theEnv)
00750 {
00751 if (EngineData(theEnv)->CurrentFocus == NULL) return(NULL);
00752 return((void *) RemoveFocus(theEnv,EngineData(theEnv)->CurrentFocus->theModule));
00753 }
00754
00755
00756
00757
00758 globle void *EnvGetNextFocus(
00759 void *theEnv,
00760 void *theFocus)
00761 {
00762
00763
00764
00765
00766
00767 if (theFocus == NULL) return((void *) EngineData(theEnv)->CurrentFocus);
00768
00769
00770
00771
00772
00773
00774 return((void *) ((struct focus *) theFocus)->next);
00775 }
00776
00777
00778
00779
00780 globle void EnvFocus(
00781 void *theEnv,
00782 void *vTheModule)
00783 {
00784 struct defmodule *theModule = (struct defmodule *) vTheModule;
00785 struct focus *tempFocus;
00786
00787
00788
00789
00790
00791
00792
00793 EnvSetCurrentModule(theEnv,(void *) theModule);
00794 if (EngineData(theEnv)->CurrentFocus != NULL)
00795 { if (EngineData(theEnv)->CurrentFocus->theModule == theModule) return; }
00796
00797
00798
00799
00800
00801
00802 #if DEBUGGING_FUNCTIONS
00803 if (EngineData(theEnv)->WatchFocus)
00804 {
00805 EnvPrintRouter(theEnv,WTRACE,"==> Focus ");
00806 EnvPrintRouter(theEnv,WTRACE,ValueToString(theModule->name));
00807 if (EngineData(theEnv)->CurrentFocus != NULL)
00808 {
00809 EnvPrintRouter(theEnv,WTRACE," from ");
00810 EnvPrintRouter(theEnv,WTRACE,ValueToString(EngineData(theEnv)->CurrentFocus->theModule->name));
00811 }
00812 EnvPrintRouter(theEnv,WTRACE,"\n");
00813 }
00814 #endif
00815
00816
00817
00818
00819
00820 tempFocus = get_struct(theEnv,focus);
00821 tempFocus->theModule = theModule;
00822 tempFocus->theDefruleModule = GetDefruleModuleItem(theEnv,theModule);
00823 tempFocus->next = EngineData(theEnv)->CurrentFocus;
00824 EngineData(theEnv)->CurrentFocus = tempFocus;
00825 EngineData(theEnv)->FocusChanged = TRUE;
00826 }
00827
00828
00829
00830
00831
00832 globle void ClearFocusStackCommand(
00833 void *theEnv)
00834 {
00835 if (EnvArgCountCheck(theEnv,"list-focus-stack",EXACTLY,0) == -1) return;
00836
00837 EnvClearFocusStack(theEnv);
00838 }
00839
00840
00841
00842
00843
00844 globle void EnvClearFocusStack(
00845 void *theEnv)
00846 {
00847 while (EngineData(theEnv)->CurrentFocus != NULL) EnvPopFocus(theEnv);
00848
00849 EngineData(theEnv)->FocusChanged = TRUE;
00850 }
00851
00852 #if ALLOW_ENVIRONMENT_GLOBALS
00853
00854
00855
00856
00857 globle intBool AddRunFunction(
00858 char *name,
00859 void (*functionPtr)(void),
00860 int priority)
00861 {
00862 void *theEnv;
00863
00864 theEnv = GetCurrentEnvironment();
00865
00866 EngineData(theEnv)->ListOfRunFunctions =
00867 AddFunctionToCallList(theEnv,name,priority,(void (*)(void *)) functionPtr,
00868 EngineData(theEnv)->ListOfRunFunctions,TRUE);
00869 return(1);
00870 }
00871 #endif
00872
00873
00874
00875
00876
00877 globle intBool EnvAddRunFunction(
00878 void *theEnv,
00879 char *name,
00880 void (*functionPtr)(void *),
00881 int priority)
00882 {
00883 EngineData(theEnv)->ListOfRunFunctions = AddFunctionToCallList(theEnv,name,priority,
00884 functionPtr,
00885 EngineData(theEnv)->ListOfRunFunctions,TRUE);
00886 return(1);
00887 }
00888
00889
00890
00891
00892
00893 globle intBool EnvAddRunFunctionWithContext(
00894 void *theEnv,
00895 char *name,
00896 void (*functionPtr)(void *),
00897 int priority,
00898 void *context)
00899 {
00900 EngineData(theEnv)->ListOfRunFunctions =
00901 AddFunctionToCallListWithContext(theEnv,name,priority,functionPtr,
00902 EngineData(theEnv)->ListOfRunFunctions,
00903 TRUE,context);
00904 return(1);
00905 }
00906
00907
00908
00909
00910
00911 globle intBool EnvRemoveRunFunction(
00912 void *theEnv,
00913 char *name)
00914 {
00915 int found;
00916
00917 EngineData(theEnv)->ListOfRunFunctions =
00918 RemoveFunctionFromCallList(theEnv,name,EngineData(theEnv)->ListOfRunFunctions,&found);
00919
00920 if (found) return(TRUE);
00921
00922 return(FALSE);
00923 }
00924
00925
00926
00927
00928 globle void RunCommand(
00929 void *theEnv)
00930 {
00931 int numArgs;
00932 long long runLimit = -1LL;
00933 DATA_OBJECT argPtr;
00934
00935 if ((numArgs = EnvArgCountCheck(theEnv,"run",NO_MORE_THAN,1)) == -1) return;
00936
00937 if (numArgs == 0)
00938 { runLimit = -1LL; }
00939 else if (numArgs == 1)
00940 {
00941 if (EnvArgTypeCheck(theEnv,"run",1,INTEGER,&argPtr) == FALSE) return;
00942 runLimit = DOToLong(argPtr);
00943 }
00944
00945 EnvRun(theEnv,runLimit);
00946
00947 return;
00948 }
00949
00950
00951
00952
00953 globle void HaltCommand(
00954 void *theEnv)
00955 {
00956 EnvArgCountCheck(theEnv,"halt",EXACTLY,0);
00957 EnvHalt(theEnv);
00958 }
00959
00960
00961
00962
00963
00964 globle void EnvHalt(
00965 void *theEnv)
00966 {
00967 EngineData(theEnv)->HaltRules = TRUE;
00968 }
00969
00970 #if DEBUGGING_FUNCTIONS
00971
00972
00973
00974
00975
00976 #if WIN_BTC
00977 #pragma argsused
00978 #endif
00979 globle void EnvSetBreak(
00980 void *theEnv,
00981 void *theRule)
00982 {
00983 #if MAC_MCW || WIN_MCW || MAC_XCD
00984 #pragma unused(theEnv)
00985 #endif
00986 struct defrule *thePtr;
00987
00988 for (thePtr = (struct defrule *) theRule;
00989 thePtr != NULL;
00990 thePtr = thePtr->disjunct)
00991 { thePtr->afterBreakpoint = 1; }
00992 }
00993
00994
00995
00996
00997
00998 #if WIN_BTC
00999 #pragma argsused
01000 #endif
01001 globle intBool EnvRemoveBreak(
01002 void *theEnv,
01003 void *theRule)
01004 {
01005 #if MAC_MCW || WIN_MCW || MAC_XCD
01006 #pragma unused(theEnv)
01007 #endif
01008 struct defrule *thePtr;
01009 int rv = FALSE;
01010
01011 for (thePtr = (struct defrule *) theRule;
01012 thePtr != NULL;
01013 thePtr = thePtr->disjunct)
01014 {
01015 if (thePtr->afterBreakpoint == 1)
01016 {
01017 thePtr->afterBreakpoint = 0;
01018 rv = TRUE;
01019 }
01020 }
01021
01022 return(rv);
01023 }
01024
01025
01026
01027
01028 globle void RemoveAllBreakpoints(
01029 void *theEnv)
01030 {
01031 void *theRule;
01032 void *theDefmodule = NULL;
01033
01034 while ((theDefmodule = EnvGetNextDefmodule(theEnv,theDefmodule)) != NULL)
01035 {
01036 theRule = NULL;
01037 while ((theRule = EnvGetNextDefrule(theEnv,theRule)) != NULL)
01038 { EnvRemoveBreak(theEnv,theRule); }
01039 }
01040 }
01041
01042
01043
01044
01045
01046 globle void EnvShowBreaks(
01047 void *theEnv,
01048 char *logicalName,
01049 void *vTheModule)
01050 {
01051 ListItemsDriver(theEnv,logicalName,(struct defmodule *) vTheModule,
01052 NULL,NULL,
01053 EnvGetNextDefrule,(char *(*)(void *)) GetConstructNameString,
01054 NULL,EnvDefruleHasBreakpoint);
01055 }
01056
01057
01058
01059
01060
01061 #if WIN_BTC
01062 #pragma argsused
01063 #endif
01064 globle intBool EnvDefruleHasBreakpoint(
01065 void *theEnv,
01066 void *theRule)
01067 {
01068 #if MAC_MCW || WIN_MCW || MAC_XCD
01069 #pragma unused(theEnv)
01070 #endif
01071
01072 return(((struct defrule *) theRule)->afterBreakpoint);
01073 }
01074
01075
01076
01077
01078
01079 globle void SetBreakCommand(
01080 void *theEnv)
01081 {
01082 DATA_OBJECT argPtr;
01083 char *argument;
01084 void *defrulePtr;
01085
01086 if (EnvArgCountCheck(theEnv,"set-break",EXACTLY,1) == -1) return;
01087
01088 if (EnvArgTypeCheck(theEnv,"set-break",1,SYMBOL,&argPtr) == FALSE) return;
01089
01090 argument = DOToString(argPtr);
01091
01092 if ((defrulePtr = EnvFindDefrule(theEnv,argument)) == NULL)
01093 {
01094 CantFindItemErrorMessage(theEnv,"defrule",argument);
01095 return;
01096 }
01097
01098 EnvSetBreak(theEnv,defrulePtr);
01099 }
01100
01101
01102
01103
01104
01105 globle void RemoveBreakCommand(
01106 void *theEnv)
01107 {
01108 DATA_OBJECT argPtr;
01109 char *argument;
01110 int nargs;
01111 void *defrulePtr;
01112
01113 if ((nargs = EnvArgCountCheck(theEnv,"remove-break",NO_MORE_THAN,1)) == -1)
01114 { return; }
01115
01116 if (nargs == 0)
01117 {
01118 RemoveAllBreakpoints(theEnv);
01119 return;
01120 }
01121
01122 if (EnvArgTypeCheck(theEnv,"remove-break",1,SYMBOL,&argPtr) == FALSE) return;
01123
01124 argument = DOToString(argPtr);
01125
01126 if ((defrulePtr = EnvFindDefrule(theEnv,argument)) == NULL)
01127 {
01128 CantFindItemErrorMessage(theEnv,"defrule",argument);
01129 return;
01130 }
01131
01132 if (EnvRemoveBreak(theEnv,defrulePtr) == FALSE)
01133 {
01134 EnvPrintRouter(theEnv,WERROR,"Rule ");
01135 EnvPrintRouter(theEnv,WERROR,argument);
01136 EnvPrintRouter(theEnv,WERROR," does not have a breakpoint set.\n");
01137 }
01138 }
01139
01140
01141
01142
01143
01144 globle void ShowBreaksCommand(
01145 void *theEnv)
01146 {
01147 int numArgs, error;
01148 struct defmodule *theModule;
01149
01150 if ((numArgs = EnvArgCountCheck(theEnv,"show-breaks",NO_MORE_THAN,1)) == -1) return;
01151
01152 if (numArgs == 1)
01153 {
01154 theModule = GetModuleName(theEnv,"show-breaks",1,&error);
01155 if (error) return;
01156 }
01157 else
01158 { theModule = ((struct defmodule *) EnvGetCurrentModule(theEnv)); }
01159
01160 EnvShowBreaks(theEnv,WDISPLAY,theModule);
01161 }
01162
01163
01164
01165
01166
01167 globle void ListFocusStackCommand(
01168 void *theEnv)
01169 {
01170 if (EnvArgCountCheck(theEnv,"list-focus-stack",EXACTLY,0) == -1) return;
01171
01172 EnvListFocusStack(theEnv,WDISPLAY);
01173 }
01174
01175
01176
01177
01178
01179 globle void EnvListFocusStack(
01180 void *theEnv,
01181 char *logicalName)
01182 {
01183 struct focus *theFocus;
01184
01185 for (theFocus = EngineData(theEnv)->CurrentFocus;
01186 theFocus != NULL;
01187 theFocus = theFocus->next)
01188 {
01189 EnvPrintRouter(theEnv,logicalName,EnvGetDefmoduleName(theEnv,theFocus->theModule));
01190 EnvPrintRouter(theEnv,logicalName,"\n");
01191 }
01192 }
01193
01194 #endif
01195
01196
01197
01198
01199
01200 globle void GetFocusStackFunction(
01201 void *theEnv,
01202 DATA_OBJECT_PTR returnValue)
01203 {
01204 if (EnvArgCountCheck(theEnv,"get-focus-stack",EXACTLY,0) == -1) return;
01205
01206 EnvGetFocusStack(theEnv,returnValue);
01207 }
01208
01209
01210
01211
01212
01213 globle void EnvGetFocusStack(
01214 void *theEnv,
01215 DATA_OBJECT_PTR returnValue)
01216 {
01217 struct focus *theFocus;
01218 struct multifield *theList;
01219 unsigned long count = 0;
01220
01221
01222
01223
01224
01225
01226 if (EngineData(theEnv)->CurrentFocus == NULL)
01227 {
01228 SetpType(returnValue,MULTIFIELD);
01229 SetpDOBegin(returnValue,1);
01230 SetpDOEnd(returnValue,0);
01231 SetpValue(returnValue,(void *) EnvCreateMultifield(theEnv,0L));
01232 return;
01233 }
01234
01235
01236
01237
01238
01239 for (theFocus = EngineData(theEnv)->CurrentFocus; theFocus != NULL; theFocus = theFocus->next)
01240 { count++; }
01241
01242
01243
01244
01245
01246
01247 SetpType(returnValue,MULTIFIELD);
01248 SetpDOBegin(returnValue,1);
01249 SetpDOEnd(returnValue,(long) count);
01250 theList = (struct multifield *) EnvCreateMultifield(theEnv,count);
01251 SetpValue(returnValue,(void *) theList);
01252
01253
01254
01255
01256
01257 for (theFocus = EngineData(theEnv)->CurrentFocus, count = 1;
01258 theFocus != NULL;
01259 theFocus = theFocus->next, count++)
01260 {
01261 SetMFType(theList,count,SYMBOL);
01262 SetMFValue(theList,count,theFocus->theModule->name);
01263 }
01264 }
01265
01266
01267
01268
01269
01270 globle void *PopFocusFunction(
01271 void *theEnv)
01272 {
01273 struct defmodule *theModule;
01274
01275 EnvArgCountCheck(theEnv,"pop-focus",EXACTLY,0);
01276
01277 theModule = (struct defmodule *) EnvPopFocus(theEnv);
01278 if (theModule == NULL) return((SYMBOL_HN *) EnvFalseSymbol(theEnv));
01279 return(theModule->name);
01280 }
01281
01282
01283
01284
01285
01286 globle void *GetFocusFunction(
01287 void *theEnv)
01288 {
01289 struct defmodule *rv;
01290
01291 EnvArgCountCheck(theEnv,"get-focus",EXACTLY,0);
01292 rv = (struct defmodule *) EnvGetFocus(theEnv);
01293 if (rv == NULL) return((SYMBOL_HN *) EnvFalseSymbol(theEnv));
01294 return(rv->name);
01295 }
01296
01297
01298
01299
01300
01301 globle void *EnvGetFocus(
01302 void *theEnv)
01303 {
01304 if (EngineData(theEnv)->CurrentFocus == NULL) return(NULL);
01305
01306 return((void *) EngineData(theEnv)->CurrentFocus->theModule);
01307 }
01308
01309
01310
01311
01312
01313 globle int FocusCommand(
01314 void *theEnv)
01315 {
01316 DATA_OBJECT argPtr;
01317 char *argument;
01318 struct defmodule *theModule;
01319 int argCount, i;
01320
01321
01322
01323
01324
01325 if ((argCount = EnvArgCountCheck(theEnv,"focus",AT_LEAST,1)) == -1)
01326 { return(FALSE); }
01327
01328
01329
01330
01331
01332 for (i = argCount; i > 0; i--)
01333 {
01334 if (EnvArgTypeCheck(theEnv,"focus",i,SYMBOL,&argPtr) == FALSE)
01335 { return(FALSE); }
01336
01337 argument = DOToString(argPtr);
01338 theModule = (struct defmodule *) EnvFindDefmodule(theEnv,argument);
01339
01340 if (theModule == NULL)
01341 {
01342 CantFindItemErrorMessage(theEnv,"defmodule",argument);
01343 return(FALSE);
01344 }
01345
01346 EnvFocus(theEnv,(void *) theModule);
01347 }
01348
01349
01350
01351
01352
01353 return(TRUE);
01354 }
01355
01356
01357
01358
01359 globle int EnvGetFocusChanged(
01360 void *theEnv)
01361 {
01362 return(EngineData(theEnv)->FocusChanged);
01363 }
01364
01365
01366
01367
01368 globle void EnvSetFocusChanged(
01369 void *theEnv,
01370 int value)
01371 {
01372 EngineData(theEnv)->FocusChanged = value;
01373 }
01374
01375
01376
01377
01378 globle void EnvSetHaltRules(
01379 void *theEnv,
01380 intBool value)
01381 {
01382 EngineData(theEnv)->HaltRules = value;
01383 }
01384
01385
01386
01387
01388 globle intBool EnvGetHaltRules(
01389 void *theEnv)
01390 {
01391 return(EngineData(theEnv)->HaltRules);
01392 }
01393
01394 #endif
01395