⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 engine.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.30  10/19/06            */   /*                                                     */   /*                    ENGINE MODULE                    */   /*******************************************************//*************************************************************//* Purpose: Provides functionality primarily associated with *//*   the run and focus commands.                             *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*      Bebe Ly                                              *//*      Brian L. Donnell                                     *//*                                                           *//* Revision History:                                         *//*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  *//*                                                           *//*            Corrected compilation errors for files         *//*            generated by constructs-to-c. DR0861           *//*                                                           *//*      6.24: Removed DYNAMIC_SALIENCE, INCREMENTAL_RESET,   *//*            and LOGICAL_DEPENDENCIES compilation flags.    *//*                                                           *//*            Renamed BOOLEAN macro type to intBool.         *//*                                                           *//*            Added access functions to the HaltRules flag.  *//*                                                           *//*            Added EnvGetNextFocus, EnvGetFocusChanged, and *//*            EnvSetFocusChanged functions.                  *//*                                                           *//*      6.30: Added additional developer statistics to help  *//*            analyze join network performance.              *//*                                                           *//*            Removed pseudo-facts used in not CEs.          *//*                                                           *//*************************************************************/#define _ENGINE_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include <string.h>#include "setup.h"#if DEFRULE_CONSTRUCT#include "agenda.h"#include "argacces.h"#include "constant.h"#include "envrnmnt.h"#include "factmngr.h"#include "inscom.h"#include "memalloc.h"#include "modulutl.h"#include "prccode.h"#include "prcdrfun.h"#include "proflfun.h"#include "reteutil.h"#include "retract.h"#include "router.h"#include "ruledlt.h"#include "sysdep.h"#include "utility.h"#include "watch.h"#include "engine.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static struct activation      *NextActivationToFire(void *);   static struct defmodule       *RemoveFocus(void *,struct defmodule *);   static void                    DeallocateEngineData(void *);/*****************************************************************************//* InitializeEngine: Initializes the activations and statistics watch items. *//*****************************************************************************/globle void InitializeEngine(  void *theEnv)  {      AllocateEnvironmentData(theEnv,ENGINE_DATA,sizeof(struct engineData),DeallocateEngineData);   EngineData(theEnv)->IncrementalResetFlag = TRUE;   #if DEBUGGING_FUNCTIONS   AddWatchItem(theEnv,"statistics",0,&EngineData(theEnv)->WatchStatistics,20,NULL,NULL);   AddWatchItem(theEnv,"focus",0,&EngineData(theEnv)->WatchFocus,0,NULL,NULL);#endif  }  /*************************************************//* DeallocateEngineData: Deallocates environment *//*    data for engine functionality.             *//*************************************************/static void DeallocateEngineData(  void *theEnv)  {   struct focus *tmpPtr, *nextPtr;      DeallocateCallList(theEnv,EngineData(theEnv)->ListOfRunFunctions);   tmpPtr = EngineData(theEnv)->CurrentFocus;   while (tmpPtr != NULL)     {      nextPtr = tmpPtr->next;      rtn_struct(theEnv,focus,tmpPtr);      tmpPtr = nextPtr;     }  }/*************************************************//* EnvRun: C access routine for the run command. *//*************************************************/globle long long EnvRun(  void *theEnv,  long long runLimit)  {   long long 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 short i;   struct patternEntity *theMatchingItem;   struct partialMatch *theBasis;   ACTIVATION *theActivation;   char *ruleFiring;#if PROFILING_FUNCTIONS   struct profileFrameInfo profileFrame;#endif   struct trackedMemory *theTM;   /*=====================================================*/   /* 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;#if DEVELOPER   EngineData(theEnv)->leftToRightComparisons = 0;   EngineData(theEnv)->rightToLeftComparisons = 0;   EngineData(theEnv)->leftToRightSucceeds = 0;   EngineData(theEnv)->rightToLeftSucceeds = 0;   EngineData(theEnv)->leftToRightLoops = 0;   EngineData(theEnv)->rightToLeftLoops = 0;   EngineData(theEnv)->findNextConflictingComparisons = 0;   EngineData(theEnv)->betaHashListSkips = 0;   EngineData(theEnv)->betaHashHTSkips = 0;   EngineData(theEnv)->unneededMarkerCompare = 0;#endif   /*=====================================================*/   /* 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);      theTM = AddTrackedMemory(theEnv,theActivation,sizeof(struct activation));      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];         gensprintf(printSpace,"FIRE %4lld ",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->marker = 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++)        {         if (theBasis->binds[i].gm.theMatch == NULL) continue;         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.              */      /*===================================================*/      theBasis->busy = FALSE;      for (i = 0; i < (theBasis->bcount); i++)        {         if (theBasis->binds[i].gm.theMatch == NULL) continue;         theMatchingItem = theBasis->binds[i].gm.theMatch->matchingItem;         if (theMatchingItem != NULL)           { (*theMatchingItem->theInfo->decrementBasisCount)(theEnv,theMatchingItem); }        }      /*========================================*/      /* Return the agenda node to free memory. */      /*========================================*/      RemoveTrackedMemory(theEnv,theTM);      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))(); }        }     }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -