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

📄 rulebld.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 2 页
字号:
   /*******************************************************/
   /*      "C" Language Integrated Production System      */
   /*                                                     */
   /*             CLIPS Version 6.24  05/17/06            */
   /*                                                     */
   /*                  RULE BUILD MODULE                  */
   /*******************************************************/

/*************************************************************/
/* Purpose: Provides routines to ntegrates a set of pattern  */
/*   and join tests associated with a rule into the pattern  */
/*   and join networks. The joins are integrated into the    */
/*   join network by routines in this module. The pattern    */
/*   is integrated by calling the external routine           */
/*   associated with the pattern parser that originally      */
/*   parsed the pattern.                                     */
/*                                                           */
/* Principal Programmer(s):                                  */
/*      Gary D. Riley                                        */
/*                                                           */
/* Contributing Programmer(s):                               */
/*                                                           */
/* Revision History:                                         */
/*                                                           */
/*      6.24: Removed INCREMENTAL_RESET compilation flag.    */
/*                                                           */
/*            Corrected code to remove compiler warnings.    */
/*                                                           */
/*************************************************************/

#define _RULEBLD_SOURCE_

#include "setup.h"

#if DEFRULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY)

#include <stdio.h>
#define _STDIO_INCLUDED_
#include <stdlib.h>

#include "constant.h"
#include "envrnmnt.h"
#include "constrct.h"
#include "drive.h"
#include "incrrset.h"
#include "memalloc.h"
#include "pattern.h"
#include "reteutil.h"
#include "router.h"
#include "rulebld.h"
#include "watch.h"

/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/

   static struct joinNode        *FindShareableJoin(struct joinNode *,void *,unsigned,unsigned,int,
                                                    struct expr *,
                                                    int,int,int,struct joinNode **);
   static int                     TestJoinForReuse(struct joinNode *,unsigned,unsigned,int,
                                                   struct expr *,
                                                   int,int,int,struct joinNode **);
   static struct joinNode        *CreateNewJoin(void *,struct expr *,
                                                struct joinNode *,void *,int,int);
   static void                    AttachTestCEsToPatternCEs(void *,struct lhsParseNode *);

/****************************************************************/
/* ConstructJoins: Integrates a set of pattern and join tests   */
/*   associated with a rule into the pattern and join networks. */
/****************************************************************/
globle struct joinNode *ConstructJoins(
  void *theEnv,
  int logicalJoin,
  struct lhsParseNode *theLHS)
  {
   struct joinNode *lastJoin = NULL;
   struct patternNodeHeader *lastPattern;
   unsigned firstJoin = TRUE;
   int tryToReuse = TRUE;
   struct joinNode *listOfJoins;
   struct joinNode *oldJoin;
   int joinNumber = 1;
   int isLogical;
   struct joinNode *nandReconnect[32];
   int currentDepth = 1;
   int lastIteration = FALSE;
   int rhsType;
   int endDepth;

   /*===================================================*/
   /* Remove any test CEs from the LHS and attach their */
   /* expression to the closest preceeding non-negated  */
   /* join at the same not/and depth.                   */
   /*===================================================*/

   AttachTestCEsToPatternCEs(theEnv,theLHS);

   /*=====================================================*/
   /* Process each pattern CE in the rule. At this point, */
   /* there should be no and/or/not/test CEs in the LHS.  */
   /*=====================================================*/

   while (theLHS != NULL)
     {
      if (theLHS->bottom == NULL) lastIteration = TRUE;

      /*==================================================*/
      /* If the pattern is the start of a new not/and CE, */
      /* then remember the join to reconnect to after the */
      /* join from the right is completed.                */
      /*==================================================*/

      while (theLHS->beginNandDepth > currentDepth)
        {
         nandReconnect[currentDepth-1] = lastJoin;
         currentDepth++;
        }

      /*============================================================*/
      /* Add the next pattern for this rule to the pattern network. */
      /*============================================================*/

      rhsType = theLHS->patternType->positionInArray;
      lastPattern = (*theLHS->patternType->addPatternFunction)(theEnv,theLHS);

      /*======================================================*/
      /* Determine if the join being added is a logical join. */
      /*======================================================*/

      if (joinNumber == logicalJoin) isLogical = TRUE;
      else isLogical = FALSE;

      /*===============================================*/
      /* Get the list of joins which could potentially */
      /* be reused in place of the join being added.   */
      /*===============================================*/

      if (firstJoin == TRUE)
        { listOfJoins = lastPattern->entryJoin; }
      else
        { listOfJoins = lastJoin->nextLevel; }

      /*=======================================================*/
      /* Determine if the next join to be added can be shared. */
      /*=======================================================*/

      endDepth = theLHS->endNandDepth;
      if ((tryToReuse == TRUE) &&
          ((oldJoin = FindShareableJoin(listOfJoins,(void *) lastPattern,firstJoin,
                                        theLHS->negated,isLogical,
                                        theLHS->networkTest,
                                        endDepth,currentDepth,
                                        lastIteration,nandReconnect)) != NULL) )
        {
#if DEBUGGING_FUNCTIONS
         if ((EnvGetWatchItem(theEnv,"compilations") == TRUE) && GetPrintWhileLoading(theEnv))
           { EnvPrintRouter(theEnv,WDIALOG,"=j"); }
#endif
         lastJoin = oldJoin;
        }
      else
        {
         tryToReuse = FALSE;
         lastJoin = CreateNewJoin(theEnv,theLHS->networkTest,
                                  lastJoin,lastPattern,
                                  FALSE,(int) theLHS->negated);
         lastJoin->rhsType = rhsType;
        }

      /*==========================================================*/
      /* Create any joins from the right needed to handle not/and */
      /* CE combinations and connect them to the join network.    */
      /*==========================================================*/

      while (endDepth < currentDepth)
        {
         currentDepth--;

         if (lastJoin->nextLevel == NULL) tryToReuse = FALSE;

         if (tryToReuse)
           {
#if DEBUGGING_FUNCTIONS
            if ((EnvGetWatchItem(theEnv,"compilations") == TRUE) && GetPrintWhileLoading(theEnv))
              { EnvPrintRouter(theEnv,WDIALOG,"=j"); }
#endif
            lastJoin = lastJoin->nextLevel;
           }
         else
           {
            lastJoin = CreateNewJoin(theEnv,NULL,nandReconnect[currentDepth-1],
                                     lastJoin,TRUE,FALSE);
           }
        }

      /*=======================================*/
      /* Move on to the next join to be added. */
      /*=======================================*/

      theLHS = theLHS->bottom;
      joinNumber++;
      firstJoin = FALSE;
     }

   /*===================================================*/
   /* If compilations are being watched, put a carriage */
   /* return after all of the =j's and +j's             */
   /*===================================================*/

#if DEBUGGING_FUNCTIONS
   if ((EnvGetWatchItem(theEnv,"compilations") == TRUE) && GetPrintWhileLoading(theEnv))
     { EnvPrintRouter(theEnv,WDIALOG,"\n"); }
#endif

   /*=============================*/
   /* Return the last join added. */
   /*=============================*/

   return(lastJoin);
  }

