static struct partialMatch *SortPartialMatch( void *theEnv, struct partialMatch *binds) { struct partialMatch *nbinds; struct alphaMatch *temp; int flag, j, k; /*=================*/ /* Copy the array. */ /*=================*/ nbinds = CopyPartialMatch(theEnv,binds,0,0); /*=================*/ /* Sort the array. */ /*=================*/ for (flag = TRUE, k = binds->bcount - 1; flag == TRUE; k--) { flag = FALSE; for (j = 0 ; j < k ; j++) { if ((nbinds->binds[j].gm.theMatch->matchingItem != NULL) && (nbinds->binds[j + 1].gm.theMatch->matchingItem != NULL)) { if (nbinds->binds[j].gm.theMatch->matchingItem->timeTag < nbinds->binds[j + 1].gm.theMatch->matchingItem->timeTag) { temp = nbinds->binds[j].gm.theMatch; nbinds->binds[j].gm.theMatch = nbinds->binds[j+1].gm.theMatch; nbinds->binds[j+1].gm.theMatch = temp; flag = TRUE; } } } } /*===================*/ /* Return the array. */ /*===================*/ return(nbinds); }
static void PrimeJoinFromRightMemory( void *theEnv, struct joinNode *joinPtr) { struct partialMatch *theList, *linker; unsigned long b; struct betaMemory *theMemory; unsigned long hashValue; struct joinLink *tempLink; struct partialMatch *notParent; /*=======================================*/ /* This should be a join from the right. */ /*=======================================*/ if (joinPtr->joinFromTheRight == FALSE) { return; } /*========================================*/ /* Find another beta memory from which we */ /* can retrieve the partial matches. */ /*========================================*/ tempLink = ((struct joinNode *) joinPtr->rightSideEntryStructure)->nextLinks; while (tempLink != NULL) { if ((tempLink->join != joinPtr) && (tempLink->join->initialize == FALSE)) { break; } tempLink = tempLink->next; } if (tempLink == NULL) { if (joinPtr->firstJoin && (joinPtr->rightMemory->beta[0] == NULL) && (! joinPtr->patternIsExists)) { notParent = joinPtr->leftMemory->beta[0]; if (joinPtr->secondaryNetworkTest != NULL) { if (EvaluateSecondaryNetworkTest(theEnv,notParent,joinPtr) == FALSE) { return; } } EPMDrive(theEnv,notParent,joinPtr); } return; } if (tempLink->enterDirection == LHS) { theMemory = tempLink->join->leftMemory; } else { theMemory = tempLink->join->rightMemory; } /*============================================*/ /* Send all partial matches from the selected */ /* beta memory to the new join. */ /*============================================*/ for (b = 0; b < theMemory->size; b++) { for (theList = theMemory->beta[b]; theList != NULL; theList = theList->nextInMemory) { linker = CopyPartialMatch(theEnv,theList); if (joinPtr->rightHash != NULL) { hashValue = BetaMemoryHashValue(theEnv,joinPtr->rightHash,linker,NULL,joinPtr); } else { hashValue = 0; } UpdateBetaPMLinks(theEnv,linker,theList->leftParent,theList->rightParent,joinPtr,hashValue,RHS); NetworkAssert(theEnv,linker,joinPtr); } } if (joinPtr->firstJoin && (joinPtr->rightMemory->beta[0] == NULL) && (! joinPtr->patternIsExists)) { notParent = joinPtr->leftMemory->beta[0]; if (joinPtr->secondaryNetworkTest != NULL) { if (EvaluateSecondaryNetworkTest(theEnv,notParent,joinPtr) == FALSE) { return; } } EPMDrive(theEnv,notParent,joinPtr); } }
static void EmptyDrive( struct joinNode *join, struct partialMatch *rhsBinds) { struct partialMatch *linker; struct joinNode *listOfJoins; int joinExpr; /*======================================================*/ /* Determine if the alpha memory partial match satifies */ /* the join expression. If it doesn't then no further */ /* action is taken. */ /*======================================================*/ if (join->networkTest != NULL) { joinExpr = EvaluateJoinExpression(join->networkTest,NULL,rhsBinds,join); EvaluationError = FALSE; if (joinExpr == FALSE) return; } /*===========================================================*/ /* The first join of a rule cannot be connected to a NOT CE. */ /*===========================================================*/ if (join->patternIsNegated == TRUE) { SystemError("DRIVE",2); ExitRouter(EXIT_FAILURE); } /*=========================================================*/ /* If the join's RHS entry is associated with a pattern CE */ /* (positive entry), then copy the alpha memory partial */ /* match and send it to all child joins. */ /*=========================================================*/ linker = CopyPartialMatch(rhsBinds, (join->ruleToActivate == NULL) ? 0 : 1, (int) join->logicalJoin); /*=======================================================*/ /* Add the partial match to the beta memory of the join. */ /*=======================================================*/ linker->next = join->beta; join->beta = linker; /*====================================================*/ /* Activate the rule satisfied by this partial match. */ /*====================================================*/ if (join->ruleToActivate != NULL) AddActivation(join->ruleToActivate,linker); /*============================================*/ /* Send the partial match to all child joins. */ /*============================================*/ listOfJoins = join->nextLevel; while (listOfJoins != NULL) { NetworkAssert(linker,listOfJoins,LHS); listOfJoins = listOfJoins->rightDriveNode; } }
static void PrimeJoinFromLeftMemory( void *theEnv, struct joinNode *joinPtr) { struct partialMatch *theList, *linker; struct alphaMemoryHash *listOfHashNodes; unsigned long b; unsigned long hashValue; struct betaMemory *theMemory; struct partialMatch *notParent; struct joinLink *tempLink; /*===========================================================*/ /* If the join is the first join of a rule, then send all of */ /* the partial matches from the alpha memory of the pattern */ /* associated with this join to the join for processing and */ /* the priming process is then complete. */ /*===========================================================*/ if (joinPtr->firstJoin == TRUE) { if (joinPtr->rightSideEntryStructure == NULL) { NetworkAssert(theEnv,joinPtr->rightMemory->beta[0],joinPtr); } else if (joinPtr->patternIsNegated) { notParent = joinPtr->leftMemory->beta[0]; if (joinPtr->secondaryNetworkTest != NULL) { if (EvaluateSecondaryNetworkTest(theEnv,notParent,joinPtr) == FALSE) { return; } } for (listOfHashNodes = ((struct patternNodeHeader *) joinPtr->rightSideEntryStructure)->firstHash; listOfHashNodes != NULL; listOfHashNodes = listOfHashNodes->nextHash) { if (listOfHashNodes->alphaMemory != NULL) { AddBlockedLink(notParent,listOfHashNodes->alphaMemory); return; } } EPMDrive(theEnv,notParent,joinPtr); } else { for (listOfHashNodes = ((struct patternNodeHeader *) joinPtr->rightSideEntryStructure)->firstHash; listOfHashNodes != NULL; listOfHashNodes = listOfHashNodes->nextHash) { for (theList = listOfHashNodes->alphaMemory; theList != NULL; theList = theList->nextInMemory) { NetworkAssert(theEnv,theList,joinPtr); } } } return; } /*========================================*/ /* Find another beta memory from which we */ /* can retrieve the partial matches. */ /*========================================*/ tempLink = joinPtr->lastLevel->nextLinks; while (tempLink != NULL) { if ((tempLink->join != joinPtr) && (tempLink->join->initialize == FALSE)) { break; } tempLink = tempLink->next; } if (tempLink == NULL) return; if (tempLink->enterDirection == LHS) { theMemory = tempLink->join->leftMemory; } else { theMemory = tempLink->join->rightMemory; } /*============================================*/ /* Send all partial matches from the selected */ /* beta memory to the new join. */ /*============================================*/ for (b = 0; b < theMemory->size; b++) { for (theList = theMemory->beta[b]; theList != NULL; theList = theList->nextInMemory) { linker = CopyPartialMatch(theEnv,theList); if (joinPtr->leftHash != NULL) { hashValue = BetaMemoryHashValue(theEnv,joinPtr->leftHash,linker,NULL,joinPtr); } else { hashValue = 0; } UpdateBetaPMLinks(theEnv,linker,theList->leftParent,theList->rightParent,joinPtr,hashValue,LHS); NetworkAssertLeft(theEnv,linker,joinPtr); } } }
static void EmptyDrive( void *theEnv, struct joinNode *join, struct partialMatch *rhsBinds) { struct partialMatch *linker, *existsParent = NULL, *notParent; struct joinLink *listOfJoins; int joinExpr; unsigned long hashValue; struct partialMatch *oldLHSBinds; struct partialMatch *oldRHSBinds; struct joinNode *oldJoin; /*======================================================*/ /* Determine if the alpha memory partial match satifies */ /* the join expression. If it doesn't then no further */ /* action is taken. */ /*======================================================*/ join->memoryCompares++; if (join->networkTest != NULL) { #if DEVELOPER EngineData(theEnv)->rightToLeftComparisons++; #endif oldLHSBinds = EngineData(theEnv)->GlobalLHSBinds; oldRHSBinds = EngineData(theEnv)->GlobalRHSBinds; oldJoin = EngineData(theEnv)->GlobalJoin; EngineData(theEnv)->GlobalLHSBinds = NULL; EngineData(theEnv)->GlobalRHSBinds = rhsBinds; EngineData(theEnv)->GlobalJoin = join; joinExpr = EvaluateJoinExpression(theEnv,join->networkTest,join); EvaluationData(theEnv)->EvaluationError = FALSE; EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds; EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds; EngineData(theEnv)->GlobalJoin = oldJoin; if (joinExpr == FALSE) return; } if (join->secondaryNetworkTest != NULL) { #if DEVELOPER EngineData(theEnv)->rightToLeftComparisons++; #endif oldLHSBinds = EngineData(theEnv)->GlobalLHSBinds; oldRHSBinds = EngineData(theEnv)->GlobalRHSBinds; oldJoin = EngineData(theEnv)->GlobalJoin; EngineData(theEnv)->GlobalLHSBinds = NULL; EngineData(theEnv)->GlobalRHSBinds = rhsBinds; EngineData(theEnv)->GlobalJoin = join; joinExpr = EvaluateJoinExpression(theEnv,join->secondaryNetworkTest,join); EvaluationData(theEnv)->EvaluationError = FALSE; EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds; EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds; EngineData(theEnv)->GlobalJoin = oldJoin; if (joinExpr == FALSE) return; } /*========================================================*/ /* Handle a negated first pattern or join from the right. */ /*========================================================*/ if (join->patternIsNegated || (join->joinFromTheRight && (! join->patternIsExists))) /* reorder to remove patternIsExists test */ { notParent = join->leftMemory->beta[0]; if (notParent->marker != NULL) { return; } AddBlockedLink(notParent,rhsBinds); if (notParent->children != NULL) { PosEntryRetractBeta(theEnv,notParent,notParent->children); } /* if (notParent->dependents != NULL) { RemoveLogicalSupport(theEnv,notParent); } */ return; } /*=====================================================*/ /* For exists CEs used as the first pattern of a rule, */ /* a special partial match in the left memory of the */ /* join is used to track the RHS partial match */ /* satisfying the CE. */ /*=====================================================*/ /* TBD reorder */ if (join->patternIsExists) { existsParent = join->leftMemory->beta[0]; if (existsParent->marker != NULL) { return; } AddBlockedLink(existsParent,rhsBinds); } /*============================================*/ /* Send the partial match to all child joins. */ /*============================================*/ listOfJoins = join->nextLinks; if (listOfJoins == NULL) return; while (listOfJoins != NULL) { /*===================================================================*/ /* An exists CE as the first pattern of a rule can generate at most */ /* one partial match, so if there's already a partial match in the */ /* beta memory nothing further needs to be done. Since there are no */ /* variable bindings which child joins can use for indexing, the */ /* partial matches will always be stored in the bucket with index 0. */ /* Although an exists is associated with a specific fact/instance */ /* (through its rightParent link) that allows it to be satisfied, */ /* the bindings in the partial match will be empty for this CE. */ /*===================================================================*/ if (join->patternIsExists) { linker = CreateEmptyPartialMatch(theEnv); } /*=============================================================*/ /* Othewise just copy the partial match from the alpha memory. */ /*=============================================================*/ else { linker = CopyPartialMatch(theEnv,rhsBinds); } /*================================================*/ /* Determine the hash value of the partial match. */ /*================================================*/ if (listOfJoins->enterDirection == LHS) { if (listOfJoins->join->leftHash != NULL) { hashValue = BetaMemoryHashValue(theEnv,listOfJoins->join->leftHash,linker,NULL,listOfJoins->join); } else { hashValue = 0; } } else { if (listOfJoins->join->rightHash != NULL) { hashValue = BetaMemoryHashValue(theEnv,listOfJoins->join->rightHash,linker,NULL,listOfJoins->join); } else { hashValue = 0; } } /*=======================================================*/ /* Add the partial match to the beta memory of the join. */ /*=======================================================*/ if (join->patternIsExists) { UpdateBetaPMLinks(theEnv,linker,existsParent,NULL,listOfJoins->join,hashValue,listOfJoins->enterDirection); } else { UpdateBetaPMLinks(theEnv,linker,NULL,rhsBinds,listOfJoins->join,hashValue,listOfJoins->enterDirection); } if (listOfJoins->enterDirection == LHS) { NetworkAssertLeft(theEnv,linker,listOfJoins->join); } else { NetworkAssertRight(theEnv,linker,listOfJoins->join); } listOfJoins = listOfJoins->next; } }