📄 objrtmch.c
字号:
}
}
alphaPtr = alphaPtr->nxtInGroup;
}
}
/******************************************************
NAME : EvaluateObjectPatternTest
DESCRIPTION : Evaluates the pattern network test
expression for a node
INPUTS : 1) The actual index of the slot value
field currently being examined
2) The multifield marker (if any)
for the pattern node being exmained
3) The pattern network test expression
4) The pattern node being examined
RETURNS : TRUE if the node passes the
test, FALSE otherwise
SIDE EFFECTS : Evaluation of the test
EvaluationError and HaltExecution
are always set to FALSE
NOTES : Assumes networkTest != NULL
******************************************************/
static intBool EvaluateObjectPatternTest(
void *theEnv,
int objectSlotField,
struct multifieldMarker *selfSlotMarker,
EXPRESSION *networkTest,
OBJECT_PATTERN_NODE *patternNode)
{
DATA_OBJECT vresult;
int rv;
if (networkTest->type == OBJ_PN_CONSTANT)
{
struct expr *oldArgument;
oldArgument = EvaluationData(theEnv)->CurrentExpression;
EvaluationData(theEnv)->CurrentExpression = networkTest;
rv = ObjectCmpConstantFunction(theEnv,networkTest->value,&vresult);
EvaluationData(theEnv)->CurrentExpression = oldArgument;
if (rv)
{
if (((struct ObjectCmpPNConstant *)
ValueToBitMap(networkTest->value))->pass)
patternNode->blocked = TRUE;
return(TRUE);
}
return(FALSE);
}
/* =========================================================
Evaluate or expressions expressed in the format:
(or <expression 1> <expression 2> ... <expression n>)
Returns TRUE (1.0) if any of the expression are TRUE,
otherwise returns false (0.0).
========================================================= */
if (networkTest->value == ExpressionData(theEnv)->PTR_OR)
{
networkTest = networkTest->argList;
while (networkTest != NULL)
{
if (EvaluateObjectPatternTest(theEnv,objectSlotField,selfSlotMarker,networkTest,patternNode))
{
/* ============================================
A node can be blocked ONLY if there were one
positive constant test on that node
============================================ */
patternNode->blocked = FALSE;
return(TRUE);
}
patternNode->blocked = FALSE;
networkTest = networkTest->nextArg;
}
return(FALSE);
}
/* ==========================================================
Evaluate and expressions expressed in the format:
(and <expression 1> <expression 2> ... <expression n>)
Returns false (0.0) if any of the expression are false,
otherwise returns TRUE (1.0).
========================================================== */
else if (networkTest->value == ExpressionData(theEnv)->PTR_AND)
{
networkTest = networkTest->argList;
while (networkTest != NULL)
{
if (EvaluateObjectPatternTest(theEnv,objectSlotField,selfSlotMarker,networkTest,patternNode)
== FALSE)
{
patternNode->blocked = FALSE;
return(FALSE);
}
patternNode->blocked = FALSE;
networkTest = networkTest->nextArg;
}
return(TRUE);
}
/* =======================================================
Evaluate all other expressions using EvaluateExpression
======================================================= */
else
{
EvaluationData(theEnv)->HaltExecution = FALSE;
if (EvaluateExpression(theEnv,networkTest,&vresult))
{
ObjectPatternNetErrorMessage(theEnv,patternNode);
EvaluationData(theEnv)->EvaluationError = FALSE;
EvaluationData(theEnv)->HaltExecution = FALSE;
return(FALSE);
}
if ((vresult.value != EnvFalseSymbol(theEnv)) || (vresult.type != SYMBOL))
return(TRUE);
}
return(FALSE);
}
/***************************************************
NAME : ObjectAssertAction
DESCRIPTION : Filters an instance through the
object pattern network
INPUTS : The instance
RETURNS : Nothing useful
SIDE EFFECTS : Instance matched
NOTES : None
***************************************************/
static void ObjectAssertAction(
void *theEnv,
INSTANCE_TYPE *ins)
{
ins->header.timeTag = ObjectReteData(theEnv)->UseEntityTimeTag;
ObjectReteData(theEnv)->CurrentPatternObject = ins;
ObjectReteData(theEnv)->CurrentPatternObjectSlot = NULL;
MarkObjectPatternNetwork(theEnv,NULL);
ObjectPatternMatch(theEnv,0,ObjectNetworkPointer(theEnv),NULL);
ins->reteSynchronized = TRUE;
}
/**********************************************************************
NAME : ObjectModifyAction
DESCRIPTION : Removes an instance from patterns (and attached joins)
applicable to specified slot(s), and then filters
same instance through object pattern network
(only against patterns which explicitly match on
named slot(s))
INPUTS : 1) The instance
2) The bitmap of slot ids
RETURNS : Nothing useful
SIDE EFFECTS : Instance retracted/asserted
NOTES : None
**********************************************************************/
static void ObjectModifyAction(
void *theEnv,
INSTANCE_TYPE *ins,
SLOT_BITMAP *slotNameIDs)
{
ins->header.timeTag = ObjectReteData(theEnv)->UseEntityTimeTag;
ObjectRetractAction(theEnv,ins,slotNameIDs);
ObjectReteData(theEnv)->CurrentPatternObject = ins;
ObjectReteData(theEnv)->CurrentPatternObjectSlot = NULL;
MarkObjectPatternNetwork(theEnv,slotNameIDs);
ObjectPatternMatch(theEnv,0,ObjectNetworkPointer(theEnv),NULL);
ins->reteSynchronized = TRUE;
}
/****************************************************
NAME : ObjectRetractAction
DESCRIPTION : Retracts the instance from the
applicable patterns for the object
(if the slotNameID != -1, then the
instance is only retracted from
the alpha memories of the patterns
which actually match on that slot)
INPUTS : 1) The instance
2) The slot bitmap for a modify
(NULL if the instance is actually
being removed)
RETURNS : Nothing useful
SIDE EFFECTS : Retractions performed
NOTES : None
****************************************************/
static void ObjectRetractAction(
void *theEnv,
INSTANCE_TYPE *ins,
SLOT_BITMAP *slotNameIDs)
{
struct patternMatch *prvMatch,*tmpMatch,
*deleteMatch,*lastDeleteMatch;
OBJECT_ALPHA_NODE *alphaPtr;
void *saveDependents;
if (slotNameIDs == NULL)
{
if (ins->partialMatchList != NULL)
{
tmpMatch = (struct patternMatch *) ins->partialMatchList;
while (tmpMatch != NULL)
{
ins->busy--;
tmpMatch = tmpMatch->next;
}
NetworkRetract(theEnv,(struct patternMatch *) ins->partialMatchList);
ins->partialMatchList = NULL;
}
}
else
{
deleteMatch = NULL;
lastDeleteMatch = NULL;
prvMatch = NULL;
tmpMatch = (struct patternMatch *) ins->partialMatchList;
while (tmpMatch != NULL)
{
alphaPtr = (OBJECT_ALPHA_NODE *) tmpMatch->matchingPattern;
if (alphaPtr->slotbmp != NULL)
{
if (CompareSlotBitMaps(slotNameIDs,
(SLOT_BITMAP *) ValueToBitMap(alphaPtr->slotbmp)))
{
ins->busy--;
if (prvMatch == NULL)
ins->partialMatchList = (void *) tmpMatch->next;
else
prvMatch->next = tmpMatch->next;
if (!deleteMatch)
deleteMatch = tmpMatch;
else
lastDeleteMatch->next = tmpMatch;
lastDeleteMatch = tmpMatch;
tmpMatch = tmpMatch->next;
lastDeleteMatch->next = NULL;
}
else
{
prvMatch = tmpMatch;
tmpMatch = tmpMatch->next;
}
}
else
{
prvMatch = tmpMatch;
tmpMatch = tmpMatch->next;
}
}
/* =============================================
We need to preserve any logical dependencies
of this object and reattach them after doing
the retract. Otherwise, the Rete network
will believe the object is gone and remove
the links from the partial matches upon which
this object is logically dependent.
============================================= */
if (deleteMatch != NULL)
{
saveDependents = ins->header.dependents;
ins->header.dependents = NULL;
NetworkRetract(theEnv,deleteMatch);
ins->header.dependents = saveDependents;
}
}
ins->reteSynchronized = TRUE;
}
/*****************************************************
NAME : ObjectPatternNetErrorMessage
DESCRIPTION : Prints out a locational error message
when an evaluation error occurs
during object pattern-matching
INPUTS : The pattern node
RETURNS : Nothing useful
SIDE EFFECTS : Error message displayed
NOTES : None
*****************************************************/
static void ObjectPatternNetErrorMessage(
void *theEnv,
OBJECT_PATTERN_NODE *patternPtr)
{
PrintErrorID(theEnv,"OBJRTMCH",1,TRUE);
EnvPrintRouter(theEnv,WERROR,"This error occurred in the object pattern network\n");
EnvPrintRouter(theEnv,WERROR," Currently active instance: [");
EnvPrintRouter(theEnv,WERROR,ValueToString(ObjectReteData(theEnv)->CurrentPatternObject->name));
EnvPrintRouter(theEnv,WERROR,"]\n");
EnvPrintRouter(theEnv,WERROR," Problem resides in slot ");
EnvPrintRouter(theEnv,WERROR,ValueToString(FindIDSlotName(theEnv,patternPtr->slotNameID)));
EnvPrintRouter(theEnv,WERROR," field #");
PrintLongInteger(theEnv,WERROR,(long) patternPtr->whichField);
EnvPrintRouter(theEnv,WERROR,"\n");
TraceErrorToObjectPattern(theEnv,TRUE,patternPtr);
EnvPrintRouter(theEnv,WERROR,"\n");
}
/*********************************************************
NAME : TraceErrorToObjectPattern
DESCRIPTION : Used by ObjectPatternNetErrorMessage() to
print the rule(s) which contain an object
pattern.
INPUTS : 1) A flag indicating if this is the
node in which the error actually
occurred or not
2) The pattern node
RETURNS : Nothing useful
SIDE EFFECTS : Error message displayed
NOTES : None
*********************************************************/
static void TraceErrorToObjectPattern(
void *theEnv,
int errorNode,
OBJECT_PATTERN_NODE *patternPtr)
{
struct joinNode *joinPtr;
while (patternPtr != NULL)
{
if (patternPtr->alphaNode != NULL)
{
joinPtr = patternPtr->alphaNode->header.entryJoin;
while (joinPtr != NULL)
{
EnvPrintRouter(theEnv,WERROR," Of pattern #");
PrintLongInteger(theEnv,WERROR,(long) joinPtr->depth);
EnvPrintRouter(theEnv,WERROR," in rule(s):\n");
TraceErrorToRule(theEnv,joinPtr," ");
joinPtr = joinPtr->rightMatchNode;
}
}
TraceErrorToObjectPattern(theEnv,FALSE,patternPtr->nextLevel);
if (errorNode)
break;
patternPtr = patternPtr->rightNode;
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -