⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objrtmch.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 4 页
字号:
  NOTES        : None
 ***************************************************/
globle void ResetObjectMatchTimeTags(
  void *theEnv)
  {
   OBJECT_ALPHA_NODE *alphaPtr;
   OBJECT_PATTERN_NODE *lastLevel;

   /* ============================================
      If the current tag incremented by one would
      not cause an overflow, then we can leave
      things alone.
      ============================================ */
   if ((ObjectReteData(theEnv)->CurrentObjectMatchTimeTag + 1L) > ObjectReteData(theEnv)->CurrentObjectMatchTimeTag)
     return;
   ObjectReteData(theEnv)->CurrentObjectMatchTimeTag = 0L;
   alphaPtr = ObjectNetworkTerminalPointer(theEnv);
   while (alphaPtr != NULL)
     {
      alphaPtr->matchTimeTag = 0L;
      lastLevel = alphaPtr->patternNode;
      while (lastLevel != NULL)
        {
         if (lastLevel->matchTimeTag == 0L)
           break;
         lastLevel->matchTimeTag = 0L;
         lastLevel = lastLevel->lastLevel;
        }
      alphaPtr = alphaPtr->nxtTerminal;
     }
  }

/***************************************************
  NAME         : QueueObjectMatchAction
  DESCRIPTION  : Posts a Rete network match event
                 for later processing
  INPUTS       : 1) The match action type
                    OBJECT_ASSERT  (1)
                    OBJECT_RETRACT (2)
                    OBJECT_MODIFY  (3)
                 2) The instance to be matched
                 3) The name id of the slot being
                    updated (can be -1)
  RETURNS      : Nothing useful
  SIDE EFFECTS : Queue updated
  NOTES        : None
 ***************************************************/
static void QueueObjectMatchAction(
  void *theEnv,
  int type,
  INSTANCE_TYPE *ins,
  int slotNameID)
  {
   OBJECT_MATCH_ACTION *prv,*cur,*newMatch;

   prv = NULL;
   cur = ObjectReteData(theEnv)->ObjectMatchActionQueue;
   while (cur != NULL)
     {
      /* ===========================================================
         Here are the possibilities for the first Rete event already
         on the queue as compared with the new event for an object:

         Assert/Retract  -->  Delete assert event
                              Ignore retract event
         Assert/Modify   -->  Ignore modify event
         Modify/Modify   -->  Merge new modify event
         Modify/Retract  -->  Delete modify event
                              Queue the retract event
         =========================================================== */
      if (cur->ins == ins)
        {
         /* ===================================================
            An action for initially asserting the newly created
            object to all applicable patterns
            =================================================== */
         if (cur->type == OBJECT_ASSERT)
           {
            if (type == OBJECT_RETRACT)
              {
               /* ===================================================
                  If we are retracting the entire object, then we can
                  remove the assert action (and all modifies as well)
                  and ignore the retract action
                  (basically the object came and went before the Rete
                  network had a chance to see it)
                  =================================================== */
               if (prv == NULL)
                 ObjectReteData(theEnv)->ObjectMatchActionQueue = cur->nxt;
               else
                 prv->nxt = cur->nxt;
               cur->ins->busy--;
               ReturnObjectMatchAction(theEnv,cur);
              }

            /* =================================================
               If this is a modify action, then we can ignore it
               since the assert action will encompass it
               ================================================= */
           }

         /* ===================================================
            If the object is being deleted after a slot modify,
            drop the modify event and replace with the retract
            =================================================== */
         else if (type == OBJECT_RETRACT)
           {
            cur->type = OBJECT_RETRACT;
            if (cur->slotNameIDs != NULL)
              {
               rm(theEnv,(void *) cur->slotNameIDs,SlotBitMapSize(cur->slotNameIDs));
               cur->slotNameIDs = NULL;
              }
           }

         /* ====================================================
            If a modify event for this slot is already on the
            queue, ignore this one. Otherwise, merge the slot id
            ==================================================== */
         else
            cur->slotNameIDs = QueueModifySlotMap(theEnv,cur->slotNameIDs,slotNameID);

         return;
        }
      prv = cur;
      cur = cur->nxt;
     }

   /* ================================================
      If there are no actions for the instance already
      on the queue, the new action is simply appended.
      ================================================ */
   newMatch = get_struct(theEnv,objectMatchAction);
   newMatch->type = type;
   newMatch->nxt = cur;
   newMatch->slotNameIDs = (type != OBJECT_MODIFY) ? NULL :
                       QueueModifySlotMap(theEnv,NULL,slotNameID);
   newMatch->ins = ins;
   newMatch->ins->busy++;
   if (prv == NULL)
     ObjectReteData(theEnv)->ObjectMatchActionQueue = newMatch;
   else
     prv->nxt = newMatch;
  }

