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

📄 engine.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 3 页
字号:
           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);
  }

/***********************************************************/
/* NextActivationToFire: Returns the next activation which */
/*   should be executed based on the current focus.        */
/***********************************************************/
static struct activation *NextActivationToFire(
  void *theEnv)
  {
   struct activation *theActivation;
   struct defmodule *theModule;

   /*====================================*/
   /* If there is no current focus, then */
   /* focus on the MAIN module.          */
   /*====================================*/

   if (EngineData(theEnv)->CurrentFocus == NULL)
     {
      theModule = (struct defmodule *) EnvFindDefmodule(theEnv,"MAIN");
      EnvFocus(theEnv,theModule);
     }

   /*===========================================================*/
   /* Determine the top activation on the agenda of the current */
   /* focus. If the current focus has no activations on its     */
   /* agenda, then pop the focus off the focus stack until      */
   /* a focus that has an activation on its agenda is found.    */
   /*===========================================================*/

   theActivation = EngineData(theEnv)->CurrentFocus->theDefruleModule->agenda;
   while ((theActivation == NULL) && (EngineData(theEnv)->CurrentFocus != NULL))
     {
      if (EngineData(theEnv)->CurrentFocus != NULL) EnvPopFocus(theEnv);
      if (EngineData(theEnv)->CurrentFocus != NULL) theActivation = EngineData(theEnv)->CurrentFocus->theDefruleModule->agenda;
     }

   /*=========================================*/
   /* Return the next activation to be fired. */
   /*=========================================*/

   return(theActivation);
  }

/***************************************************/
/* RemoveFocus: Removes the first occurence of the */
/*   specified module from the focus stack.        */
/***************************************************/
static struct defmodule *RemoveFocus(
  void *theEnv,
  struct defmodule *theModule)
  {
   struct focus *tempFocus,*prevFocus, *nextFocus;
   int found = FALSE;
   int currentFocusRemoved = FALSE;

   /*====================================*/
   /* Return NULL if there is nothing on */
   /* the focus stack to remove.         */
   /*====================================*/

   if (EngineData(theEnv)->CurrentFocus == NULL) return(NULL);

   /*=============================================*/
   /* Remove the first occurence of the specified */
   /* module from the focus stack.                */
   /*=============================================*/

   prevFocus = NULL;
   tempFocus = EngineData(theEnv)->CurrentFocus;
   while ((tempFocus != NULL) && (! found))
     {
      if (tempFocus->theModule == theModule)
        {
         found = TRUE;

         nextFocus = tempFocus->next;
         rtn_struct(theEnv,focus,tempFocus);
         tempFocus = nextFocus;

         if (prevFocus == NULL)
           {
            currentFocusRemoved = TRUE;
            EngineData(theEnv)->CurrentFocus = tempFocus;
           }
         else
           { prevFocus->next = tempFocus; }
        }
      else
        {
         prevFocus = tempFocus;
         tempFocus = tempFocus->next;
        }
     }

   /*=========================================*/
   /* If the given module is not in the focus */
   /* stack, simply return the current focus  */
   /*=========================================*/

   if (! found) return(EngineData(theEnv)->CurrentFocus->theModule);

   /*========================================*/
   /* If the current focus is being watched, */
   /* then print an informational message.   */
   /*========================================*/

#if DEBUGGING_FUNCTIONS
   if (EngineData(theEnv)->WatchFocus)
     {
      EnvPrintRouter(theEnv,WTRACE,"<== Focus ");
      EnvPrintRouter(theEnv,WTRACE,ValueToString(theModule->name));

      if ((EngineData(theEnv)->CurrentFocus != NULL) && currentFocusRemoved)
        {
         EnvPrintRouter(theEnv,WTRACE," to ");
         EnvPrintRouter(theEnv,WTRACE,ValueToString(EngineData(theEnv)->CurrentFocus->theModule->name));
        }

      EnvPrintRouter(theEnv,WTRACE,"\n");
     }
#endif

   /*======================================================*/
   /* Set the current module to the module associated with */
   /* the current focus (if it changed) and set a boolean  */
   /* flag indicating that the focus has changed.          */
   /*======================================================*/

   if ((EngineData(theEnv)->CurrentFocus != NULL) && currentFocusRemoved)
     { EnvSetCurrentModule(theEnv,(void *) EngineData(theEnv)->CurrentFocus->theModule); }
   EngineData(theEnv)->FocusChanged = TRUE;

   /*====================================*/
   /* Return the module that was removed */
   /* from the focus stack.              */
   /*====================================*/

   return(theModule);
  }

/*************************************************************/
/* EnvPopFocus: C access routine for the pop-focus function. */
/*************************************************************/
globle void *EnvPopFocus(
  void *theEnv)
  {
   if (EngineData(theEnv)->CurrentFocus == NULL) return(NULL);
   return((void *) RemoveFocus(theEnv,EngineData(theEnv)->CurrentFocus->theModule));
  }

/***************************************************************/
/* EnvGetNextFocus: Returns the next focus on the focus stack. */
/***************************************************************/
globle void *EnvGetNextFocus(
  void *theEnv,
  void *theFocus)
  {
   /*==================================================*/
   /* If NULL is passed as an argument, return the top */
   /* focus on the focus stack (the current focus).    */
   /*==================================================*/

   if (theFocus == NULL) return((void *) EngineData(theEnv)->CurrentFocus);

   /*=======================================*/
   /* Otherwise, return the focus following */
   /* the focus passed as an argument.      */
   /*=======================================*/

   return((void *) ((struct focus *) theFocus)->next);
  }

