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

📄 factmch.c

📁 一套美国国家宇航局人工智能中心NASA的专家系统工具源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   theSlotValue = (struct multifield *)      CurrentPatternFact->theProposition.theFields[thePattern->whichSlot].value;   /*===============================================*/   /* Save the value of the markers already stored. */   /*===============================================*/   oldMark = markers;   /*===========================================*/   /* Create a new multifield marker and append */   /* it to the end of the current list.        */   /*===========================================*/      newMark = get_struct(multifieldMarker);   newMark->whichField = thePattern->whichField - 1;   newMark->where.whichSlotNumber = (short) thePattern->whichSlot;   newMark->startPosition = (thePattern->whichField - 1) + offset;   newMark->next = NULL;      if (endMark == NULL)     {      markers = newMark;      CurrentPatternMarks = markers;     }   else     { endMark->next = newMark; }          /*============================================*/   /* Handle a multifield constraint as the last */   /* constraint of a slot as a special case.    */   /*============================================*/      if (thePattern->header.endSlot)     {      newMark->endPosition = theSlotValue->multifieldLength -                              (thePattern->leaveFields + 1);                                   /*=======================================================*/      /* Make sure the endPosition is never more than less one */      /* less of the startPosition (a multifield containing no */      /* values.                                               */      /*=======================================================*/            if (newMark->endPosition < newMark->startPosition)        { newMark->endPosition = newMark->startPosition - 1; }            /*===========================================*/      /* Determine if the constraint is satisfied. */      /*===========================================*/            if ((thePattern->networkTest == NULL) ?           CLIPS_TRUE :           (EvaluatePatternExpression(thePattern,thePattern->networkTest,                                     (int) thePattern->whichField + offset)))        {         /*=======================================================*/         /* If a leaf pattern node has been successfully reached, */         /* then the pattern has been satisified. Generate an     */         /* alpha match to store in the pattern node.             */         /*=======================================================*/         if (thePattern->header.stopNode)            { ProcessFactAlphaMatch(CurrentPatternFact,CurrentPatternMarks,thePattern); }                  /*=============================================*/         /* Recursively continue pattern matching based */         /* on the multifield binding just generated.   */         /*=============================================*/                  FactPatternMatch(CurrentPatternFact,                          thePattern->nextLevel,0,CurrentPatternMarks,newMark);        }             /*================================================*/      /* Discard the multifield marker since we've done */      /* all the pattern matching for this binding of   */      /* the multifield slot constraint.                */      /*================================================*/            rtn_struct(multifieldMarker,newMark);      if (endMark != NULL) endMark->next = NULL;      CurrentPatternMarks = oldMark;      return;     }         /*==============================================*/   /* Perform matching for nodes beneath this one. */   /*==============================================*/      for (repeatCount = theSlotValue->multifieldLength -                       (newMark->startPosition + thePattern->leaveFields);        repeatCount >= 0;        repeatCount--)     {            newMark->endPosition = newMark->startPosition + (repeatCount - 1);            if ((thePattern->networkTest == NULL) ?           CLIPS_TRUE :           (EvaluatePatternExpression(thePattern,thePattern->networkTest,                                     (int) thePattern->whichField + offset)))        {         FactPatternMatch(CurrentPatternFact,                          thePattern->nextLevel,offset + repeatCount - 1,                          CurrentPatternMarks,newMark);        }     }    /*======================================================*/    /* Get rid of the marker created for a multifield node. */    /*======================================================*/    rtn_struct(multifieldMarker,newMark);    if (endMark != NULL) endMark->next = NULL;    CurrentPatternMarks = oldMark;   }        /******************************************************//* GetNextFactPatternNode: Returns the next node in a *//*   pattern network tree to be traversed. The next   *//*   node is computed using a depth first traversal.  */                /******************************************************/static struct factPatternNode *GetNextFactPatternNode(finishedMatching,thePattern)  int finishedMatching;  struct factPatternNode *thePattern;  {   EvaluationError = CLIPS_FALSE;      /*===================================================*/   /* If pattern matching was successful at the current */   /* node in the tree and it's possible to go deeper   */   /* into the tree, then move down to the next level.  */   /*===================================================*/   if (finishedMatching == CLIPS_FALSE)      { if (thePattern->nextLevel != NULL) return(thePattern->nextLevel); }        /*================================================*/   /* Keep backing up toward the root of the pattern */   /* network until a side branch can be taken.      */   /*================================================*/           while (thePattern->rightNode == NULL)     {      /*========================================*/      /* Back up to check the next side branch. */      /*========================================*/      thePattern = thePattern->lastLevel;            /*======================================*/      /* If we branched up from the root, the */      /* entire tree has been traversed.      */      /*======================================*/      if (thePattern == NULL) return(NULL);            /*===================================================*/      /* If we branched up to a multifield node, then stop */      /* since these nodes are handled recursively. The    */      /* previous call to the pattern matching algorithm   */      /* on the stack will handle backing up to the nodes  */      /* above the multifield node in the pattern network. */      /*===================================================*/            if (thePattern->header.multifieldNode) return(NULL);     }      /*==================================*/   /* Move on to the next side branch. */   /*==================================*/    return(thePattern->rightNode);  }           /*******************************************************//* ProcessFactAlphaMatch: When a fact pattern has been *//*   satisfied, this routine creates an alpha match to *//*   store in the pattern network and then sends the   *//*   new alpha match through the join network.         *//*******************************************************/static VOID ProcessFactAlphaMatch(theFact,theMarks,thePattern)  struct fact *theFact;  struct multifieldMarker *theMarks;  struct factPatternNode *thePattern;  {   struct partialMatch *theMatch;   struct patternMatch *listOfMatches;   struct joinNode *listOfJoins;     /*===========================================*/  /* Create the partial match for the pattern. */  /*===========================================*/           theMatch = CreateAlphaMatch(theFact,theMarks,(struct patternNodeHeader *) &thePattern->header);           /*=======================================================*/  /* Add the pattern to the list of matches for this fact. */  /*=======================================================*/  listOfMatches = (struct patternMatch *) theFact->list;  theFact->list = (VOID *) get_struct(patternMatch);  ((struct patternMatch *) theFact->list)->next = listOfMatches;  ((struct patternMatch *) theFact->list)->matchingPattern = (struct patternNodeHeader *) thePattern;  ((struct patternMatch *) theFact->list)->theMatch = theMatch;  /*================================================================*/  /* Send the partial match to the joins connected to this pattern. */  /*================================================================*/  for (listOfJoins = thePattern->header.entryJoin;       listOfJoins != NULL;       listOfJoins = listOfJoins->rightMatchNode)     { NetworkAssert(theMatch,listOfJoins,RHS); }  }  /*****************************************************************//* EvaluatePatternExpression: Performs a faster evaluation for   *//*   fact pattern network expressions than if EvaluateExpression *//*   were used directly.                                         *//*****************************************************************/static int EvaluatePatternExpression(patternPtr,theTest,thePosition)  struct factPatternNode *patternPtr;  struct expr *theTest;  int thePosition;  {   DATA_OBJECT theResult;   struct expr *oldArgument;   int rv;      /*=====================================*/   /* A pattern node without a constraint */   /* is always satisfied.                */   /*=====================================*/      if (theTest == NULL) return(CLIPS_TRUE);      /*======================================*/   /* Evaluate pattern network primitives. */   /*======================================*/      switch(theTest->type)     {      /*==============================================*/      /* This primitive compares the value stored in  */      /* a single field slot to a constant for either */      /* equality or inequality.                      */      /*==============================================*/            case FACT_PN_CONSTANT1:        oldArgument = CurrentExpression;        CurrentExpression = theTest;        rv = FactPNConstant1(theTest->value,&theResult);        CurrentExpression = oldArgument;        return(rv);              /*=============================================*/      /* This primitive compares the value stored in */      /* a multifield slot to a constant for either  */      /* equality or inequality.                     */      /*=============================================*/

⌨️ 快捷键说明

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