📄 insmngr.c
字号:
if (InstanceData(theEnv)->InstanceTable[hashTableIndex] != NULL) InstanceData(theEnv)->InstanceTable[hashTableIndex]->prvHash = InstanceData(theEnv)->CurrentInstance; InstanceData(theEnv)->InstanceTable[hashTableIndex] = InstanceData(theEnv)->CurrentInstance; } else { InstanceData(theEnv)->CurrentInstance->nxtHash = iprv->nxtHash; if (iprv->nxtHash != NULL) iprv->nxtHash->prvHash = InstanceData(theEnv)->CurrentInstance; iprv->nxtHash = InstanceData(theEnv)->CurrentInstance; InstanceData(theEnv)->CurrentInstance->prvHash = iprv; } /* ====================================== Put instance in global and class lists ====================================== */ if (InstanceData(theEnv)->CurrentInstance->cls->instanceList == NULL) InstanceData(theEnv)->CurrentInstance->cls->instanceList = InstanceData(theEnv)->CurrentInstance; else InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom->nxtClass = InstanceData(theEnv)->CurrentInstance; InstanceData(theEnv)->CurrentInstance->prvClass = InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom; InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom = InstanceData(theEnv)->CurrentInstance; if (InstanceData(theEnv)->InstanceList == NULL) InstanceData(theEnv)->InstanceList = InstanceData(theEnv)->CurrentInstance; else InstanceData(theEnv)->InstanceListBottom->nxtList = InstanceData(theEnv)->CurrentInstance; InstanceData(theEnv)->CurrentInstance->prvList = InstanceData(theEnv)->InstanceListBottom; InstanceData(theEnv)->InstanceListBottom = InstanceData(theEnv)->CurrentInstance; InstanceData(theEnv)->ChangesToInstances = TRUE; /* ============================================================================== Install the instance's name and slot-value symbols (prevent them from becoming ephemeral) - the class name and slot names are accounted for by the class ============================================================================== */ InstallInstance(theEnv,InstanceData(theEnv)->CurrentInstance,TRUE); ins = InstanceData(theEnv)->CurrentInstance; InstanceData(theEnv)->CurrentInstance = NULL; if (InstanceData(theEnv)->MkInsMsgPass) { DirectMessage(theEnv,MessageHandlerData(theEnv)->CREATE_SYMBOL,ins,&temp,NULL); }#if DEFRULE_CONSTRUCT if (ins->cls->reactive) ObjectNetworkAction(theEnv,OBJECT_ASSERT,(INSTANCE_TYPE *) ins,-1);#endif return(ins); }/***************************************************************************** NAME : InitSlotsCommand DESCRIPTION : Calls Kernel Expression Evaluator EvaluateExpression for each expression-value of an instance expression Evaluates default slots only - slots that were specified by overrides (sp->override == 1) are ignored) INPUTS : 1) Instance address RETURNS : Nothing useful SIDE EFFECTS : Each DATA_OBJECT slot in the instance's slot array is replaced by the evaluation (by EvaluateExpression) of the expression in the slot list. The old expression-values are deleted. NOTES : H/L Syntax: (init-slots <instance>) *****************************************************************************/globle void InitSlotsCommand( void *theEnv, DATA_OBJECT *result) { SetpType(result,SYMBOL); SetpValue(result,EnvFalseSymbol(theEnv)); EvaluationData(theEnv)->EvaluationError = FALSE; if (CheckCurrentMessage(theEnv,"init-slots",TRUE) == FALSE) return; EvaluateClassDefaults(theEnv,GetActiveInstance(theEnv)); if (! EvaluationData(theEnv)->EvaluationError) { SetpType(result,INSTANCE_ADDRESS); SetpValue(result,(void *) GetActiveInstance(theEnv)); } }/****************************************************** NAME : QuashInstance DESCRIPTION : Deletes an instance if it is not in use, otherwise sticks it on the garbage list INPUTS : The instance RETURNS : 1 if successful, 0 otherwise SIDE EFFECTS : Instance deleted or added to garbage NOTES : Even though the instance is removed from the class list, hash table and instance list, its links remain unchanged so that outside loops can still determine where the next node in the list is (assuming the instance was garbage collected). ******************************************************/globle intBool QuashInstance( void *theEnv, INSTANCE_TYPE *ins) { register int iflag; IGARBAGE *gptr;#if DEFRULE_CONSTRUCT if (EngineData(theEnv)->JoinOperationInProgress && ins->cls->reactive) { PrintErrorID(theEnv,"INSMNGR",12,FALSE); EnvPrintRouter(theEnv,WERROR,"Cannot delete instances of reactive classes while\n"); EnvPrintRouter(theEnv,WERROR," pattern-matching is in process.\n"); SetEvaluationError(theEnv,TRUE); return(0); }#endif if (ins->garbage == 1) return(0); if (ins->installed == 0) { PrintErrorID(theEnv,"INSMNGR",6,FALSE); EnvPrintRouter(theEnv,WERROR,"Cannot delete instance "); EnvPrintRouter(theEnv,WERROR,ValueToString(ins->name)); EnvPrintRouter(theEnv,WERROR," during initialization.\n"); SetEvaluationError(theEnv,TRUE); return(0); }#if DEBUGGING_FUNCTIONS if (ins->cls->traceInstances) PrintInstanceWatch(theEnv,UNMAKE_TRACE,ins);#endif#if DEFRULE_CONSTRUCT RemoveEntityDependencies(theEnv,(struct patternEntity *) ins); if (ins->cls->reactive) ObjectNetworkAction(theEnv,OBJECT_RETRACT,(INSTANCE_TYPE *) ins,-1);#endif if (ins->prvHash != NULL) ins->prvHash->nxtHash = ins->nxtHash; else InstanceData(theEnv)->InstanceTable[ins->hashTableIndex] = ins->nxtHash; if (ins->nxtHash != NULL) ins->nxtHash->prvHash = ins->prvHash; if (ins->prvClass != NULL) ins->prvClass->nxtClass = ins->nxtClass; else ins->cls->instanceList = ins->nxtClass; if (ins->nxtClass != NULL) ins->nxtClass->prvClass = ins->prvClass; else ins->cls->instanceListBottom = ins->prvClass; if (ins->prvList != NULL) ins->prvList->nxtList = ins->nxtList; else InstanceData(theEnv)->InstanceList = ins->nxtList; if (ins->nxtList != NULL) ins->nxtList->prvList = ins->prvList; else InstanceData(theEnv)->InstanceListBottom = ins->prvList; iflag = ins->installed; InstallInstance(theEnv,ins,FALSE); /* ============================================== If the instance is the basis for an executing rule, don't bother deleting its slots yet, for they may still be needed by pattern variables ============================================== */ if ((iflag == 1)#if DEFRULE_CONSTRUCT && (ins->header.busyCount == 0)#endif ) RemoveInstanceData(theEnv,ins); if ((ins->busy == 0) && (ins->depth > EvaluationData(theEnv)->CurrentEvaluationDepth) && (InstanceData(theEnv)->MaintainGarbageInstances == FALSE)#if DEFRULE_CONSTRUCT && (ins->header.busyCount == 0)#endif ) { DecrementSymbolCount(theEnv,ins->name); rtn_struct(theEnv,instance,ins); } else { gptr = get_struct(theEnv,igarbage); ins->garbage = 1; gptr->ins = ins; gptr->nxt = InstanceData(theEnv)->InstanceGarbageList; InstanceData(theEnv)->InstanceGarbageList = gptr; UtilityData(theEnv)->EphemeralItemCount += 2; UtilityData(theEnv)->EphemeralItemSize += InstanceSizeHeuristic(ins) + sizeof(IGARBAGE); } InstanceData(theEnv)->ChangesToInstances = TRUE; return(1); }#if DEFRULE_CONSTRUCT/**************************************************** NAME : InactiveInitializeInstance DESCRIPTION : Initializes an instance of a class Pattern-matching is automatically delayed until the instance is completely initialized INPUTS : The address of the result value RETURNS : Nothing useful SIDE EFFECTS : Instance intialized NOTES : H/L Syntax: (initialize-instance <instance-name> <slot-override>*) ****************************************************/globle void InactiveInitializeInstance( void *theEnv, DATA_OBJECT *result) { int ov; ov = SetDelayObjectPatternMatching(theEnv,TRUE); InitializeInstanceCommand(theEnv,result); SetDelayObjectPatternMatching(theEnv,ov); }/************************************************************** NAME : InactiveMakeInstance DESCRIPTION : Creates and initializes an instance of a class Pattern-matching is automatically delayed until the instance is completely initialized INPUTS : The address of the result value RETURNS : Nothing useful SIDE EFFECTS : Instance intialized NOTES : H/L Syntax: (make-instance <instance-name> of <class> <slot-override>*) **************************************************************/globle void InactiveMakeInstance( void *theEnv, DATA_OBJECT *result) { int ov; ov = SetDelayObjectPatternMatching(theEnv,TRUE); MakeInstanceCommand(theEnv,result); SetDelayObjectPatternMatching(theEnv,ov); }#endif/* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** *//******************************************************** NAME : NewInstance DESCRIPTION : Allocates and initializes a new instance INPUTS : None RETURNS : The address of the new instance SIDE EFFECTS : None NOTES : None ********************************************************/static INSTANCE_TYPE *NewInstance( void *theEnv) { INSTANCE_TYPE *instance; instance = get_struct(theEnv,instance);#if DEFRULE_CONSTRUCT instance->header.theInfo = &InstanceData(theEnv)->InstanceInfo; instance->header.dependents = NULL; instance->header.busyCount = 0; instance->header.timeTag = 0L; instance->partialMatchList = NULL; instance->basisSlots = NULL; instance->reteSynchronized = FALSE;#endif instance->busy = 0; instance->installed = 0; instance->garbage = 0; instance->initSlotsCalled = 0; instance->initializeInProgress = 0; instance->depth = EvaluationData(theEnv)->CurrentEvaluationDepth; instance->name = NULL; instance->hashTableIndex = 0; instance->cls = NULL; instance->slots = NULL; instance->slotAddresses = NULL; instance->prvClass = NULL; instance->nxtClass = NULL; instance->prvHash = NULL; instance->nxtHash = NULL; instance->prvList = NULL; instance->nxtList = NULL; return(instance); }/***************************************************************** NAME : InstanceLocationInfo DESCRIPTION : Determines where a specified instance belongs in the instance hash table INPUTS : 1) The class of the new instance 2) The symbol for the name of the instance 3) Caller's buffer for previous node address 4) Caller's buffer for hash value RETURNS : The address of the found instance, NULL otherwise SIDE EFFECTS : None NOTES : Instance names only have to be unique within a module *****************************************************************/static INSTANCE_TYPE *InstanceLocationInfo( void *theEnv, DEFCLASS *cls, SYMBOL_HN *iname, INSTANCE_TYPE **prv, unsigned *hashTableIndex) { INSTANCE_TYPE *ins; *hashTableIndex = HashInstance(iname); ins = InstanceData(theEnv)->InstanceTable[*hashTableIndex]; /* ======================================== Make sure all instances of the same name are grouped together regardless of what module their classes are in ======================================== */ *prv = NULL; while ((ins != NULL) ? (ins->name != iname) : FALSE) { *prv = ins; ins = ins->nxtHash; } while ((ins != NULL) ? (ins->name == iname) : FALSE) { if (ins->cls->header.whichModule->theModule == cls->header.whichModule->theModule) return(ins); *prv = ins; ins = ins->nxtHash; } return(NULL); }/******************************************************** NAME : InstallInstance DESCRIPTION : Prevent name and slot value symbols from being ephemeral (all others taken care of by class defn) INPUTS : 1) The address of the instance 2) A flag indicating whether to install or deinstall RETURNS : Nothing useful SIDE EFFECTS : Symbol counts incremented or decremented NOTES : Slot symbol installations are handled
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -