Example #1
0
globle void PNLDrive(
  void *theEnv,
  struct joinNode *join,
  struct partialMatch *binds)
  {
   struct joinNode *listOfJoins;
   struct alphaMatch *tempAlpha;

    /*=======================================================*/
    /* Create a pseudo-fact representing the facts which did */
    /* not match the not CE associated with this join.       */
    /*=======================================================*/

    tempAlpha = get_struct(theEnv,alphaMatch);
    tempAlpha->next = NULL;
    tempAlpha->matchingItem = NULL;
    tempAlpha->markers = NULL;

    /*===============================================*/
    /* Store the pointer to the pseudo-fact directly */
    /* in the beta memory partial match.             */
    /*===============================================*/

    binds->counterf = FALSE;
    binds->binds[binds->bcount - 1].gm.theMatch = tempAlpha;

   /*====================================================*/
   /* Activate the rule satisfied by this partial match. */
   /*====================================================*/

   if (join->ruleToActivate != NULL) AddActivation(theEnv,join->ruleToActivate,binds);

    /*========================================================*/
    /* Send the merged partial match to all descendent joins. */
    /*========================================================*/

    listOfJoins = join->nextLevel;
    if (listOfJoins != NULL)
      {
       if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == join)
         { NetworkAssert(theEnv,binds,listOfJoins,RHS); }
       else while (listOfJoins != NULL)
         {
          NetworkAssert(theEnv,binds,listOfJoins,LHS);
          listOfJoins = listOfJoins->rightDriveNode;
         }
      }
   }
Example #2
0
static void PPDrive(
  void *theEnv,
  struct partialMatch *lhsBinds,
  struct partialMatch *rhsBinds,
  struct joinNode *join)
  {
   struct partialMatch *linker;
   struct joinNode *listOfJoins;
   
   /*==================================================*/
   /* Merge the alpha and beta memory partial matches. */
   /*==================================================*/

   linker = MergePartialMatches(theEnv,lhsBinds,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(theEnv,join->ruleToActivate,linker);

   /*================================================*/
   /* Send the new partial match to all child joins. */
   /*================================================*/

   listOfJoins = join->nextLevel;
   if (listOfJoins != NULL)
     {
      if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == join)
        { NetworkAssert(theEnv,linker,listOfJoins,RHS); }
      else while (listOfJoins != NULL)
        {
         NetworkAssert(theEnv,linker,listOfJoins,LHS);
         listOfJoins = listOfJoins->rightDriveNode;
        }
     }

   return;
  }
Example #3
0
static void ResetDefrulesPrime(
  void *theEnv)
  {
   struct joinLink *theLink;
   struct partialMatch *notParent;
      
   for (theLink = DefruleData(theEnv)->RightPrimeJoins;
        theLink != NULL;
        theLink = theLink->next)
     { NetworkAssert(theEnv,theLink->join->rightMemory->beta[0],theLink->join); }

   for (theLink = DefruleData(theEnv)->LeftPrimeJoins;
        theLink != NULL;
        theLink = theLink->next)
     { 
      if ((theLink->join->patternIsNegated || theLink->join->joinFromTheRight) && 
          (! theLink->join->patternIsExists))
        {
         notParent = theLink->join->leftMemory->beta[0];

         if (theLink->join->secondaryNetworkTest != NULL)
           {
            if (EvaluateSecondaryNetworkTest(theEnv,notParent,theLink->join) == FALSE)
              { continue; }
           }

         notParent->marker = NULL;

         EPMDrive(theEnv,notParent,theLink->join);
        }
     }

  }
Example #4
0
static void ProcessFactAlphaMatch(
  void *theEnv,
  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(theEnv,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(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,RHS); }
  }
static void PrimeJoin(
  void *theEnv,
  struct joinNode *joinPtr)
  {
   struct partialMatch *theList;
   
   /*===========================================================*/
   /* 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)
     {
      for (theList = ((struct patternNodeHeader *) joinPtr->rightSideEntryStructure)->alphaMemory;
           theList != NULL;
           theList = theList->next)
        { NetworkAssert(theEnv,theList,joinPtr,RHS); }
      return;
     }

   /*======================================================*/
   /* If the join already has partial matches in its beta  */
   /* memory, then don't bother priming it. I don't recall */
   /* if this situation is possible.                       */
   /*======================================================*/

   if (joinPtr->beta != NULL) return;

   /*================================================================*/
   /* Send all partial matches from the preceding join to this join. */
   /*================================================================*/

   for (theList = joinPtr->lastLevel->beta;
        theList != NULL;
        theList = theList->next)
     {
      if (! theList->counterf) /* 6.05 incremental reset bug fix */
        { NetworkAssert(theEnv,theList,joinPtr,LHS); }
     }
  }