/****************************************************
  NAME         : QueueModifySlotMap
  DESCRIPTION  : Sets the bitmap for a queued
                 object modify Rete network action
  INPUTS       : 1) The old bitmap (can be NULL)
                 2) The canonical slot id to set
  RETURNS      : The (new) bitmap
  SIDE EFFECTS : Bitmap allocated/reallocated if
                 necessary, and slot id bit set
  NOTES        : If the bitmap must be (re)allocated,
                 this routine allocates twice the
                 room necessary for the current id
                 to allow for growth.
 ****************************************************/
static SLOT_BITMAP *QueueModifySlotMap(
  void *theEnv,
  SLOT_BITMAP *oldMap,
  int slotNameID)
  {
   SLOT_BITMAP *newMap;
   unsigned short newmaxid;
   unsigned oldsz,newsz;

   if ((oldMap == NULL) ? TRUE : (slotNameID > oldMap->maxid))
     {
      newmaxid = (unsigned short) (slotNameID * 2);
      newsz = sizeof(SLOT_BITMAP) +
              (sizeof(char) * (newmaxid / BITS_PER_BYTE));
      newMap = (SLOT_BITMAP *) gm2(theEnv,newsz);
      ClearBitString((void *) newMap,newsz);
      if (oldMap != NULL)
        {
         oldsz = SlotBitMapSize(oldMap);
         GenCopyMemory(char,oldsz,newMap,oldMap);
         rm(theEnv,(void *) oldMap,oldsz);
        }
      newMap->maxid = newmaxid;
     }
   else
     newMap = oldMap;
   SetBitMap(newMap->map,slotNameID);
   return(newMap);
  }

/***************************************************
  NAME         : ReturnObjectMatchAction
  DESCRIPTION  : Deallocates and object match action
                 structure and associated slot
                 bitmap (if any)
  INPUTS       : The queued match action item
  RETURNS      : Nothing useful
  SIDE EFFECTS : Object match action item deleted
  NOTES        : None
 ***************************************************/
static void ReturnObjectMatchAction(
  void *theEnv,
  OBJECT_MATCH_ACTION *omaPtr)
  {
   if (omaPtr->slotNameIDs != NULL)
     rm(theEnv,(void *) omaPtr->slotNameIDs,SlotBitMapSize(omaPtr->slotNameIDs));
   rtn_struct(theEnv,objectMatchAction,omaPtr);
  }

/***************************************************
  NAME         : ProcessObjectMatchQueue
  DESCRIPTION  : Processes all outstanding object
                 Rete network update events
  INPUTS       : None
  RETURNS      : Nothing useful
  SIDE EFFECTS : Pattern-matching on objects
  NOTES        : None
 ***************************************************/
static void ProcessObjectMatchQueue(
  void *theEnv)
  {
   OBJECT_MATCH_ACTION *cur;

   while ((ObjectReteData(theEnv)->ObjectMatchActionQueue != NULL) &&
          (ObjectReteData(theEnv)->DelayObjectPatternMatching == FALSE))
     {
      cur = ObjectReteData(theEnv)->ObjectMatchActionQueue;
      ObjectReteData(theEnv)->ObjectMatchActionQueue = cur->nxt;

      switch(cur->type)
        {
         case OBJECT_ASSERT  :
           ObjectAssertAction(theEnv,cur->ins);
           break;
         case OBJECT_RETRACT :
           ObjectRetractAction(theEnv,cur->ins,cur->slotNameIDs);
           break;
         default             :
           ObjectModifyAction(theEnv,cur->ins,cur->slotNameIDs);
        }
      cur->ins->busy--;
      ReturnObjectMatchAction(theEnv,cur);
     }
  }