/******************************************************/
/* EnvFocus: C access routine for the focus function. */
/******************************************************/
globle void EnvFocus(
  void *theEnv,
  void *vTheModule)
  {
   struct defmodule *theModule = (struct defmodule *) vTheModule;
   struct focus *tempFocus;

   /*==================================================*/
   /* Make the specified module be the current module. */
   /* If the specified module is the current focus,    */
   /* then no further action is needed.                */
   /*==================================================*/

   EnvSetCurrentModule(theEnv,(void *) theModule);
   if (EngineData(theEnv)->CurrentFocus != NULL)
     { if (EngineData(theEnv)->CurrentFocus->theModule == theModule) return; }

   /*=====================================*/
   /* If the focus is being watched, then */
   /* print an information message.       */
   /*=====================================*/

#if DEBUGGING_FUNCTIONS
   if (EngineData(theEnv)->WatchFocus)
     {
      EnvPrintRouter(theEnv,WTRACE,"==> Focus ");
      EnvPrintRouter(theEnv,WTRACE,ValueToString(theModule->name));
      if (EngineData(theEnv)->CurrentFocus != NULL)
        {
         EnvPrintRouter(theEnv,WTRACE," from ");
         EnvPrintRouter(theEnv,WTRACE,ValueToString(EngineData(theEnv)->CurrentFocus->theModule->name));
        }
      EnvPrintRouter(theEnv,WTRACE,"\n");
     }
#endif

   /*=======================================*/
   /* Add the new focus to the focus stack. */
   /*=======================================*/

   tempFocus = get_struct(theEnv,focus);
   tempFocus->theModule = theModule;
   tempFocus->theDefruleModule = GetDefruleModuleItem(theEnv,theModule);
   tempFocus->next = EngineData(theEnv)->CurrentFocus;
   EngineData(theEnv)->CurrentFocus = tempFocus;
   EngineData(theEnv)->FocusChanged = TRUE;
  }

/************************************************/
/* ClearFocusStackCommand: H/L access routine   */
/*   for the clear-focus-stack command.         */
/************************************************/
globle void ClearFocusStackCommand(
  void *theEnv)
  {
   if (EnvArgCountCheck(theEnv,"list-focus-stack",EXACTLY,0) == -1) return;

   EnvClearFocusStack(theEnv);
  }

/****************************************/
/* EnvClearFocusStack: C access routine */
/*   for the clear-focus-stack command. */
/****************************************/
globle void EnvClearFocusStack(
  void *theEnv)
  {
   while (EngineData(theEnv)->CurrentFocus != NULL) EnvPopFocus(theEnv);

   EngineData(theEnv)->FocusChanged = TRUE;
  }

#if (! ENVIRONMENT_API_ONLY) && ALLOW_ENVIRONMENT_GLOBALS
/***********************************/
/* AddRunFunction: Adds a function */
/*   to the ListOfRunFunctions.    */
/***********************************/
globle intBool AddRunFunction(
  char *name,
  void (*functionPtr)(void),
  int priority)
  {
   void *theEnv;
   
   theEnv = GetCurrentEnvironment();

   EngineData(theEnv)->ListOfRunFunctions = 
       AddFunctionToCallList(theEnv,name,priority,(void (*)(void *)) functionPtr,
                             EngineData(theEnv)->ListOfRunFunctions,TRUE);
   return(1);
  }
#endif

/**************************************/
/* EnvAddRunFunction: Adds a function */
/*   to the ListOfRunFunctions.       */
/**************************************/
globle intBool EnvAddRunFunction(
  void *theEnv,
  char *name,
  void (*functionPtr)(void *),
  int priority)
  {
   EngineData(theEnv)->ListOfRunFunctions = AddFunctionToCallList(theEnv,name,priority,
                                              functionPtr,
                                              EngineData(theEnv)->ListOfRunFunctions,TRUE);
   return(1);
  }

/********************************************/
/* EnvRemoveRunFunction: Removes a function */
/*   from the ListOfRunFunctions.           */
/********************************************/
globle intBool EnvRemoveRunFunction(
  void *theEnv,
  char *name)
  {
   int found;

   EngineData(theEnv)->ListOfRunFunctions = 
      RemoveFunctionFromCallList(theEnv,name,EngineData(theEnv)->ListOfRunFunctions,&found);

   if (found) return(TRUE);

   return(FALSE);
  }

/*********************************************************/
/* RunCommand: H/L access routine for the run command.   */
/*********************************************************/
globle void RunCommand(
  void *theEnv)
  {
   int numArgs;
   long int runLimit = -1;
   DATA_OBJECT argPtr;

   if ((numArgs = EnvArgCountCheck(theEnv,"run",NO_MORE_THAN,1)) == -1) return;

   if (numArgs == 0)
     { runLimit = -1; }
   else if (numArgs == 1)
     {
      if (EnvArgTypeCheck(theEnv,"run",1,INTEGER,&argPtr) == FALSE) return;
      runLimit = DOToLong(argPtr);
     }

   EnvRun(theEnv,runLimit);

   return;
  }

/***********************************************/
/* HaltCommand: Causes rule execution to halt. */
/***********************************************/
globle void HaltCommand(
  void *theEnv)
  {
   EnvArgCountCheck(theEnv,"halt",EXACTLY,0);
   EngineData(theEnv)->HaltRules = TRUE;
  }

⌨️ 快捷键说明

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