Example #6
0
static void DriveRetractions()
  {
   struct rdriveinfo *tempDR;
   struct joinNode *joinPtr;

   while (DriveRetractionList != NULL)
     {
      for (joinPtr = DriveRetractionList->jlist;
           joinPtr != NULL;
           joinPtr = joinPtr->rightDriveNode)
        { NetworkAssert(DriveRetractionList->link,joinPtr,LHS); }

      tempDR = DriveRetractionList->next;
      rtn_struct(rdriveinfo,DriveRetractionList);
      DriveRetractionList = tempDR;
     }
  }
Example #7
0
static void DriveRetractions(
  void *theEnv)
  {
   struct rdriveinfo *tempDR;
   struct joinNode *joinPtr;

   while (EngineData(theEnv)->DriveRetractionList != NULL)
     {
      for (joinPtr = EngineData(theEnv)->DriveRetractionList->jlist;
           joinPtr != NULL;
           joinPtr = joinPtr->rightDriveNode)
        { NetworkAssert(theEnv,EngineData(theEnv)->DriveRetractionList->link,joinPtr,LHS); }

      tempDR = EngineData(theEnv)->DriveRetractionList->next;
      rtn_struct(theEnv,rdriveinfo,EngineData(theEnv)->DriveRetractionList);
      EngineData(theEnv)->DriveRetractionList = tempDR;
     }
  }
Example #8
0
void NegEntryRetract(
  struct joinNode *theJoin,
  struct partialMatch *theMatch,
  int duringRetract)
  {
   struct partialMatch *theLHS;
   int result;
   struct rdriveinfo *tempDR;
   struct alphaMatch *tempAlpha;
   struct joinNode *listOfJoins;

   /*===============================================*/
   /* Loop through all LHS partial matches checking */
   /* for sets that satisfied the join expression.  */
   /*===============================================*/

   for (theLHS = theJoin->beta; theLHS != NULL; theLHS = theLHS->next)
     {
      /*===========================================================*/
      /* Don't bother checking partial matches that are satisfied. */
      /* We're looking for joins from which the removal of a       */
      /* partial match would satisfy the join.                     */
      /*===========================================================*/

      if (theLHS->counterf == FALSE) continue;

      /*==================================================*/
      /* If the partial match being removed isn't the one */
      /* preventing the LHS partial match from being      */
      /* satisifed, then don't bother processing it.      */
      /*==================================================*/

      if (theLHS->binds[theLHS->bcount - 1].gm.theValue != (void *) theMatch) continue;

      /*======================================================*/
      /* Try to find another RHS partial match which prevents */
      /* the LHS partial match from being satisifed.          */
      /*======================================================*/

      theLHS->binds[theLHS->bcount - 1].gm.theValue = NULL;
      result = FindNextConflictingAlphaMatch(theLHS,theMatch->next,theJoin);

      /*=========================================================*/
      /* If the LHS partial match now has no RHS partial matches */
      /* that conflict with it, then it satisfies the conditions */
      /* of the RHS not CE. Create a partial match and send it   */
      /* to the joins below.                                     */
      /*=========================================================*/

      if (result == FALSE)
        {
         /*===============================*/
         /* Create the new partial match. */
         /*===============================*/

         theLHS->counterf = FALSE;
         tempAlpha = get_struct(alphaMatch);
         tempAlpha->next = NULL;
         tempAlpha->matchingItem = NULL;
         tempAlpha->markers = NULL;
         theLHS->binds[theLHS->bcount - 1].gm.theMatch = tempAlpha;

         /*==============================================*/
         /* If partial matches from this join correspond */
         /* to a rule activation, then add an activation */
         /* to the agenda.                               */
         /*==============================================*/

         if (theJoin->ruleToActivate != NULL)
           { AddActivation(theJoin->ruleToActivate,theLHS); }

         /*=======================================================*/
         /* Send the partial match to the list of joins following */
         /* this join. If we're in the middle of a retract, add   */
         /* the partial match to the list of join activities that */
         /* need to be processed later. If we're doing an assert, */
         /* then the join activity can be processed immediately.  */
         /*=======================================================*/

         listOfJoins = theJoin->nextLevel;
         if (listOfJoins != NULL)
           {
            if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == theJoin)
              { NetworkAssert(theLHS,listOfJoins,RHS); }
            else
              {
               if (duringRetract)
                 {
                  tempDR = get_struct(rdriveinfo);
                  tempDR->link = theLHS;
                  tempDR->jlist = theJoin->nextLevel;
                  tempDR->next = DriveRetractionList;
                  DriveRetractionList = tempDR;
                 }
               else while (listOfJoins != NULL)
                 {
                  NetworkAssert(theLHS,listOfJoins,LHS);
                  listOfJoins = listOfJoins->rightDriveNode;
                 }
              }
           }
        }
     }
  }
Example #9
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);
     }
  }
Example #10
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);
        }
     }
  }
Example #11
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;
     }
  }