/****************************************************************/
/* AttachTestCEsToPatternCEs: Attaches the expressions found in */
/*   test CEs to the closest preceeding pattern CE that is not  */
/*   negated and is at the same not/and depth.                  */
/****************************************************************/
static void AttachTestCEsToPatternCEs(
  void *theEnv,
  struct lhsParseNode *theLHS)
  {
   struct lhsParseNode *lastNode = NULL, *trackNode, *tempNode;

   /*===============================================*/
   /* Look at each pattern on the rule's LHS to see */
   /* if any test CEs should be attached to it.     */
   /*===============================================*/

   while (theLHS != NULL)
     {
      /*==============================================*/
      /* If the pattern is negated, then don't bother */
      /* looking for any test CEs to attach to it.    */
      /*==============================================*/

      if (theLHS->negated)
        { trackNode = NULL; }
      else
        {
         lastNode = theLHS;
         trackNode = theLHS->bottom;
        }

      /*=================================================*/
      /* Check all of the patterns following the current */
      /* pattern to check for test CEs which can be      */
      /* attached to the current pattern.                */
      /*=================================================*/

      while (trackNode != NULL)
        {
         /*=======================================================*/
         /* Skip over any CEs that have a higher not/and depth or */
         /* are negated since any test CEs found within these CEs */
         /* would be attached to another pattern with the same    */
         /* depth, rather than the current pattern.               */
         /*=======================================================*/

         if ((trackNode->beginNandDepth != theLHS->beginNandDepth) ||
             (trackNode->negated))
           {
            lastNode = trackNode;
            trackNode = trackNode->bottom;
           }

         /*======================================================*/
         /* Once a non-negated pattern has been encounted at the */
         /* same not/and depth as the current pattern, then stop */
         /* because any test CEs following this pattern would be */
         /* attached to it rather than the current pattern.      */
         /*======================================================*/

         else if (trackNode->type == PATTERN_CE)
           { trackNode = NULL; }

         /*==================================================*/
         /* A test CE encountered at the same not/and depth  */
         /* can be added to the network test expressions for */
         /* the currentpattern.                              */
         /*==================================================*/

         else if (trackNode->type == TEST_CE)
           {
            theLHS->networkTest = CombineExpressions(theEnv,theLHS->networkTest,
                                                     trackNode->networkTest);
            trackNode->networkTest = NULL;
            tempNode = trackNode->bottom;
            trackNode->bottom = NULL;

⌨️ 快捷键说明

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