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

📄 rulebld.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 2 页
字号:
            lastNode->bottom = tempNode;
            lastNode->endNandDepth = trackNode->endNandDepth;
            ReturnLHSParseNodes(theEnv,trackNode);
            trackNode = tempNode;
           }

         /*================================================*/
         /* If none of the previous conditions have been   */
         /* met, then there is an internal error.          */
         /*================================================*/

         else
           {
            SystemError(theEnv,"BUILD",1);
            EnvExitRouter(theEnv,EXIT_FAILURE);
           }
        }

      /*====================================*/
      /* Check the next pattern in the LHS. */
      /*====================================*/

      theLHS = theLHS->bottom;
     }
  }

/********************************************************************/
/* FindShareableJoin: Determines whether a join exists that can be  */
/*   reused for the join currently being added to the join network. */
/*   Returns a pointer to the join to be shared if one if found,    */
/*   otherwise returns a NULL pointer.                              */
/********************************************************************/
static struct joinNode *FindShareableJoin(
  struct joinNode *listOfJoins,
  void *rhsStruct,
  unsigned int firstJoin,
  unsigned int negatedRHS,
  int isLogical,
  struct expr *joinTest,
  int endDepth,
  int currentDepth,
  int lastIteration,
  struct joinNode **nandReconnect)
  {
   /*========================================*/
   /* Loop through all of the joins in the   */
   /* list of potential candiates for reuse. */
   /*========================================*/

   while (listOfJoins != NULL)
     {
      /*=========================================================*/
      /* If the join being tested for reuse is connected on the  */
      /* RHS to the end node of the pattern node associated with */
      /* the join to be added, then determine if the join can    */
      /* be reused. If so, return the join.                      */
      /*=========================================================*/

      if (listOfJoins->rightSideEntryStructure == rhsStruct)
        {
         if (TestJoinForReuse(listOfJoins,firstJoin,negatedRHS,isLogical,
                              joinTest,endDepth,currentDepth,
                              lastIteration,nandReconnect))
           { return(listOfJoins); }
        }

      /*====================================================*/
      /* Move on to the next potential candidate. Note that */
      /* the rightMatchNode link is used for traversing     */
      /* through the candidates for the first join of a     */
      /* rule and that rightDriveNode link is used for      */
      /* traversing through the candidates for subsequent   */
      /* joins of a rule.                                   */
      /*====================================================*/

      if (firstJoin)
        { listOfJoins = listOfJoins->rightMatchNode; }
      else
        { listOfJoins = listOfJoins->rightDriveNode; }
     }

   /*================================*/
   /* Return a NULL pointer, since a */
   /* reusable join was not found.   */
   /*================================*/

   return(NULL);
  }

/**************************************************************/
/* TestJoinForReuse: Determines if the specified join can be  */
/*   shared with a join being added for a rule being defined. */
/*   Returns TRUE if the join can be shared, otherwise FALSE. */
/**************************************************************/
static int TestJoinForReuse(
  struct joinNode *testJoin,
  unsigned firstJoin,
  unsigned negatedRHS,
  int isLogical,
  struct expr *joinTest,
  int endDepth,
  int currentDepth,
  int lastIteration,
  struct joinNode **nandReconnect)
  {
   /*==================================================*/
   /* The first join of a rule may only be shared with */
   /* a join that has its firstJoin field set to TRUE. */
   /*==================================================*/

   if (testJoin->firstJoin != firstJoin) return(FALSE);

   /*========================================================*/
   /* A join connected to a not CE may only be shared with a */
   /* join that has its patternIsNegated field set to TRUE.  */
   /*========================================================*/

   if (testJoin->patternIsNegated != negatedRHS) return(FALSE);

   /*==========================================================*/
   /* If the join added is associated with a logical CE, then  */
   /* either the join to be shared must be associated with a   */
   /* logical CE or the beta memory must be empty (since       */
   /* joins associate an extra field with each partial match). */
   /*==========================================================*/

   if ((isLogical == TRUE) &&
       (testJoin->logicalJoin == FALSE) &&
       (testJoin->beta != NULL))
     { return(FALSE); }

   /*===============================================================*/
   /* The expression associated with the join must be identical to  */
   /* the networkTest expression stored with the join to be shared. */
   /*===============================================================*/

   if (IdenticalExpression(testJoin->networkTest,joinTest) != TRUE)
     { return(FALSE); }

   /*==============================================================*/
   /* If the join being added enters another join from the right,  */
   /* then the series of "joins from the right" for the join being */
   /* added must match the series of "joins from the right" for    */
   /* the join being tested for reuse (i.e. the LHS connections    */
   /* from other joins must be identical for each of the joins in  */
   /* the series of "joins from the right."                        */
   /*==============================================================*/

   for (; endDepth < currentDepth; currentDepth--)
     {
      testJoin = testJoin->nextLevel;
      if (testJoin == NULL) return(FALSE);

      if (testJoin->joinFromTheRight == FALSE)
        { return(FALSE); }
      else if (nandReconnect[currentDepth-2] != testJoin->lastLevel)
        { return(FALSE); }
     }

   /*=============================================================*/
   /* The last join of a rule cannot be shared with the last join */
   /* of another rule. A join cannot be used as the last join of  */
   /* a rule if it already has partial matches in its beta memory */
   /* (because of the extra slot used to point at activations).   */
   /*=============================================================*/

   if (lastIteration)
     {
      if (testJoin->ruleToActivate != NULL) return(FALSE);

      if (testJoin->beta != NULL) return(FALSE);
     }

   /*===========================================================================*/
   /* A join cannot be shared if it is not the last join for a rule and shares  */
   /* part, but not all, of a series of joins connected to other joins from the */
   /* right. This is because the data structure for joins can only point to     */
   /* either a single join that is entered from the right or a series of joins  */
   /* that are entered from the left, but not both. (The last join of a rule    */
   /* does not require any links to other joins so it can be shared).           */
   /*===========================================================================*/

   if ((! lastIteration) && (testJoin->nextLevel != NULL))
     {
      if (testJoin->nextLevel->joinFromTheRight == TRUE)
        {
         if (((struct joinNode *) testJoin->nextLevel->rightSideEntryStructure) == testJoin)
           { return(FALSE); }
        }
     }

   /*=============================================*/
   /* The join can be shared since all conditions */
   /* for sharing have been satisfied.            */
   /*=============================================*/

   return(TRUE);
  }

