📄 objrtmch.c
字号:
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 + -