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

📄 rulebld.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 2 页
字号:
            trackNode = tempNode;           }                    /*================================================*/         /* If none of the previous conditions have been   */         /* met, then there is an internal error in CLIPS. */          /*================================================*/                     else           {             CLIPSSystemError("BUILD",1);            ExitCLIPS(4);           }        }              /*====================================*/      /* 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(listOfJoins,rhsStruct,firstJoin,negatedRHS,                                          isLogical,joinTest,                                          endDepth,currentDepth,lastIteration,                                          nandReconnect)  struct joinNode *listOfJoins;  VOID *rhsStruct;  int firstJoin;  int negatedRHS;  int isLogical;  struct expr *joinTest;  int endDepth, currentDepth, 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(testJoin,firstJoin,negatedRHS,isLogical,joinTest,                            endDepth,currentDepth,lastIteration,nandReconnect)  struct joinNode *testJoin;  int firstJoin;  int negatedRHS;  int isLogical;  struct expr *joinTest;  int endDepth, currentDepth, 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(CLIPS_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(CLIPS_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 == CLIPS_TRUE) &&        (testJoin->logicalJoin == CLIPS_FALSE) &&       (testJoin->beta != NULL))     { return(CLIPS_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) != CLIPS_TRUE)      { return(CLIPS_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(CLIPS_FALSE);            if (testJoin->joinFromTheRight == CLIPS_FALSE)         { return(CLIPS_FALSE); }      else if (nandReconnect[currentDepth-2] != testJoin->lastLevel)         { return(CLIPS_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(CLIPS_FALSE);            if (testJoin->beta != NULL) return(CLIPS_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 == CLIPS_TRUE)        {         if (((struct joinNode *) testJoin->nextLevel->rightSideEntryStructure) == testJoin)           { return(CLIPS_FALSE); }        }     }      /*=============================================*/   /* The join can be shared since all conditions */   /* for sharing have been satisfied.            */   /*=============================================*/      return(CLIPS_TRUE);  }              /*************************************************************************//* CreateNewJoin: Creates a new join and links it into the join network. *//*************************************************************************/static struct joinNode *CreateNewJoin(joinTest,lhsEntryStruct,rhsEntryStruct,                                      joinFromTheRight,negatedRHSPattern)  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 ((GetWatchItem("compilations") == CLIPS_TRUE) && GetPrintWhileLoading())     { PrintCLIPS(WDIALOG,"+j"); }#endif   /*========================================================*/   /* Create the new join and initialize some of its values. */   /*========================================================*/      newJoin = get_struct(joinNode);   newJoin->beta = NULL;   newJoin->nextLevel = NULL;   newJoin->joinFromTheRight = joinFromTheRight;   newJoin->patternIsNegated = negatedRHSPattern;#if INCREMENTAL_RESET   newJoin->initialize = GetIncrementalReset();#else   newJoin->initialize = CLIPS_FALSE;#endif   newJoin->logicalJoin = CLIPS_FALSE;   newJoin->ruleToActivate = NULL;      /*==============================================*/   /* Install the expressions used to determine    */   /* if a partial match satisfies the constraints */   /* associated with this join.                   */   /*==============================================*/      newJoin->networkTest = AddHashedExpression(joinTest);      /*============================================================*/   /* Initialize the values associated with the LHS of the join. */   /*============================================================*/         newJoin->lastLevel = lhsEntryStruct;                   if (lhsEntryStruct == NULL)     {      newJoin->firstJoin = CLIPS_TRUE;      newJoin->depth = 1;      newJoin->rightDriveNode = NULL;     }   else     {      newJoin->firstJoin = CLIPS_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 + -