📄 reteutil.c
字号:
/*=========================*/ /* Update the alpha lists. */ /*=========================*/ if (thePM->prevRightChild == NULL) { if (thePM->rightParent != NULL) { thePM->rightParent->children = thePM->nextRightChild; if (thePM->nextRightChild != NULL) { thePM->rightParent->children = thePM->nextRightChild; thePM->nextRightChild->rightParent = thePM->rightParent; } } } else { thePM->prevRightChild->nextRightChild = thePM->nextRightChild; } if (thePM->nextRightChild != NULL) { thePM->nextRightChild->prevRightChild = thePM->prevRightChild; } /*===========================*/ /* Update the blocked lists. */ /*===========================*/ if (thePM->prevBlocked == NULL) { tempPM = (struct partialMatch *) thePM->marker; if (tempPM != NULL) { tempPM->blockList = thePM->nextBlocked; } } else { thePM->prevBlocked->nextBlocked = thePM->nextBlocked; } if (thePM->nextBlocked != NULL) { thePM->nextBlocked->prevBlocked = thePM->prevBlocked; } if (! DefruleData(theEnv)->BetaMemoryResizingFlag) { return; } if ((theMemory->count == 0) && (theMemory->size > 1)) { ResetBetaMemory(theEnv,theMemory); } } /*******************************************************************//* UnlinkBetaPartialMatchfromAlphaAndBetaLineage: Removes the *//* lineage links from a beta memory partial match. This removes *//* the links between this partial match and its left and right *//* memory parents. It also removes the links between this *//* partial match and any of its children in other beta memories. *//*******************************************************************/static void UnlinkBetaPartialMatchfromAlphaAndBetaLineage( struct partialMatch *thePM) { struct partialMatch *tempPM; /*=========================*/ /* Update the alpha lists. */ /*=========================*/ if (thePM->prevRightChild == NULL) { if (thePM->rightParent != NULL) { thePM->rightParent->children = thePM->nextRightChild; } } else { thePM->prevRightChild->nextRightChild = thePM->nextRightChild; } if (thePM->nextRightChild != NULL) { thePM->nextRightChild->prevRightChild = thePM->prevRightChild; } thePM->rightParent = NULL; thePM->nextRightChild = NULL; thePM->prevRightChild = NULL; /*========================*/ /* Update the beta lists. */ /*========================*/ if (thePM->prevLeftChild == NULL) { if (thePM->leftParent != NULL) { thePM->leftParent->children = thePM->nextLeftChild; } } else { thePM->prevLeftChild->nextLeftChild = thePM->nextLeftChild; } if (thePM->nextLeftChild != NULL) { thePM->nextLeftChild->prevLeftChild = thePM->prevLeftChild; } thePM->leftParent = NULL; thePM->nextLeftChild = NULL; thePM->prevLeftChild = NULL; /*===========================*/ /* Update the blocked lists. */ /*===========================*/ if (thePM->prevBlocked == NULL) { tempPM = (struct partialMatch *) thePM->marker; if (tempPM != NULL) { tempPM->blockList = thePM->nextBlocked; } } else { thePM->prevBlocked->nextBlocked = thePM->nextBlocked; } if (thePM->nextBlocked != NULL) { thePM->nextBlocked->prevBlocked = thePM->prevBlocked; } thePM->marker = NULL; thePM->nextBlocked = NULL; thePM->prevBlocked = NULL; /*===============================================*/ /* Remove parent reference from the child links. */ /*===============================================*/ if (thePM->children != NULL) { if (thePM->betaMemory) { for (tempPM = thePM->children; tempPM != NULL; tempPM = tempPM->nextLeftChild) { tempPM->leftParent = NULL; } } else { for (tempPM = thePM->children; tempPM != NULL; tempPM = tempPM->nextRightChild) { tempPM->rightParent = NULL; } } thePM->children = NULL; } } /********************************************************//* MergePartialMatches: Merges two partial matches. The *//* second match should either be NULL (indicating a *//* negated CE) or contain a single match. *//********************************************************/globle struct partialMatch *MergePartialMatches( void *theEnv, struct partialMatch *lhsBind, struct partialMatch *rhsBind) { struct partialMatch *linker; static struct partialMatch mergeTemplate = { 1 }; /* betaMemory is TRUE, remainder are 0 or NULL */ /*=================================*/ /* Allocate the new partial match. */ /*=================================*/ linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) * lhsBind->bcount); /*============================================*/ /* Set the flags to their appropriate values. */ /*============================================*/ memcpy(linker,&mergeTemplate,sizeof(struct partialMatch) - sizeof(struct genericMatch)); linker->bcount = lhsBind->bcount + 1; /*========================================================*/ /* Copy the bindings of the partial match being extended. */ /*========================================================*/ memcpy(linker->binds,lhsBind->binds,sizeof(struct genericMatch) * lhsBind->bcount); /*===================================*/ /* Add the binding of the rhs match. */ /*===================================*/ if (rhsBind == NULL) { linker->binds[lhsBind->bcount].gm.theValue = NULL; } else { linker->binds[lhsBind->bcount].gm.theValue = rhsBind->binds[0].gm.theValue; } return(linker); }/*******************************************************************//* InitializePatternHeader: Initializes a pattern header structure *//* (used by the fact and instance pattern matchers). *//*******************************************************************/globle void InitializePatternHeader( void *theEnv, struct patternNodeHeader *theHeader) {#if MAC_MCW || IBM_MCW || MAC_XCD#pragma unused(theEnv)#endif theHeader->firstHash = NULL; theHeader->lastHash = NULL; theHeader->entryJoin = NULL; theHeader->rightHash = NULL; theHeader->singlefieldNode = FALSE; theHeader->multifieldNode = FALSE; theHeader->stopNode = FALSE;#if (! RUN_TIME) theHeader->initialize = EnvGetIncrementalReset(theEnv);#else theHeader->initialize = FALSE;#endif theHeader->marked = FALSE; theHeader->beginSlot = FALSE; theHeader->endSlot = FALSE; theHeader->selector = FALSE; }/******************************************************************//* CreateAlphaMatch: Given a pointer to an entity (such as a fact *//* or instance) which matched a pattern, this function creates *//* a partial match suitable for storing in the alpha memory of *//* the pattern network. Note that the multifield markers which *//* are passed as a calling argument are copied (thus the caller *//* is still responsible for freeing these data structures). *//******************************************************************/globle struct partialMatch *CreateAlphaMatch( void *theEnv, void *theEntity, struct multifieldMarker *markers, struct patternNodeHeader *theHeader, unsigned long hashOffset) { struct partialMatch *theMatch; struct alphaMatch *afbtemp; unsigned long hashValue; struct alphaMemoryHash *theAlphaMemory; /*==================================================*/ /* Create the alpha match and intialize its values. */ /*==================================================*/ theMatch = get_struct(theEnv,partialMatch); InitializePMLinks(theMatch); theMatch->betaMemory = FALSE; theMatch->busy = FALSE; theMatch->bcount = 1; theMatch->hashValue = hashOffset; afbtemp = get_struct(theEnv,alphaMatch); afbtemp->next = NULL; afbtemp->matchingItem = (struct patternEntity *) theEntity; if (markers != NULL) { afbtemp->markers = CopyMultifieldMarkers(theEnv,markers); } else { afbtemp->markers = NULL; } theMatch->binds[0].gm.theMatch = afbtemp; /*============================================*/ /* Find the alpha memory of the pattern node. */ /*============================================*/ hashValue = AlphaMemoryHashValue(theHeader,hashOffset); theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue); afbtemp->bucket = hashValue; /*============================================*/ /* Create an alpha memory if it wasn't found. */ /*============================================*/ if (theAlphaMemory == NULL) { theAlphaMemory = get_struct(theEnv,alphaMemoryHash); theAlphaMemory->bucket = hashValue; theAlphaMemory->owner = theHeader; theAlphaMemory->alphaMemory = NULL; theAlphaMemory->endOfQueue = NULL; theAlphaMemory->nextHash = NULL; theAlphaMemory->next = DefruleData(theEnv)->AlphaMemoryTable[hashValue]; if (theAlphaMemory->next != NULL) { theAlphaMemory->next->prev = theAlphaMemory; } theAlphaMemory->prev = NULL; DefruleData(theEnv)->AlphaMemoryTable[hashValue] = theAlphaMemory; if (theHeader->firstHash == NULL) { theHeader->firstHash = theAlphaMemory; theHeader->lastHash = theAlphaMemory; theAlphaMemory->prevHash = NULL; } else { theHeader->lastHash->nextHash = theAlphaMemory; theAlphaMemory->prevHash = theHeader->lastHash; theHeader->lastHash = theAlphaMemory; } } /*====================================*/ /* Store the alpha match in the alpha */ /* memory of the pattern node. */ /*====================================*/ theMatch->prevInMemory = theAlphaMemory->endOfQueue; if (theAlphaMemory->endOfQueue == NULL) { theAlphaMemory->alphaMemory = theMatch; theAlphaMemory->endOfQueue = theMatch; } else { theAlphaMemory->endOfQueue->nextInMemory = theMatch; theAlphaMemory->endOfQueue = theMatch; } /*===================================================*/ /* Return a pointer to the newly create alpha match. */ /*===================================================*/ return(theMatch); } /*******************************************//* CopyMultifieldMarkers: Copies a list of *//* multifieldMarker data structures. *//*******************************************/struct multifieldMarker *CopyMultifieldMarkers( void *theEnv, struct multifieldMarker *theMarkers) { struct multifieldMarker *head = NULL, *lastMark = NULL, *newMark; while (theMarkers != NULL) { newMark = get_struct(theEnv,multifieldMarker); newMark->next = NULL; newMark->whichField = theMarkers->whichField; newMark->where = theMarkers->where; newMark->startPosition = theMarkers->startPosition; newMark->endPosition = theMarkers->endPosition; if (lastMark == NULL) { head = newMark; } else { lastMark->next = newMark; } lastMark = newMark; theMarkers = theMarkers->next; } return(head); }/***************************************************************//* FlushAlphaBetaMemory: Returns all partial matches in a list *//* of partial matches either directly to the pool of free *//* memory or to the list of GarbagePartialMatches. Partial *//* matches stored in alpha memories must be placed on the *//* list of GarbagePartialMatches. *//***************************************************************/globle void FlushAlphaBetaMemory( void *theEnv, struct partialMatch *pfl) { struct partialMatch *pfltemp; while (pfl != NULL) { pfltemp = pfl->nextInMemory; UnlinkBetaPartialMatchfromAlphaAndBetaLineage(pfl); ReturnPartialMatch(theEnv,pfl); pfl = pfltemp; } }/*****************************************************************//* DestroyAlphaBetaMemory: Returns all partial matches in a list *//* of partial matches directly to the pool of free memory. *//*****************************************************************/globle void DestroyAlphaBetaMemory( void *theEnv, struct partialMatch *pfl) { struct partialMatch *pfltemp; while (pfl != NULL) { pfltemp = pfl->nextInMemory; DestroyPartialMatch(theEnv,pfl); pfl = pfltemp; } }/******************************************************//* FindEntityInPartialMatch: Searches for a specified *//* data entity in a partial match. *//******************************************************/globle int FindEntityInPartialMatch( struct patternEntity *theEntity,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -