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

📄 factmch.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   oldMark = markers;   /*===========================================*/   /* Create a new multifield marker and append */   /* it to the end of the current list.        */   /*===========================================*/   newMark = get_struct(theEnv,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;      FactData(theEnv)->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 = (long) 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->header.selector)        {         if (EvaluatePatternExpression(theEnv,thePattern,thePattern->networkTest->nextArg))           {            EvaluateExpression(theEnv,thePattern->networkTest,&theResult);                     thePattern = FindHashedPatternNode(theEnv,thePattern,theResult.type,theResult.value);            if (thePattern != NULL)              { success = TRUE; }            else              { success = FALSE; }           }         else           { success = FALSE; }        }      else if ((thePattern->networkTest == NULL) ?          TRUE :          (EvaluatePatternExpression(theEnv,thePattern,thePattern->networkTest)))        { success = TRUE; }      else        { success = FALSE; }          if (success)        {         /*=======================================================*/         /* 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(theEnv,FactData(theEnv)->CurrentPatternFact,FactData(theEnv)->CurrentPatternMarks,thePattern); }         /*=============================================*/         /* Recursively continue pattern matching based */         /* on the multifield binding just generated.   */         /*=============================================*/         FactPatternMatch(theEnv,FactData(theEnv)->CurrentPatternFact,                          thePattern->nextLevel,0,FactData(theEnv)->CurrentPatternMarks,newMark);        }      /*================================================*/      /* Discard the multifield marker since we've done */      /* all the pattern matching for this binding of   */      /* the multifield slot constraint.                */      /*================================================*/      rtn_struct(theEnv,multifieldMarker,newMark);      if (endMark != NULL) endMark->next = NULL;      FactData(theEnv)->CurrentPatternMarks = oldMark;      return;     }   /*==============================================*/   /* Perform matching for nodes beneath this one. */   /*==============================================*/   for (repeatCount = (long) (theSlotValue->multifieldLength -                      (newMark->startPosition + thePattern->leaveFields));        repeatCount >= 0;        repeatCount--)     {      newMark->endPosition = newMark->startPosition + (repeatCount - 1);      if (thePattern->header.selector)        {         if (EvaluatePatternExpression(theEnv,thePattern,thePattern->networkTest->nextArg))           {            EvaluateExpression(theEnv,thePattern->networkTest,&theResult);                     tempPtr = FindHashedPatternNode(theEnv,thePattern,theResult.type,theResult.value);            if (tempPtr != NULL)              {               FactPatternMatch(theEnv,FactData(theEnv)->CurrentPatternFact,                                tempPtr->nextLevel,offset + repeatCount - 1,                                FactData(theEnv)->CurrentPatternMarks,newMark);              }           }        }      else if ((thePattern->networkTest == NULL) ?               TRUE :               (EvaluatePatternExpression(theEnv,thePattern,thePattern->networkTest)))        {         FactPatternMatch(theEnv,FactData(theEnv)->CurrentPatternFact,                          thePattern->nextLevel,offset + repeatCount - 1,                          FactData(theEnv)->CurrentPatternMarks,newMark);        }     }    /*======================================================*/    /* Get rid of the marker created for a multifield node. */    /*======================================================*/    rtn_struct(theEnv,multifieldMarker,newMark);    if (endMark != NULL) endMark->next = NULL;    FactData(theEnv)->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(  void *theEnv,  int finishedMatching,  struct factPatternNode *thePattern)  {   EvaluationData(theEnv)->EvaluationError = 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 == 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) ||          ((thePattern->lastLevel != NULL) &&           (thePattern->lastLevel->header.selector)))     {      /*========================================*/      /* 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);            /*======================================*/      /* Skip selector constants and pop back */      /* back to the selector node.           */      /*======================================*/      if ((thePattern->lastLevel != NULL) &&          (thePattern->lastLevel->header.selector))        { thePattern = thePattern->lastLevel; }      /*===================================================*/      /* 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(  void *theEnv,  struct fact *theFact,  struct multifieldMarker *theMarks,  struct factPatternNode *thePattern)  {   struct partialMatch *theMatch;   struct patternMatch *listOfMatches;   struct joinNode *listOfJoins;   unsigned long hashValue = 0;  /*============================================*/  /* Create the hash value for the alpha match. */  /*============================================*/  hashValue = ComputeRightHashValue(theEnv,&thePattern->header);  /*===========================================*/  /* Create the partial match for the pattern. */  /*===========================================*/  theMatch = CreateAlphaMatch(theEnv,theFact,theMarks,(struct patternNodeHeader *) &thePattern->header,hashValue);  theMatch->owner = &thePattern->header;  /*=======================================================*/  /* Add the pattern to the list of matches for this fact. */  /*=======================================================*/  listOfMatches = (struct patternMatch *) theFact->list;  theFact->list = (void *) get_struct(theEnv,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(theEnv,theMatch,listOfJoins); }  }/*****************************************************************//* EvaluatePatternExpression: Performs a faster evaluation for   *//*   fact pattern network expressions than if EvaluateExpression *//*   were used directly.                                         *//*****************************************************************/static int EvaluatePatternExpression(  void *theEnv,  struct factPatternNode *patternPtr,  struct expr *theTest)  {   DATA_OBJECT theResult;   struct expr *oldArgument;   int rv;   /*=====================================*/   /* A pattern node without a constraint */   /* is always satisfied.                */   /*=====================================*/   if (theTest == NULL) return(TRUE);   /*======================================*/   /* Evaluate pattern network primitives. */   /*======================================*/

⌨️ 快捷键说明

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