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

📄 classfun.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
     }  }  #endif#if (! BLOAD_ONLY) && (! RUN_TIME)/***************************************************  NAME         : IsClassBeingUsed  DESCRIPTION  : Checks the busy flag of a class                   and ALL classes that inherit from                   it to make sure that it is not                   in use before deletion  INPUTS       : The class  RETURNS      : CLIPS_TRUE if in use, CLIPS_FALSE otherwise  SIDE EFFECTS : None  NOTES        : Recursively examines all subclasses ***************************************************/globle int IsClassBeingUsed(cls)  DEFCLASS *cls;  {   register unsigned i;      if (cls->busy > 0)     return(CLIPS_TRUE);   for (i = 0 ; i < cls->directSubclasses.classCount ; i++)     if (IsClassBeingUsed(cls->directSubclasses.classArray[i]))       return(CLIPS_TRUE);   return(CLIPS_FALSE);  }  /***************************************************  NAME         : RemoveAllUserClasses  DESCRIPTION  : Removes all classes  INPUTS       : None  RETURNS      : CLIPS_TRUE if succesful, CLIPS_FALSE otherwise  SIDE EFFECTS : The class hash table is cleared  NOTES        : None ***************************************************/globle int RemoveAllUserClasses()  {   VOID *userClasses,*ctmp;   int success = CLIPS_TRUE;   #if BLOAD || BLOAD_AND_BSAVE   if (Bloaded())     return(CLIPS_FALSE);#endif      /* ====================================================      Don't delete built-in system classes at head of list      ==================================================== */   userClasses = GetNextDefclass(NULL);   while (userClasses != NULL)     {      if (((DEFCLASS *) userClasses)->system == 0)        break;      userClasses = GetNextDefclass(userClasses);     }   while (userClasses != NULL)     {      ctmp = userClasses;      userClasses = GetNextDefclass(userClasses);      if (IsDefclassDeletable(ctmp))        {         RemoveConstructFromModule((struct constructHeader *) ctmp);         RemoveDefclass(ctmp);        }      else        {         success = CLIPS_FALSE;         CantDeleteItemErrorMessage("defclass",GetDefclassName(ctmp));        }     }   return(success);  }  /****************************************************  NAME         : DeleteClassUAG  DESCRIPTION  : Deallocates a class and all its                  subclasses  INPUTS       : The address of the class  RETURNS      : 1 if successful, 0 otherwise  SIDE EFFECTS : Removes the class from each of                 its superclasses' subclass lists  NOTES        : None ****************************************************/globle int DeleteClassUAG(cls)  DEFCLASS *cls;  {   unsigned subCount;      while (cls->directSubclasses.classCount != 0)     {      subCount = cls->directSubclasses.classCount;      DeleteClassUAG(cls->directSubclasses.classArray[0]);      if (cls->directSubclasses.classCount == subCount)        return(CLIPS_FALSE);     }   if (IsDefclassDeletable((VOID *) cls))     {      RemoveConstructFromModule((struct constructHeader *) cls);      RemoveDefclass((VOID *) cls);      return(CLIPS_TRUE);     }   return(CLIPS_FALSE);  }/*********************************************************  NAME         : MarkBitMapSubclasses  DESCRIPTION  : Recursively marks the ids of a class                 and all its subclasses in a bitmap  INPUTS       : 1) The bitmap                 2) The class                 3) A code indicating whether to set                    or clear the bits of the map                    corresponding to the class ids  RETURNS      : Nothing useful  SIDE EFFECTS : BitMap marked  NOTES        : IMPORTANT!!!!  Assumes the bitmap is                 large enough to hold all ids encountered! *********************************************************/globle VOID MarkBitMapSubclasses(map,cls,set)  char *map;  DEFCLASS *cls;  int set;  {   register unsigned i;      if (set)     SetBitMap(map,cls->id);   else     ClearBitMap(map,cls->id);   for (i = 0 ; i < cls->directSubclasses.classCount ; i++)     MarkBitMapSubclasses(map,cls->directSubclasses.classArray[i],set);  }  #endif/***************************************************  NAME         : FindSlotNameID  DESCRIPTION  : Finds the id of a slot name  INPUTS       : The slot name  RETURNS      : The slot name id (-1 if not found)  SIDE EFFECTS : None  NOTES        : A slot name always has the same                 id regardless of what class uses                 it.  In this way, a slot can                 be referred to by index independent                 of class.  Each class stores a                 map showing which slot name indices                 go to which slot.  This provides                 for immediate lookup of slots                 given the index (object pattern                 matching uses this). ***************************************************/globle int FindSlotNameID(slotName)  SYMBOL_HN *slotName;  {   SLOT_NAME *snp;      snp = SlotNameTable[HashSlotName(slotName)];   while ((snp != NULL) ? (snp->name != slotName) : CLIPS_FALSE)     snp = snp->nxt;   return((snp != NULL) ? (int) snp->id : -1);  }/***************************************************  NAME         : FindIDSlotName  DESCRIPTION  : Finds the slot anme for an id  INPUTS       : The id  RETURNS      : The slot name (NULL if not found)  SIDE EFFECTS : None  NOTES        : None ***************************************************/globle SYMBOL_HN *FindIDSlotName(id)  unsigned id;  {   SLOT_NAME *snp;      snp = FindIDSlotNameHash(id);   return((snp != NULL) ? snp->name : NULL);  }  /***************************************************  NAME         : FindIDSlotNameHash  DESCRIPTION  : Finds the slot anme for an id  INPUTS       : The id  RETURNS      : The slot name (NULL if not found)  SIDE EFFECTS : None  NOTES        : None ***************************************************/globle SLOT_NAME *FindIDSlotNameHash(id)  unsigned id;  {   register int i;   SLOT_NAME *snp;      for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)     {      snp = SlotNameTable[i];      while (snp != NULL)        {         if (snp->id == id)           return(snp);         snp = snp->nxt;        }     }   return(NULL);  }  /***************************************************  NAME         : GetTraversalID  DESCRIPTION  : Returns a unique integer ID for a                  traversal into the class hierarchy  INPUTS       : None  RETURNS      : The id, or -1 if none available  SIDE EFFECTS : EvaluationError set when no ids                   available  NOTES        : Used for recursive traversals of                  class hierarchy to assure that a                  class is only visited once ***************************************************/globle int GetTraversalID()  {   register unsigned i;   register DEFCLASS *cls;      if (CTID >= MAX_TRAVERSALS)     {      PrintErrorID("CLASSFUN",2,CLIPS_FALSE);      PrintCLIPS(WERROR,"Maximum number of simultaneous class hierarchy\n  traversals exceeded ");      PrintLongInteger(WERROR,(long) MAX_TRAVERSALS);      PrintCLIPS(WERROR,".\n");      SetEvaluationError(CLIPS_TRUE);      return(-1);     }        for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)     for (cls = ClassTable[i] ; cls != NULL ; cls = cls->nxtHash)       ClearTraversalID(cls->traversalRecord,CTID);   return(CTID++);  }  /***************************************************  NAME         : ReleaseTraversalID  DESCRIPTION  : Releases an ID for future use                 Also clears id from all classes  INPUTS       : None  RETURNS      : Nothing useful  SIDE EFFECTS : Old ID released for later reuse  NOTES        : Releases ID returned by most recent                   call to GetTraversalID() ***************************************************/globle VOID ReleaseTraversalID()  {   CTID--;  }  /*******************************************************  NAME         : HashClass  DESCRIPTION  : Generates a hash index for a given                 class name  INPUTS       : The address of the class name SYMBOL_HN  RETURNS      : The hash index value  SIDE EFFECTS : None   NOTES        : Counts on the fact that the symbol                 has already been hashed into the CLIPS                 symbol table - uses that hash value                 multiplied by a prime for a new hash *******************************************************/globle unsigned HashClass(cname)  SYMBOL_HN *cname;  {   unsigned long tally;      tally = ((unsigned long) cname->bucket) * BIG_PRIME;   return((unsigned) (tally % CLASS_TABLE_HASH_SIZE));  }/* =========================================   *****************************************          INTERNALLY VISIBLE FUNCTIONS   =========================================   ***************************************** *//*******************************************************  NAME         : HashSlotName  DESCRIPTION  : Generates a hash index for a given                 slot name  INPUTS       : The address of the slot name SYMBOL_HN  RETURNS      : The hash index value  SIDE EFFECTS : None   NOTES        : Counts on the fact that the symbol                 has already been hashed into the CLIPS                 symbol table - uses that hash value                 multiplied by a prime for a new hash *******************************************************/static unsigned HashSlotName(sname)  SYMBOL_HN *sname;  {   unsigned long tally;      tally = ((unsigned long) sname->bucket) * BIG_PRIME;   return((unsigned) (tally % SLOT_NAME_TABLE_HASH_SIZE));  }#if (! RUN_TIME)/***********************************************  NAME         : NewSlotNameID  DESCRIPTION  : Returns  an unused slot name id                 as close to 1 as possible  INPUTS       : None  RETURNS      : The new unused id  SIDE EFFECTS : None  NOTES        : None ***********************************************/static unsigned NewSlotNameID()  {   unsigned newid = 0;   register unsigned i;   SLOT_NAME *snp;      while (CLIPS_TRUE)     {      for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)        {         snp = SlotNameTable[i];         while ((snp != NULL) ? (snp->id != newid) : CLIPS_FALSE)           snp = snp->nxt;         if (snp != NULL)           break;        }      if (i < SLOT_NAME_TABLE_HASH_SIZE)        newid++;      else        break;     }   return(newid);  }    /***************************************************  NAME         : DeassignClassID  DESCRIPTION  : Reduces id map and MaxClassID if                 no ids in use above the one being                 released.  INPUTS       : The id  RETURNS      : Nothing useful  SIDE EFFECTS : ID map and MaxClassID possibly                 reduced  NOTES        : None ***************************************************/static VOID DeassignClassID(id)  unsigned id;  {   register unsigned i;   int reallocReqd;   unsigned oldChunk,newChunk;         ClassIDMap[id] = NULL;   for (i = id + 1 ; i < MaxClassID ; i++)     if (ClassIDMap[i] != NULL)       return;   reallocReqd = CLIPS_FALSE;   while (ClassIDMap[id] == NULL)     {      MaxClassID = (unsigned short) id;      if ((MaxClassID % CLASS_ID_MAP_CHUNK) == 0)        {         newChunk = MaxClassID;         if (reallocReqd == CLIPS_FALSE)           {            oldChunk = MaxClassID + CLASS_ID_MAP_CHUNK;            reallocReqd = CLIPS_TRUE;           }        }      if (id == 0)        break;      id--;     }   if (reallocReqd)     ClassIDMap = (DEFCLASS **) genrealloc((VOID *) ClassIDMap,                      (unsigned) (oldChunk * sizeof(DEFCLASS *)),                      (unsigned) (newChunk * sizeof(DEFCLASS *)));  }  #endif#endif/***************************************************  NAME         :   DESCRIPTION  :   INPUTS       :   RETURNS      :   SIDE EFFECTS :   NOTES        :  ***************************************************/

⌨️ 快捷键说明

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