void Dependencies( Environment *theEnv, struct patternEntity *theEntity) { struct dependency *fdPtr; /*=========================================*/ /* If the data entity has no dependencies, */ /* then print "None" and return. */ /*=========================================*/ if (theEntity->dependents == NULL) { WriteString(theEnv,STDOUT,"None\n"); return; } /*============================================*/ /* Loop through the list of the data entities */ /* dependencies and print them. */ /*============================================*/ for (fdPtr = (struct dependency *) theEntity->dependents; fdPtr != NULL; fdPtr = fdPtr->next) { if (GetHaltExecution(theEnv) == true) return; PrintPartialMatch(theEnv,STDOUT,(struct partialMatch *) fdPtr->dPtr); WriteString(theEnv,STDOUT,"\n"); } }
globle void Dependencies( void *theEnv, struct patternEntity *theEntity) { struct dependency *fdPtr; /*=========================================*/ /* If the data entity has no dependencies, */ /* then print "None" and return. */ /*=========================================*/ if (theEntity->dependents == NULL) { EnvPrintRouter(theEnv,WDISPLAY,"None\n"); return; } /*============================================*/ /* Loop through the list of the data entities */ /* dependencies and print them. */ /*============================================*/ for (fdPtr = (struct dependency *) theEntity->dependents; fdPtr != NULL; fdPtr = fdPtr->next) { if (GetHaltExecution(theEnv) == TRUE) return; PrintPartialMatch(theEnv,WDISPLAY,(struct partialMatch *) fdPtr->dPtr); EnvPrintRouter(theEnv,WDISPLAY,"\n"); } }
globle void EnvGetActivationBasisPPForm( void *theEnv, char *buffer, unsigned bufferLength, void *vTheActivation) { struct activation *theActivation = (struct activation *) vTheActivation; OpenStringDestination(theEnv,(char*)"ActPPForm",buffer,bufferLength); PrintPartialMatch(theEnv,(char*)"ActPPForm",theActivation->basis); CloseStringDestination(theEnv,(char*)"ActPPForm"); }
static void PrintActivation( void *theEnv, char *logicalName, void *vTheActivation) { struct activation *theActivation = (struct activation *) vTheActivation; char printSpace[20]; gensprintf(printSpace,"%-6d ",theActivation->salience); EnvPrintRouter(theEnv,logicalName,printSpace); EnvPrintRouter(theEnv,logicalName,ValueToString(theActivation->theRule->header.name)); EnvPrintRouter(theEnv,logicalName,(char*)": "); PrintPartialMatch(theEnv,logicalName,theActivation->basis); }
static void PrintMatchesMemory( void *theEnv, struct joinNode *theJoin, struct betaMemory *theMemory, int startCE, int endCE) { #if MAC_MCW || WIN_MCW || MAC_XCD #pragma unused(theJoin) #endif struct partialMatch *listOfMatches; unsigned long b; int matchesDisplayed; if (GetHaltExecution(theEnv) == TRUE) { return; } matchesDisplayed = 0; EnvPrintRouter(theEnv,WDISPLAY,"Partial matches for CEs "); PrintLongInteger(theEnv,WDISPLAY,(long int) startCE); EnvPrintRouter(theEnv,WDISPLAY," - "); PrintLongInteger(theEnv,WDISPLAY,(long int) endCE); EnvPrintRouter(theEnv,WDISPLAY,"\n"); for (b = 0; b < theMemory->size; b++) { listOfMatches = theMemory->beta[b]; while (listOfMatches != NULL) { if (GetHaltExecution(theEnv) == TRUE) { return; } matchesDisplayed++; PrintPartialMatch(theEnv,WDISPLAY,listOfMatches); EnvPrintRouter(theEnv,WDISPLAY,"\n"); listOfMatches = listOfMatches->nextInMemory; } } if (matchesDisplayed == 0) { EnvPrintRouter(theEnv,WDISPLAY," None\n"); } }
static int ListAlphaMatches( void *theEnv, struct joinNode *theJoin, int priorPatterns) { struct alphaMemoryHash *listOfHashNodes; struct partialMatch *listOfMatches; int flag; if (theJoin == NULL) { return(priorPatterns); } if (theJoin->rightSideEntryStructure == NULL) { priorPatterns++; EnvPrintRouter(theEnv,WDISPLAY,"Matches for Pattern "); PrintLongInteger(theEnv,WDISPLAY,(long int) priorPatterns); EnvPrintRouter(theEnv,WDISPLAY,"\n"); if (theJoin->rightMemory->beta[0]->children != NULL) { EnvPrintRouter(theEnv,WDISPLAY,"*\n"); } else { EnvPrintRouter(theEnv,WDISPLAY," None\n"); } return(priorPatterns); } if (theJoin->lastLevel != NULL) { priorPatterns = ListAlphaMatches(theEnv,theJoin->lastLevel,priorPatterns); } if (theJoin->joinFromTheRight) { return ListAlphaMatches(theEnv,(struct joinNode *) theJoin->rightSideEntryStructure,priorPatterns); } listOfHashNodes = ((struct patternNodeHeader *) theJoin->rightSideEntryStructure)->firstHash; priorPatterns++; if (GetHaltExecution(theEnv) == TRUE) { return(priorPatterns); } EnvPrintRouter(theEnv,WDISPLAY,"Matches for Pattern "); PrintLongInteger(theEnv,WDISPLAY,(long int) priorPatterns); EnvPrintRouter(theEnv,WDISPLAY,"\n"); for (flag = 1; listOfHashNodes != NULL; listOfHashNodes = listOfHashNodes->nextHash) { listOfMatches = listOfHashNodes->alphaMemory; while (listOfMatches != NULL) { if (GetHaltExecution(theEnv) == TRUE) { return(priorPatterns); } flag = 0; PrintPartialMatch(theEnv,WDISPLAY,listOfMatches); EnvPrintRouter(theEnv,WDISPLAY,"\n"); listOfMatches = listOfMatches->nextInMemory; } } if (flag) EnvPrintRouter(theEnv,WDISPLAY," None\n"); return(priorPatterns); }
globle intBool EnvMatches( void *theEnv, void *theRule) { struct defrule *rulePtr, *tmpPtr; struct joinNode *lastJoin; ACTIVATION *agendaPtr; int flag; /*=================================================*/ /* Loop through each of the disjuncts for the rule */ /*=================================================*/ for (rulePtr = (struct defrule *) theRule, tmpPtr = rulePtr; rulePtr != NULL; rulePtr = rulePtr->disjunct) { /*======================================*/ /* Determine the last join in the rule. */ /*======================================*/ lastJoin = rulePtr->lastJoin; /*========================================*/ /* List the alpha memory partial matches. */ /*========================================*/ ListAlphaMatches(theEnv,lastJoin->lastLevel,0); /*=======================================*/ /* List the beta memory partial matches. */ /*=======================================*/ ListBetaMatches(theEnv,lastJoin,1); } /*===================*/ /* List activations. */ /*===================*/ rulePtr = tmpPtr; EnvPrintRouter(theEnv,WDISPLAY,"Activations\n"); flag = 1; for (agendaPtr = (struct activation *) EnvGetNextActivation(theEnv,NULL); agendaPtr != NULL; agendaPtr = (struct activation *) EnvGetNextActivation(theEnv,agendaPtr)) { if (GetHaltExecution(theEnv) == TRUE) return(TRUE); if (((struct activation *) agendaPtr)->theRule->header.name == rulePtr->header.name) { flag = 0; PrintPartialMatch(theEnv,WDISPLAY,GetActivationBasis(agendaPtr)); EnvPrintRouter(theEnv,WDISPLAY,"\n"); } } if (flag) EnvPrintRouter(theEnv,WDISPLAY," None\n"); return(TRUE); }
globle BOOLEAN EnvMatches_PY( void *theEnv, char *logicalName, void *theRule) { struct defrule *rulePtr, *tmpPtr; struct partialMatch *listOfMatches, **theStorage; struct joinNode *theJoin, *lastJoin; int i, depth; ACTIVATION *agendaPtr; int flag; int matchesDisplayed; /*=================================================*/ /* Loop through each of the disjuncts for the rule */ /*=================================================*/ for (rulePtr = (struct defrule *) theRule, tmpPtr = rulePtr; rulePtr != NULL; rulePtr = rulePtr->disjunct) { /*======================================*/ /* Determine the last join in the rule. */ /*======================================*/ lastJoin = rulePtr->lastJoin; /*===================================*/ /* Determine the number of patterns. */ /*===================================*/ depth = GetPatternNumberFromJoin(lastJoin); /*=========================================*/ /* Store the alpha memory partial matches. */ /*=========================================*/ theStorage = (struct partialMatch **) genalloc(theEnv,(unsigned) (depth * sizeof(struct partialMatch))); theJoin = lastJoin; i = depth - 1; while (theJoin != NULL) { if (theJoin->joinFromTheRight) { theJoin = (struct joinNode *) theJoin->rightSideEntryStructure; } else { theStorage[i] = ((struct patternNodeHeader *) theJoin->rightSideEntryStructure)->alphaMemory; i--; theJoin = theJoin->lastLevel; } } /*========================================*/ /* List the alpha memory partial matches. */ /*========================================*/ for (i = 0; i < depth; i++) { if (GetHaltExecution(theEnv) == TRUE) { genfree(theEnv,theStorage,(unsigned) (depth * sizeof(struct partialMatch))); return(TRUE); } EnvPrintRouter(theEnv,logicalName,"Matches for Pattern "); PrintLongInteger(theEnv,logicalName,(long int) i + 1); EnvPrintRouter(theEnv,logicalName,"\n"); listOfMatches = theStorage[i]; if (listOfMatches == NULL) EnvPrintRouter(theEnv,logicalName," None\n"); while (listOfMatches != NULL) { if (GetHaltExecution(theEnv) == TRUE) { genfree(theEnv,theStorage,(unsigned) (depth * sizeof(struct partialMatch))); return(TRUE); } PrintPartialMatch(theEnv,logicalName,listOfMatches); EnvPrintRouter(theEnv,logicalName,"\n"); listOfMatches = listOfMatches->next; } } genfree(theEnv,theStorage,(unsigned) (depth * sizeof(struct partialMatch))); /*========================================*/ /* Store the beta memory partial matches. */ /*========================================*/ depth = lastJoin->depth; theStorage = (struct partialMatch **) genalloc(theEnv,(unsigned) (depth * sizeof(struct partialMatch))); theJoin = lastJoin; for (i = depth - 1; i >= 0; i--) { theStorage[i] = theJoin->beta; theJoin = theJoin->lastLevel; } /*=======================================*/ /* List the beta memory partial matches. */ /*=======================================*/ for (i = 1; i < depth; i++) { if (GetHaltExecution(theEnv) == TRUE) { genfree(theEnv,theStorage,(unsigned) (depth * sizeof(struct partialMatch))); return(TRUE); } matchesDisplayed = 0; EnvPrintRouter(theEnv,logicalName,"Partial matches for CEs 1 - "); PrintLongInteger(theEnv,logicalName,(long int) i + 1); EnvPrintRouter(theEnv,logicalName,"\n"); listOfMatches = theStorage[i]; while (listOfMatches != NULL) { if (GetHaltExecution(theEnv) == TRUE) { genfree(theEnv,theStorage,(unsigned) (depth * sizeof(struct partialMatch))); return(TRUE); } if (listOfMatches->counterf == FALSE) { matchesDisplayed++; PrintPartialMatch(theEnv,logicalName,listOfMatches); EnvPrintRouter(theEnv,logicalName,"\n"); } listOfMatches = listOfMatches->next; } if (matchesDisplayed == 0) { EnvPrintRouter(theEnv,logicalName," None\n"); } } genfree(theEnv,theStorage,(unsigned) (depth * sizeof(struct partialMatch))); } /*===================*/ /* List activations. */ /*===================*/ rulePtr = tmpPtr; EnvPrintRouter(theEnv,logicalName,"Activations\n"); flag = 1; for (agendaPtr = (struct activation *) EnvGetNextActivation(theEnv,NULL); agendaPtr != NULL; agendaPtr = (struct activation *) EnvGetNextActivation(theEnv,agendaPtr)) { if (GetHaltExecution(theEnv) == TRUE) return(TRUE); if (((struct activation *) agendaPtr)->theRule->header.name == rulePtr->header.name) { flag = 0; PrintPartialMatch(theEnv,logicalName,GetActivationBasis(agendaPtr)); EnvPrintRouter(theEnv,logicalName,"\n"); } } if (flag) EnvPrintRouter(theEnv,logicalName," None\n"); return(TRUE); }
globle long int EnvRun( void *theEnv, long int runLimit) { long int rulesFired = 0; DATA_OBJECT result; struct callFunctionItem *theRunFunction; #if DEBUGGING_FUNCTIONS unsigned long maxActivations = 0, sumActivations = 0; #if DEFTEMPLATE_CONSTRUCT unsigned long maxFacts = 0, sumFacts = 0; #endif #if OBJECT_SYSTEM unsigned long maxInstances = 0, sumInstances = 0; #endif double endTime, startTime = 0.0; unsigned long tempValue; #endif unsigned int i; struct patternEntity *theMatchingItem; struct partialMatch *theBasis; ACTIVATION *theActivation; char *ruleFiring; #if PROFILING_FUNCTIONS struct profileFrameInfo profileFrame; #endif /*=====================================================*/ /* Make sure the run command is not already executing. */ /*=====================================================*/ if (EngineData(theEnv)->AlreadyRunning) return(0); EngineData(theEnv)->AlreadyRunning = TRUE; /*================================*/ /* Set up statistics information. */ /*================================*/ #if DEBUGGING_FUNCTIONS if (EngineData(theEnv)->WatchStatistics) { #if DEFTEMPLATE_CONSTRUCT maxFacts = GetNumberOfFacts(theEnv); sumFacts = maxFacts; #endif #if OBJECT_SYSTEM maxInstances = GetGlobalNumberOfInstances(theEnv); sumInstances = maxInstances; #endif maxActivations = GetNumberOfActivations(theEnv); sumActivations = maxActivations; startTime = gentime(); } #endif /*=============================*/ /* Set up execution variables. */ /*=============================*/ if (EvaluationData(theEnv)->CurrentEvaluationDepth == 0) SetHaltExecution(theEnv,FALSE); EngineData(theEnv)->HaltRules = FALSE; /*=====================================================*/ /* Fire rules until the agenda is empty, the run limit */ /* has been reached, or a rule execution error occurs. */ /*=====================================================*/ theActivation = NextActivationToFire(theEnv); while ((theActivation != NULL) && (runLimit != 0) && (EvaluationData(theEnv)->HaltExecution == FALSE) && (EngineData(theEnv)->HaltRules == FALSE)) { /*===========================================*/ /* Detach the activation from the agenda and */ /* determine which rule is firing. */ /*===========================================*/ DetachActivation(theEnv,theActivation); ruleFiring = EnvGetActivationName(theEnv,theActivation); theBasis = (struct partialMatch *) GetActivationBasis(theActivation); EngineData(theEnv)->ExecutingRule = (struct defrule *) GetActivationRule(theActivation); /*=============================================*/ /* Update the number of rules that have fired. */ /*=============================================*/ rulesFired++; if (runLimit > 0) { runLimit--; } /*==================================*/ /* If rules are being watched, then */ /* print an information message. */ /*==================================*/ #if DEBUGGING_FUNCTIONS if (EngineData(theEnv)->ExecutingRule->watchFiring) { char printSpace[60]; sprintf(printSpace,"FIRE %4ld ",rulesFired); EnvPrintRouter(theEnv,WTRACE,printSpace); EnvPrintRouter(theEnv,WTRACE,ruleFiring); EnvPrintRouter(theEnv,WTRACE,": "); PrintPartialMatch(theEnv,WTRACE,theBasis); EnvPrintRouter(theEnv,WTRACE,"\n"); } #endif /*=================================================*/ /* Remove the link between the activation and the */ /* completed match for the rule. Set the busy flag */ /* for the completed match to TRUE (so the match */ /* upon which our RHS variables are dependent is */ /* not deleted while our rule is firing). Set up */ /* the global pointers to the completed match for */ /* routines which do variable extractions. */ /*=================================================*/ theBasis->binds[theBasis->bcount].gm.theValue = NULL; theBasis->busy = TRUE; EngineData(theEnv)->GlobalLHSBinds = theBasis; EngineData(theEnv)->GlobalRHSBinds = NULL; /*===================================================================*/ /* Increment the count for each of the facts/objects associated with */ /* the rule activation so that the facts/objects cannot be deleted */ /* by garbage collection while the rule is executing. */ /*===================================================================*/ for (i = 0; i < theBasis->bcount; i++) { theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem; if (theMatchingItem != NULL) { (*theMatchingItem->theInfo->incrementBasisCount)(theEnv,theMatchingItem); } } /*====================================================*/ /* Execute the rule's right hand side actions. If the */ /* rule has logical CEs, set up the pointer to the */ /* rules logical join so the assert command will */ /* attach the appropriate dependencies to the facts. */ /*====================================================*/ EngineData(theEnv)->TheLogicalJoin = EngineData(theEnv)->ExecutingRule->logicalJoin; EvaluationData(theEnv)->CurrentEvaluationDepth++; SetEvaluationError(theEnv,FALSE); EngineData(theEnv)->ExecutingRule->executing = TRUE; #if PROFILING_FUNCTIONS StartProfile(theEnv,&profileFrame, &EngineData(theEnv)->ExecutingRule->header.usrData, ProfileFunctionData(theEnv)->ProfileConstructs); #endif EvaluateProcActions(theEnv,EngineData(theEnv)->ExecutingRule->header.whichModule->theModule, EngineData(theEnv)->ExecutingRule->actions,EngineData(theEnv)->ExecutingRule->localVarCnt, &result,NULL); #if PROFILING_FUNCTIONS EndProfile(theEnv,&profileFrame); #endif EngineData(theEnv)->ExecutingRule->executing = FALSE; SetEvaluationError(theEnv,FALSE); EvaluationData(theEnv)->CurrentEvaluationDepth--; EngineData(theEnv)->TheLogicalJoin = NULL; /*=====================================================*/ /* If rule execution was halted, then print a message. */ /*=====================================================*/ #if DEBUGGING_FUNCTIONS if ((EvaluationData(theEnv)->HaltExecution) || (EngineData(theEnv)->HaltRules && EngineData(theEnv)->ExecutingRule->watchFiring)) #else if ((EvaluationData(theEnv)->HaltExecution) || (EngineData(theEnv)->HaltRules)) #endif { PrintErrorID(theEnv,"PRCCODE",4,FALSE); EnvPrintRouter(theEnv,WERROR,"Execution halted during the actions of defrule "); EnvPrintRouter(theEnv,WERROR,ruleFiring); EnvPrintRouter(theEnv,WERROR,".\n"); } /*===================================================================*/ /* Decrement the count for each of the facts/objects associated with */ /* the rule activation. If the last match for the activation */ /* is from a not CE, then we need to make sure that the last */ /* match is an actual match for the CE and not a counter. */ /*===================================================================*/ theBasis->busy = FALSE; for (i = 0; i < (theBasis->bcount - 1); i++) { theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem; if (theMatchingItem != NULL) { (*theMatchingItem->theInfo->decrementBasisCount)(theEnv,theMatchingItem); } } i = (unsigned) (theBasis->bcount - 1); if (theBasis->counterf == FALSE) { theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem; if (theMatchingItem != NULL) { (*theMatchingItem->theInfo->decrementBasisCount)(theEnv,theMatchingItem); } } /*========================================*/ /* Return the agenda node to free memory. */ /*========================================*/ RemoveActivation(theEnv,theActivation,FALSE,FALSE); /*======================================*/ /* Get rid of partial matches discarded */ /* while executing the rule's RHS. */ /*======================================*/ FlushGarbagePartialMatches(theEnv); /*==================================*/ /* Get rid of other garbage created */ /* while executing the rule's RHS. */ /*==================================*/ PeriodicCleanup(theEnv,FALSE,TRUE); /*==========================*/ /* Keep up with statistics. */ /*==========================*/ #if DEBUGGING_FUNCTIONS if (EngineData(theEnv)->WatchStatistics) { #if DEFTEMPLATE_CONSTRUCT tempValue = GetNumberOfFacts(theEnv); if (tempValue > maxFacts) maxFacts = tempValue; sumFacts += tempValue; #endif #if OBJECT_SYSTEM tempValue = GetGlobalNumberOfInstances(theEnv); if (tempValue > maxInstances) maxInstances = tempValue; sumInstances += tempValue; #endif tempValue = GetNumberOfActivations(theEnv); if (tempValue > maxActivations) maxActivations = tempValue; sumActivations += tempValue; } #endif /*==================================*/ /* Update saliences if appropriate. */ /*==================================*/ if (EnvGetSalienceEvaluation(theEnv) == EVERY_CYCLE) EnvRefreshAgenda(theEnv,NULL); /*========================================*/ /* Execute the list of functions that are */ /* to be called after each rule firing. */ /*========================================*/ for (theRunFunction = EngineData(theEnv)->ListOfRunFunctions; theRunFunction != NULL; theRunFunction = theRunFunction->next) { if (theRunFunction->environmentAware) { (*theRunFunction->func)(theEnv); } else { ((void (*)(void))(*theRunFunction->func))(); } } /*========================================*/ /* If a return was issued on the RHS of a */ /* rule, then remove *that* rule's module */ /* from the focus stack */ /*========================================*/ if (ProcedureFunctionData(theEnv)->ReturnFlag == TRUE) { RemoveFocus(theEnv,EngineData(theEnv)->ExecutingRule->header.whichModule->theModule); } ProcedureFunctionData(theEnv)->ReturnFlag = FALSE; /*========================================*/ /* Determine the next activation to fire. */ /*========================================*/ theActivation = (struct activation *) NextActivationToFire(theEnv); /*==============================*/ /* Check for a rule breakpoint. */ /*==============================*/ if (theActivation != NULL) { if (((struct defrule *) GetActivationRule(theActivation))->afterBreakpoint) { EngineData(theEnv)->HaltRules = TRUE; EnvPrintRouter(theEnv,WDIALOG,"Breaking on rule "); EnvPrintRouter(theEnv,WDIALOG,EnvGetActivationName(theEnv,theActivation)); EnvPrintRouter(theEnv,WDIALOG,".\n"); } } } /*=====================================================*/ /* Make sure run functions are executed at least once. */ /*=====================================================*/ if (rulesFired == 0) { for (theRunFunction = EngineData(theEnv)->ListOfRunFunctions; theRunFunction != NULL; theRunFunction = theRunFunction->next) { if (theRunFunction->environmentAware) { (*theRunFunction->func)(theEnv); } else { ((void (*)(void))(*theRunFunction->func))(); } } } /*======================================================*/ /* If rule execution was halted because the rule firing */ /* limit was reached, then print a message. */ /*======================================================*/ if (runLimit == rulesFired) { EnvPrintRouter(theEnv,WDIALOG,"rule firing limit reached\n"); } /*==============================*/ /* Restore execution variables. */ /*==============================*/ EngineData(theEnv)->ExecutingRule = NULL; EngineData(theEnv)->HaltRules = FALSE; /*=================================================*/ /* Print out statistics if they are being watched. */ /*=================================================*/ #if DEBUGGING_FUNCTIONS if (EngineData(theEnv)->WatchStatistics) { char printSpace[60]; endTime = gentime(); PrintLongInteger(theEnv,WDIALOG,rulesFired); EnvPrintRouter(theEnv,WDIALOG," rules fired"); #if (! GENERIC) if (startTime != endTime) { EnvPrintRouter(theEnv,WDIALOG," Run time is "); PrintFloat(theEnv,WDIALOG,endTime - startTime); EnvPrintRouter(theEnv,WDIALOG," seconds.\n"); PrintFloat(theEnv,WDIALOG,(double) rulesFired / (endTime - startTime)); EnvPrintRouter(theEnv,WDIALOG," rules per second.\n"); } else { EnvPrintRouter(theEnv,WDIALOG,"\n"); } #endif #if DEFTEMPLATE_CONSTRUCT sprintf(printSpace,"%ld mean number of facts (%ld maximum).\n", (long) (((double) sumFacts / (rulesFired + 1)) + 0.5), maxFacts); EnvPrintRouter(theEnv,WDIALOG,printSpace); #endif #if OBJECT_SYSTEM sprintf(printSpace,"%ld mean number of instances (%ld maximum).\n", (long) (((double) sumInstances / (rulesFired + 1)) + 0.5), maxInstances); EnvPrintRouter(theEnv,WDIALOG,printSpace); #endif sprintf(printSpace,"%ld mean number of activations (%ld maximum).\n", (long) (((double) sumActivations / (rulesFired + 1)) + 0.5), maxActivations); EnvPrintRouter(theEnv,WDIALOG,printSpace); } #endif /*==========================================*/ /* The current module should be the current */ /* focus when the run finishes. */ /*==========================================*/ if (EngineData(theEnv)->CurrentFocus != NULL) { if (EngineData(theEnv)->CurrentFocus->theModule != ((struct defmodule *) EnvGetCurrentModule(theEnv))) { EnvSetCurrentModule(theEnv,(void *) EngineData(theEnv)->CurrentFocus->theModule); } } /*===================================*/ /* Return the number of rules fired. */ /*===================================*/ EngineData(theEnv)->AlreadyRunning = FALSE; return(rulesFired); }