예제 #1
0
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);
  }
예제 #2
0
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);
     }
  }
예제 #3
0
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;
     }
  }
예제 #4
0
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);
        }
     }
  }
예제 #5
0
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;
     }
  }