/*************************************************************************/
/* CreateNewJoin: Creates a new join and links it into the join network. */
/*************************************************************************/
static struct joinNode *CreateNewJoin(
  void *theEnv,
  struct expr *joinTest,
  struct joinNode *lhsEntryStruct,
  void *rhsEntryStruct,
  int joinFromTheRight,
  int negatedRHSPattern)
  {
   struct joinNode *newJoin;

   /*===============================================*/
   /* If compilations are being watch, print +j to  */
   /* indicate that a new join has been created for */
   /* this pattern of the rule (i.e. a join could   */
   /* not be shared with another rule.              */
   /*===============================================*/

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

   /*========================================================*/
   /* Create the new join and initialize some of its values. */
   /*========================================================*/

   newJoin = get_struct(theEnv,joinNode);
   newJoin->beta = NULL;
   newJoin->nextLevel = NULL;
   newJoin->joinFromTheRight = joinFromTheRight;
   newJoin->patternIsNegated = negatedRHSPattern;
   newJoin->initialize = EnvGetIncrementalReset(theEnv);
   newJoin->logicalJoin = FALSE;
   newJoin->ruleToActivate = NULL;

   /*==============================================*/
   /* Install the expressions used to determine    */
   /* if a partial match satisfies the constraints */
   /* associated with this join.                   */
   /*==============================================*/

   newJoin->networkTest = AddHashedExpression(theEnv,joinTest);

   /*============================================================*/
   /* Initialize the values associated with the LHS of the join. */
   /*============================================================*/

   newJoin->lastLevel = lhsEntryStruct;

   if (lhsEntryStruct == NULL)
     {
      newJoin->firstJoin = TRUE;
      newJoin->depth = 1;
      newJoin->rightDriveNode = NULL;
     }
   else
     {
      newJoin->firstJoin = FALSE;
      newJoin->depth = lhsEntryStruct->depth;
      newJoin->depth++; /* To work around Sparcworks C compiler bug */
      newJoin->rightDriveNode = lhsEntryStruct->nextLevel;
      lhsEntryStruct->nextLevel = newJoin;
     }

   /*=======================================================*/
   /* Initialize the pointer values associated with the RHS */
   /* of the join (both for the new join and the join or    */
   /* pattern which enters this join from the right.        */
   /*=======================================================*/

   newJoin->rightSideEntryStructure = rhsEntryStruct;

   if (joinFromTheRight)
     {
      newJoin->rightMatchNode = NULL;
      ((struct joinNode *) rhsEntryStruct)->nextLevel = newJoin;
     }
   else
     {
      newJoin->rightMatchNode = ((struct patternNodeHeader *) rhsEntryStruct)->entryJoin;
      ((struct patternNodeHeader *) rhsEntryStruct)->entryJoin = newJoin;
     }

   /*================================*/
   /* Return the newly created join. */
   /*================================*/

   return(newJoin);
  }

#endif



⌨️ 快捷键说明

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