Ejemplo n.º 1
0
globle void EPMDrive(
  void *theEnv,
  struct partialMatch *parent,
  struct joinNode *join)
  {
   struct partialMatch *linker;
   struct joinLink *listOfJoins;
   
   listOfJoins = join->nextLinks;
   if (listOfJoins == NULL) return;
         
   while (listOfJoins != NULL)
     {
      linker = CreateEmptyPartialMatch(theEnv);
         
      UpdateBetaPMLinks(theEnv,linker,parent,NULL,listOfJoins->join,0,listOfJoins->enterDirection); 

      if (listOfJoins->enterDirection == LHS)
        { NetworkAssertLeft(theEnv,linker,listOfJoins->join); }
      else
        { NetworkAssertRight(theEnv,linker,listOfJoins->join); }
        
      listOfJoins = listOfJoins->next;
     }
  }
Ejemplo n.º 2
0
static struct joinNode *CreateNewJoin(
  void *theEnv,
  struct expr *joinTest,
  struct expr *secondaryJoinTest,
  struct joinNode *lhsEntryStruct,
  void *rhsEntryStruct,
  int joinFromTheRight,
  int negatedRHSPattern,
  int existsRHSPattern,
  struct expr *leftHash,
  struct expr *rightHash)
  {
   struct joinNode *newJoin;
   struct joinLink *theLink;
   
   /*===============================================*/
   /* If compilations are being watch, print +j to  */
   /* indicate that a new join has been created for */
   /* this pattern of the rule (i.e. a join could   */
   /* not be shared with another rule.              */
   /*===============================================*/

#if DEBUGGING_FUNCTIONS
   if ((EnvGetWatchItem(theEnv,(char*)"compilations") == TRUE) && GetPrintWhileLoading(theEnv))
     { EnvPrintRouter(theEnv,WDIALOG,(char*)"+j"); }
#endif

   /*======================*/
   /* Create the new join. */
   /*======================*/

   newJoin = get_struct(theEnv,joinNode);
   
   /*======================================================*/
   /* The first join of a rule does not have a beta memory */
   /* unless the RHS pattern is an exists or not CE.       */
   /*======================================================*/
   
   if ((lhsEntryStruct != NULL) || existsRHSPattern || negatedRHSPattern || joinFromTheRight)
     {
      if (leftHash == NULL)     
        {      
         newJoin->leftMemory = get_struct(theEnv,betaMemory); 
         newJoin->leftMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
         newJoin->leftMemory->beta[0] = NULL;
         newJoin->leftMemory->last = NULL;
         newJoin->leftMemory->size = 1;
         newJoin->leftMemory->count = 0;
         }
      else
        {
         newJoin->leftMemory = get_struct(theEnv,betaMemory); 
         newJoin->leftMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         memset(newJoin->leftMemory->beta,0,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         newJoin->leftMemory->last = NULL;
         newJoin->leftMemory->size = INITIAL_BETA_HASH_SIZE;
         newJoin->leftMemory->count = 0;
        }
      
      /*===========================================================*/
      /* If the first join of a rule connects to an exists or not  */
      /* CE, then we create an empty partial match for the usually */
      /* empty left beta memory so that we can track the current   */
      /* current right memory partial match satisfying the CE.     */
      /*===========================================================*/
         
      if ((lhsEntryStruct == NULL) && (existsRHSPattern || negatedRHSPattern || joinFromTheRight))
        {
         newJoin->leftMemory->beta[0] = CreateEmptyPartialMatch(theEnv); 
         newJoin->leftMemory->beta[0]->owner = newJoin;
         newJoin->leftMemory->count = 1;
        }
     }
   else
     { newJoin->leftMemory = NULL; }
     
   if (joinFromTheRight)
     {
      if (leftHash == NULL)     
        {      
         newJoin->rightMemory = get_struct(theEnv,betaMemory); 
         newJoin->rightMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
         newJoin->rightMemory->last = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
         newJoin->rightMemory->beta[0] = NULL;
         newJoin->rightMemory->last[0] = NULL;
         newJoin->rightMemory->size = 1;
         newJoin->rightMemory->count = 0;
         }
      else
        {
         newJoin->rightMemory = get_struct(theEnv,betaMemory); 
         newJoin->rightMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         newJoin->rightMemory->last = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         memset(newJoin->rightMemory->beta,0,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         memset(newJoin->rightMemory->last,0,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         newJoin->rightMemory->size = INITIAL_BETA_HASH_SIZE;
         newJoin->rightMemory->count = 0;
        }     
     }
   else if ((lhsEntryStruct == NULL) && (rhsEntryStruct == NULL))
     {
      newJoin->rightMemory = get_struct(theEnv,betaMemory); 
      newJoin->rightMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
      newJoin->rightMemory->last = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
      newJoin->rightMemory->beta[0] = CreateEmptyPartialMatch(theEnv);
      newJoin->rightMemory->beta[0]->owner = newJoin;
      newJoin->rightMemory->beta[0]->rhsMemory = TRUE;
      newJoin->rightMemory->last[0] = newJoin->rightMemory->beta[0];
      newJoin->rightMemory->size = 1;
      newJoin->rightMemory->count = 1;    
     }
   else
     { newJoin->rightMemory = NULL; }
     
   newJoin->nextLinks = NULL;
   newJoin->joinFromTheRight = joinFromTheRight;
   
   if (existsRHSPattern)
     { newJoin->patternIsNegated = FALSE; }
   else
     { newJoin->patternIsNegated = negatedRHSPattern; }
   newJoin->patternIsExists = existsRHSPattern;

   newJoin->marked = FALSE;
   newJoin->initialize = EnvGetIncrementalReset(theEnv);
   newJoin->logicalJoin = FALSE;
   newJoin->ruleToActivate = NULL;
   newJoin->memoryAdds = 0;
   newJoin->memoryDeletes = 0;
   newJoin->memoryCompares = 0;

   /*==============================================*/
   /* Install the expressions used to determine    */
   /* if a partial match satisfies the constraints */
   /* associated with this join.                   */
   /*==============================================*/

   newJoin->networkTest = AddHashedExpression(theEnv,joinTest);
   newJoin->secondaryNetworkTest = AddHashedExpression(theEnv,secondaryJoinTest);
   
   /*=====================================================*/
   /* Install the expression used to hash the beta memory */
   /* partial match to determine the location to search   */
   /* in the alpha memory.                                */
   /*=====================================================*/
   
   newJoin->leftHash = AddHashedExpression(theEnv,leftHash);
   newJoin->rightHash = AddHashedExpression(theEnv,rightHash);

   /*============================================================*/
   /* Initialize the values associated with the LHS of the join. */
   /*============================================================*/

   newJoin->lastLevel = lhsEntryStruct;

   if (lhsEntryStruct == NULL)
     {
      newJoin->firstJoin = TRUE;
      newJoin->depth = 1;
     }
   else
     {
      newJoin->firstJoin = FALSE;
      newJoin->depth = lhsEntryStruct->depth;
      newJoin->depth++; /* To work around Sparcworks C compiler bug */
      
      theLink = get_struct(theEnv,joinLink);
      theLink->join = newJoin;
      theLink->enterDirection = LHS;
      theLink->next = lhsEntryStruct->nextLinks;
      lhsEntryStruct->nextLinks = theLink;
     }

   /*=======================================================*/
   /* Initialize the pointer values associated with the RHS */
   /* of the join (both for the new join and the join or    */
   /* pattern which enters this join from the right.        */
   /*=======================================================*/

   newJoin->rightSideEntryStructure = rhsEntryStruct;
   
   if (rhsEntryStruct == NULL)
     { 
      if (newJoin->firstJoin)
        {
         theLink = get_struct(theEnv,joinLink);
         theLink->join = newJoin;
         theLink->enterDirection = RHS;
         theLink->next = DefruleData(theEnv)->RightPrimeJoins;
         DefruleData(theEnv)->RightPrimeJoins = theLink;
        }
        
      newJoin->rightMatchNode = NULL;
        
      return(newJoin); 
     }
     
   /*===========================================================*/
   /* If the first join of a rule is a not CE, then it needs to */
   /* be "primed" under certain circumstances. This used to be  */
   /* handled by adding the (initial-fact) pattern to a rule    */
   /* with the not CE as its first pattern, but this alternate  */
   /* mechanism is now used so patterns don't have to be added. */
   /*===========================================================*/
     
   if (newJoin->firstJoin && (newJoin->patternIsNegated || newJoin->joinFromTheRight) && (! newJoin->patternIsExists))
     {
      theLink = get_struct(theEnv,joinLink);
      theLink->join = newJoin;
      theLink->enterDirection = LHS;
      theLink->next = DefruleData(theEnv)->LeftPrimeJoins;
      DefruleData(theEnv)->LeftPrimeJoins = theLink;
     }
       
   if (joinFromTheRight)
     {
      theLink = get_struct(theEnv,joinLink);
      theLink->join = newJoin;
      theLink->enterDirection = RHS;
      theLink->next = ((struct joinNode *) rhsEntryStruct)->nextLinks;
      ((struct joinNode *) rhsEntryStruct)->nextLinks = theLink;
      newJoin->rightMatchNode = NULL;
     }
   else
     {
      newJoin->rightMatchNode = ((struct patternNodeHeader *) rhsEntryStruct)->entryJoin;
      ((struct patternNodeHeader *) rhsEntryStruct)->entryJoin = newJoin;
     }

   /*================================*/
   /* Return the newly created join. */
   /*================================*/

   return(newJoin);
  }
Ejemplo n.º 3
0
globle void AddBetaMemoriesToJoin(
  void *theEnv,
  struct joinNode *theNode)
  {   
   if ((theNode->leftMemory != NULL) || (theNode->rightMemory != NULL))
     { return; }

   //if ((! theNode->firstJoin) || theNode->patternIsExists)

   if ((! theNode->firstJoin) || theNode->patternIsExists || theNode-> patternIsNegated || theNode->joinFromTheRight)
     {
      if (theNode->leftHash == NULL)
        {
         theNode->leftMemory = get_struct(theEnv,betaMemory); 
         theNode->leftMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
         theNode->leftMemory->beta[0] = NULL;
         theNode->leftMemory->size = 1;
         theNode->leftMemory->count = 0;
         theNode->leftMemory->last = NULL;
        }
      else
        {
         theNode->leftMemory = get_struct(theEnv,betaMemory); 
         theNode->leftMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         memset(theNode->leftMemory->beta,0,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         theNode->leftMemory->size = INITIAL_BETA_HASH_SIZE;
         theNode->leftMemory->count = 0;
         theNode->leftMemory->last = NULL;
        }

 //     if (theNode->firstJoin && theNode->patternIsExists)
      if (theNode->firstJoin && (theNode->patternIsExists || theNode-> patternIsNegated || theNode->joinFromTheRight))
        {
         theNode->leftMemory->beta[0] = CreateEmptyPartialMatch(theEnv); 
         theNode->leftMemory->beta[0]->owner = theNode;
        }
     }
   else
     { theNode->leftMemory = NULL; }

   if (theNode->joinFromTheRight)
     {
      if (theNode->leftHash == NULL)
        {
         theNode->rightMemory = get_struct(theEnv,betaMemory); 
         theNode->rightMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
         theNode->rightMemory->last = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
         theNode->rightMemory->beta[0] = NULL;
         theNode->rightMemory->last[0] = NULL;
         theNode->rightMemory->size = 1;
         theNode->rightMemory->count = 0;
        }
      else
        {
         theNode->rightMemory = get_struct(theEnv,betaMemory); 
         theNode->rightMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         theNode->rightMemory->last = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * INITIAL_BETA_HASH_SIZE);
         memset(theNode->rightMemory->beta,0,sizeof(struct partialMatch **) * INITIAL_BETA_HASH_SIZE);
         memset(theNode->rightMemory->last,0,sizeof(struct partialMatch **) * INITIAL_BETA_HASH_SIZE);
         theNode->rightMemory->size = INITIAL_BETA_HASH_SIZE;
         theNode->rightMemory->count = 0;
        }
     }

   else if (theNode->firstJoin && (theNode->rightSideEntryStructure == NULL))
     {
      theNode->rightMemory = get_struct(theEnv,betaMemory); 
      theNode->rightMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
      theNode->rightMemory->last = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *));
      theNode->rightMemory->beta[0] = CreateEmptyPartialMatch(theEnv);
      theNode->rightMemory->beta[0]->owner = theNode;
      theNode->rightMemory->beta[0]->rhsMemory = TRUE;
      theNode->rightMemory->last[0] = theNode->rightMemory->beta[0];
      theNode->rightMemory->size = 1;
      theNode->rightMemory->count = 1;    
     }

   else
     { theNode->rightMemory = NULL; }
  }
Ejemplo n.º 4
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;
     }
  }