/******************************************************
  NAME         : MarkObjectPatternNetwork
  DESCRIPTION  : Iterates through all terminal
                 pattern nodes checking class and
                 slot bitmaps.  If a pattern is
                 applicable to the object/slot change,
                 then all the nodes belonging to
                 the pattern are marked as needing
                 to be examined by the pattern matcher.
  INPUTS       : The bitmap of ids of the slots being
                 changed (NULL if this is an assert for the
                  for the entire object)
  RETURNS      : Nothing useful
  SIDE EFFECTS : Applicable pattern nodes marked
  NOTES        : Incremental reset status is also
                 checked here
 ******************************************************/
static void MarkObjectPatternNetwork(
  void *theEnv,
  SLOT_BITMAP *slotNameIDs)
  {
   OBJECT_ALPHA_NODE *alphaPtr;
   OBJECT_PATTERN_NODE *upper;
   CLASS_BITMAP *clsset;
   unsigned id;

   ResetObjectMatchTimeTags(theEnv);
   ObjectReteData(theEnv)->CurrentObjectMatchTimeTag++;
   alphaPtr = ObjectNetworkTerminalPointer(theEnv);
   id = ObjectReteData(theEnv)->CurrentPatternObject->cls->id;
   while (alphaPtr != NULL)
     {
      /* =============================================================
         If an incremental reset is in progress, make sure that the
         pattern has been marked for initialization before proceeding.
         ============================================================= */
#if (! RUN_TIME) && (! BLOAD_ONLY)
      if (EngineData(theEnv)->IncrementalResetInProgress &&
          (alphaPtr->header.initialize == FALSE))
        {
         alphaPtr = alphaPtr->nxtTerminal;
         continue;
        }
#endif

      /* ============================================
         Check the class bitmap to see if the pattern
         pattern is applicable to the object at all
         ============================================ */
      clsset = (CLASS_BITMAP *) ValueToBitMap(alphaPtr->classbmp);

      if ((id > (unsigned) clsset->maxid) ? FALSE : TestBitMap(clsset->map,id))
        {
         /* ===================================================
            If we are doing an assert, then we need to
            check all patterns which satsify the class bitmap
            (The retraction has already been done in this case)
            =================================================== */
         if (slotNameIDs == NULL)
           {
            alphaPtr->matchTimeTag = ObjectReteData(theEnv)->CurrentObjectMatchTimeTag;
            for (upper = alphaPtr->patternNode ; upper != NULL ; upper = upper->lastLevel)
              {
               if (upper->matchTimeTag == ObjectReteData(theEnv)->CurrentObjectMatchTimeTag)
                 break;
               else
                 upper->matchTimeTag = ObjectReteData(theEnv)->CurrentObjectMatchTimeTag;
              }
           }

         /* ===================================================
            If we are doing a slot modify, then we need to
            check only the subset of patterns which satisfy the
            class bitmap AND actually match on the slot in
            question.
            =================================================== */
         else if (alphaPtr->slotbmp != NULL)
           {
           if (CompareSlotBitMaps(slotNameIDs,
                  (SLOT_BITMAP *) ValueToBitMap(alphaPtr->slotbmp)))
              {
               alphaPtr->matchTimeTag = ObjectReteData(theEnv)->CurrentObjectMatchTimeTag;
               for (upper = alphaPtr->patternNode ; upper != NULL ; upper = upper->lastLevel)
                 {
                  if (upper->matchTimeTag == ObjectReteData(theEnv)->CurrentObjectMatchTimeTag)
                    break;
                  else
                    upper->matchTimeTag = ObjectReteData(theEnv)->CurrentObjectMatchTimeTag;
                 }
              }
           }
        }
      alphaPtr = alphaPtr->nxtTerminal;
     }
  }

/***************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -