#include "setup.h"
#if DEFRULE_CONSTRUCT && OBJECT_SYSTEM
#if (! BLOAD_ONLY) && (! RUN_TIME)
#include <string.h>
#include <stdlib.h>
#include "classcom.h"
#include "classfun.h"
#include "cstrnutl.h"
#include "constrnt.h"
#include "cstrnchk.h"
#include "cstrnops.h"
#include "drive.h"
#include "envrnmnt.h"
#include "inscom.h"
#include "insfun.h"
#include "insmngr.h"
#include "memalloc.h"
#include "network.h"
#include "object.h"
#include "pattern.h"
#include "prntutil.h"
#include "reteutil.h"
#include "ruledef.h"
#include "rulepsr.h"
#include "scanner.h"
#include "symbol.h"
#include "utility.h"
#endif
#include "constrct.h"
#include "exprnpsr.h"
#include "objrtmch.h"
#include "objrtgen.h"
#include "objrtfnx.h"
#include "pprint.h"
#include "reorder.h"
#include "router.h"
#if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
#include "objrtbin.h"
#endif
#if CONSTRUCT_COMPILER && (! RUN_TIME)
#include "objrtcmp.h"
#endif
#include "objrtbld.h"
#if ! DEFINSTANCES_CONSTRUCT
#include "classfun.h"
#include "classcom.h"
#include "extnfunc.h"
#endif
#if (! BLOAD_ONLY) && (! RUN_TIME)
#define OBJECT_PATTERN_INDICATOR "object"
static bool PatternParserFind(CLIPSLexeme *);
static struct lhsParseNode *ObjectLHSParse(Environment *,const char *,struct token *);
static bool ReorderAndAnalyzeObjectPattern(Environment *,struct lhsParseNode *);
static struct patternNodeHeader
*PlaceObjectPattern(Environment *,struct lhsParseNode *);
static OBJECT_PATTERN_NODE *FindObjectPatternNode(OBJECT_PATTERN_NODE *,struct lhsParseNode *,
OBJECT_PATTERN_NODE **,bool,bool);
static OBJECT_PATTERN_NODE *CreateNewObjectPatternNode(Environment *,struct lhsParseNode *,OBJECT_PATTERN_NODE *,
OBJECT_PATTERN_NODE *,bool,bool);
static void DetachObjectPattern(Environment *,struct patternNodeHeader *);
static void ClearObjectPatternMatches(Environment *,OBJECT_ALPHA_NODE *);
static void RemoveObjectPartialMatches(Environment *,Instance *,struct patternNodeHeader *);
static bool CheckDuplicateSlots(Environment *,struct lhsParseNode *,CLIPSLexeme *);
static struct lhsParseNode *ParseClassRestriction(Environment *,const char *,struct token *);
static struct lhsParseNode *ParseNameRestriction(Environment *,const char *,struct token *);
static struct lhsParseNode *ParseSlotRestriction(Environment *,const char *,struct token *,CONSTRAINT_RECORD *,bool);
static CLASS_BITMAP *NewClassBitMap(Environment *,unsigned short,bool);
static void InitializeClassBitMap(Environment *,CLASS_BITMAP *,bool);
static void DeleteIntermediateClassBitMap(Environment *,CLASS_BITMAP *);
static void *CopyClassBitMap(Environment *,void *);
static void DeleteClassBitMap(Environment *,void *);
static void MarkBitMapClassesBusy(Environment *,CLIPSBitMap *,int);
static bool EmptyClassBitMap(CLASS_BITMAP *);
static bool IdenticalClassBitMap(CLASS_BITMAP *,CLASS_BITMAP *);
static bool ProcessClassRestriction(Environment *,CLASS_BITMAP *,struct lhsParseNode **,bool);
static CONSTRAINT_RECORD *ProcessSlotRestriction(Environment *,CLASS_BITMAP *,CLIPSLexeme *,bool *);
static void IntersectClassBitMaps(CLASS_BITMAP *,CLASS_BITMAP *);
static void UnionClassBitMaps(CLASS_BITMAP *,CLASS_BITMAP *);
static CLASS_BITMAP *PackClassBitMap(Environment *,CLASS_BITMAP *);
static struct lhsParseNode *FilterObjectPattern(Environment *,struct patternParser *,
struct lhsParseNode *,struct lhsParseNode **,
struct lhsParseNode **,struct lhsParseNode **);
static CLIPSBitMap *FormSlotBitMap(Environment *,struct lhsParseNode *);
static struct lhsParseNode *RemoveSlotExistenceTests(Environment *,struct lhsParseNode *,CLIPSBitMap **);
static void MarkObjectPtnIncrementalReset(Environment *,struct patternNodeHeader *,bool);
static void ObjectIncrementalReset(Environment *);
#endif
static Expression *ObjectMatchDelayParse(Environment *,Expression *,const char *);
#if ! DEFINSTANCES_CONSTRUCT
static void ResetInitialObject(Environment *);
#endif
void SetupObjectPatternStuff(
Environment *theEnv)
{
#if (! BLOAD_ONLY) && (! RUN_TIME)
struct patternParser *newPtr;
if (ReservedPatternSymbol(theEnv,"object",NULL) == true)
{
SystemError(theEnv,"OBJRTBLD",1);
ExitRouter(theEnv,EXIT_FAILURE);
}
AddReservedPatternSymbol(theEnv,"object",NULL);
newPtr = get_struct(theEnv,patternParser);
newPtr->name = "objects";
newPtr->priority = 20;
newPtr->entityType = &InstanceData(theEnv)->InstanceInfo;
newPtr->recognizeFunction = PatternParserFind;
newPtr->parseFunction = ObjectLHSParse;
newPtr->postAnalysisFunction = ReorderAndAnalyzeObjectPattern;
newPtr->addPatternFunction = PlaceObjectPattern;
newPtr->removePatternFunction = DetachObjectPattern;
newPtr->genJNConstantFunction = NULL;
newPtr->replaceGetJNValueFunction = ReplaceGetJNObjectValue;
newPtr->genGetJNValueFunction = GenGetJNObjectValue;
newPtr->genCompareJNValuesFunction = ObjectJNVariableComparison;
newPtr->genPNConstantFunction = GenObjectPNConstantCompare;
newPtr->replaceGetPNValueFunction = ReplaceGetPNObjectValue;
newPtr->genGetPNValueFunction = GenGetPNObjectValue;
newPtr->genComparePNValuesFunction = ObjectPNVariableComparison;
newPtr->returnUserDataFunction = DeleteClassBitMap;
newPtr->copyUserDataFunction = CopyClassBitMap;
newPtr->markIRPatternFunction = MarkObjectPtnIncrementalReset;
newPtr->incrementalResetFunction = ObjectIncrementalReset;
#if CONSTRUCT_COMPILER && (! RUN_TIME)
newPtr->codeReferenceFunction = ObjectPatternNodeReference;
#else
newPtr->codeReferenceFunction = NULL;
#endif
AddPatternParser(theEnv,newPtr);
#endif
#if (! RUN_TIME)
AddUDF(theEnv,"object-pattern-match-delay","*",0,UNBOUNDED,NULL,ObjectMatchDelay,"ObjectMatchDelay",NULL);
FuncSeqOvlFlags(theEnv,"object-pattern-match-delay",false,false);
#endif
AddFunctionParser(theEnv,"object-pattern-match-delay",ObjectMatchDelayParse);
InstallObjectPrimitives(theEnv);
#if CONSTRUCT_COMPILER && (! RUN_TIME)
ObjectPatternsCompilerSetup(theEnv);
#endif
#if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
SetupObjectPatternsBload(theEnv);
#endif
}
#if (! BLOAD_ONLY) && (! RUN_TIME)
static bool PatternParserFind(
CLIPSLexeme *value)
{
if (strcmp(value->contents,OBJECT_PATTERN_INDICATOR) == 0)
return true;
return false;
}
static struct lhsParseNode *ObjectLHSParse(
Environment *theEnv,
const char *readSource,
struct token *lastToken)
{
#if MAC_XCD
#pragma unused(lastToken)
#endif
struct token theToken;
struct lhsParseNode *firstNode = NULL,*lastNode = NULL,*tmpNode;
CLASS_BITMAP *clsset,*tmpset;
CONSTRAINT_RECORD *slotConstraints;
bool ppbackupReqd = false,multip;
clsset = NewClassBitMap(theEnv,DefclassData(theEnv)->MaxClassID - 1,true);
if (EmptyClassBitMap(clsset))
{
PrintErrorID(theEnv,"OBJRTBLD",1,false);
WriteString(theEnv,STDERR,"No objects of existing classes can satisfy pattern.\n");
DeleteIntermediateClassBitMap(theEnv,clsset);
return NULL;
}
tmpset = NewClassBitMap(theEnv,DefclassData(theEnv)->MaxClassID - 1,true);
IncrementIndentDepth(theEnv,7);
GetToken(theEnv,readSource,&theToken);
while (theToken.tknType != RIGHT_PARENTHESIS_TOKEN)
{
ppbackupReqd = true;
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken.printForm);
if (theToken.tknType != LEFT_PARENTHESIS_TOKEN)
{
SyntaxErrorMessage(theEnv,"object pattern");
goto ObjectLHSParseERROR;
}
GetToken(theEnv,readSource,&theToken);
if (theToken.tknType != SYMBOL_TOKEN)
{
SyntaxErrorMessage(theEnv,"object pattern");
goto ObjectLHSParseERROR;
}
if (CheckDuplicateSlots(theEnv,firstNode,theToken.lexemeValue))
goto ObjectLHSParseERROR;
if (theToken.value == (void *) DefclassData(theEnv)->ISA_SYMBOL)
{
tmpNode = ParseClassRestriction(theEnv,readSource,&theToken);
if (tmpNode == NULL)
goto ObjectLHSParseERROR;
InitializeClassBitMap(theEnv,tmpset,false);
if (ProcessClassRestriction(theEnv,tmpset,&tmpNode->bottom,true) == false)
{
ReturnLHSParseNodes(theEnv,tmpNode);
goto ObjectLHSParseERROR;
}
IntersectClassBitMaps(clsset,tmpset);
}
else if (theToken.value == (void *) DefclassData(theEnv)->NAME_SYMBOL)
{
tmpNode = ParseNameRestriction(theEnv,readSource,&theToken);
if (tmpNode == NULL)
goto ObjectLHSParseERROR;
InitializeClassBitMap(theEnv,tmpset,true);
}
else
{
slotConstraints = ProcessSlotRestriction(theEnv,clsset,theToken.lexemeValue,&multip);
if (slotConstraints != NULL)
{
InitializeClassBitMap(theEnv,tmpset,true);
tmpNode = ParseSlotRestriction(theEnv,readSource,&theToken,slotConstraints,multip);
if (tmpNode == NULL)
goto ObjectLHSParseERROR;
}
else
{
InitializeClassBitMap(theEnv,tmpset,false);
tmpNode = GetLHSParseNode(theEnv);
tmpNode->slot = theToken.lexemeValue;
}
}
if (EmptyClassBitMap(tmpset))
{
PrintErrorID(theEnv,"OBJRTBLD",2,false);
WriteString(theEnv,STDERR,"No objects of existing classes can satisfy '");
WriteString(theEnv,STDERR,tmpNode->slot->contents);
WriteString(theEnv,STDERR,"' restriction in object pattern.\n");
ReturnLHSParseNodes(theEnv,tmpNode);
goto ObjectLHSParseERROR;
}
if (EmptyClassBitMap(clsset))
{
PrintErrorID(theEnv,"OBJRTBLD",1,false);
WriteString(theEnv,STDERR,"No objects of existing classes can satisfy pattern.\n");
ReturnLHSParseNodes(theEnv,tmpNode);
goto ObjectLHSParseERROR;
}
if (tmpNode != NULL)
{
if (firstNode == NULL)
firstNode = tmpNode;
else
lastNode->right = tmpNode;
lastNode = tmpNode;
}
PPCRAndIndent(theEnv);
GetToken(theEnv,readSource,&theToken);
}
if (firstNode == NULL)
{
if (EmptyClassBitMap(clsset))
{
PrintErrorID(theEnv,"OBJRTBLD",1,false);
WriteString(theEnv,STDERR,"No objects of existing classes can satisfy pattern.\n");
goto ObjectLHSParseERROR;
}
firstNode = GetLHSParseNode(theEnv);
firstNode->pnType = SF_WILDCARD_NODE;
firstNode->slot = DefclassData(theEnv)->ISA_SYMBOL;
firstNode->slotNumber = ISA_ID;
firstNode->index = 1;
}
if (ppbackupReqd)
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,theToken.printForm);
}
DeleteIntermediateClassBitMap(theEnv,tmpset);
clsset = PackClassBitMap(theEnv,clsset);
firstNode->userData = AddBitMap(theEnv,clsset,ClassBitMapSize(clsset));
IncrementBitMapCount(firstNode->userData);
DeleteIntermediateClassBitMap(theEnv,clsset);
DecrementIndentDepth(theEnv,7);
return(firstNode);
ObjectLHSParseERROR:
DeleteIntermediateClassBitMap(theEnv,clsset);
DeleteIntermediateClassBitMap(theEnv,tmpset);
ReturnLHSParseNodes(theEnv,firstNode);
DecrementIndentDepth(theEnv,7);
return NULL;
}
static bool ReorderAndAnalyzeObjectPattern(
Environment *theEnv,
struct lhsParseNode *topNode)
{
CLASS_BITMAP *clsset,*tmpset;
Expression *rexp,*tmpmin,*tmpmax;
Defclass *cls;
struct lhsParseNode *tmpNode,*subNode,*bitmap_node,*isa_node,*name_node;
unsigned short i;
SlotDescriptor *sd;
CONSTRAINT_RECORD *crossConstraints, *theConstraint;
int incompatibleConstraint;
bool clssetChanged = false;
topNode->right = FilterObjectPattern(theEnv,topNode->patternType,topNode->right,
&bitmap_node,&isa_node,&name_node);
clsset = (CLASS_BITMAP *) ((CLIPSBitMap *) bitmap_node->userData)->contents;
tmpset = NewClassBitMap(theEnv,clsset->maxid,false);
if ((isa_node == NULL) ? false :
((isa_node->constraints == NULL) ? false :
(isa_node->constraints->restrictionList != NULL)))
{
rexp = isa_node->constraints->restrictionList;
while (rexp != NULL)
{
cls = LookupDefclassInScope(theEnv,rexp->lexemeValue->contents);
if (cls != NULL)
{
if ((cls->id <= clsset->maxid) ? TestBitMap(clsset->map,cls->id) : false)
SetBitMap(tmpset->map,cls->id);
}
rexp = rexp->nextArg;
}
clssetChanged = IdenticalClassBitMap(tmpset,clsset) ? false : true;
}
else
GenCopyMemory(char,tmpset->maxid / BITS_PER_BYTE + 1,tmpset->map,clsset->map);
tmpNode = topNode->right;
while (tmpNode != bitmap_node)
{
if ((tmpNode == isa_node) || (tmpNode == name_node))
{
tmpNode = tmpNode->right;
continue;
}
for (i = 0 ; i <= tmpset->maxid ; i++)
if (TestBitMap(tmpset->map,i))
{
cls = DefclassData(theEnv)->ClassIDMap[i];
sd = cls->instanceTemplate[FindInstanceTemplateSlot(theEnv,cls,tmpNode->slot)];
crossConstraints = IntersectConstraints(theEnv,tmpNode->constraints,sd->constraint);
incompatibleConstraint = UnmatchableConstraint(crossConstraints);
RemoveConstraint(theEnv,crossConstraints);
if (incompatibleConstraint)
{
ClearBitMap(tmpset->map,i);
clssetChanged = true;
}
else if (tmpNode->pnType == MF_WILDCARD_NODE)
{
for (subNode = tmpNode->bottom ; subNode != NULL ; subNode = subNode->right)
{
if ((subNode->pnType == MF_WILDCARD_NODE) || (subNode->pnType == MF_VARIABLE_NODE))
{ theConstraint = subNode->constraints->multifield; }
else
{ theConstraint = subNode->constraints; }
tmpmin = theConstraint->minFields;
theConstraint->minFields = sd->constraint->minFields;
tmpmax = theConstraint->maxFields;
theConstraint->maxFields = sd->constraint->maxFields;
crossConstraints = IntersectConstraints(theEnv,theConstraint,sd->constraint);
theConstraint->minFields = tmpmin;
theConstraint->maxFields = tmpmax;
incompatibleConstraint = UnmatchableConstraint(crossConstraints);
RemoveConstraint(theEnv,crossConstraints);
if (incompatibleConstraint)
{
ClearBitMap(tmpset->map,i);
clssetChanged = true;
break;
}
}
}
}
tmpNode = tmpNode->right;
}
if (clssetChanged)
{
if (EmptyClassBitMap(tmpset))
{
PrintErrorID(theEnv,"OBJRTBLD",3,true);
DeleteIntermediateClassBitMap(theEnv,tmpset);
WriteString(theEnv,STDERR,"No objects of existing classes can satisfy pattern #");
WriteInteger(theEnv,STDERR,topNode->pattern);
WriteString(theEnv,STDERR,".\n");
return true;
}
clsset = PackClassBitMap(theEnv,tmpset);
DeleteClassBitMap(theEnv,bitmap_node->userData);
bitmap_node->userData = AddBitMap(theEnv,clsset,ClassBitMapSize(clsset));
IncrementBitMapCount(bitmap_node->userData);
DeleteIntermediateClassBitMap(theEnv,clsset);
}
else
DeleteIntermediateClassBitMap(theEnv,tmpset);
return false;
}
static struct patternNodeHeader *PlaceObjectPattern(
Environment *theEnv,
struct lhsParseNode *thePattern)
{
OBJECT_PATTERN_NODE *currentLevel,*lastLevel;
struct lhsParseNode *tempPattern = NULL;
OBJECT_PATTERN_NODE *nodeSlotGroup, *newNode;
OBJECT_ALPHA_NODE *newAlphaNode;
bool endSlot;
CLIPSBitMap *newClassBitMap,*newSlotBitMap;
struct expr *rightHash;
unsigned int i;
CLASS_BITMAP *cbmp;
Defclass *relevantDefclass;
CLASS_ALPHA_LINK *newAlphaLink;
currentLevel = ObjectNetworkPointer(theEnv);
lastLevel = NULL;
rightHash = thePattern->rightHash;
newSlotBitMap = FormSlotBitMap(theEnv,thePattern->right);
thePattern->right = RemoveSlotExistenceTests(theEnv,thePattern->right,&newClassBitMap);
thePattern = thePattern->right;
do
{
if (thePattern->multifieldSlot)
{
tempPattern = thePattern;
thePattern = thePattern->bottom;
}
if (((thePattern->pnType == MF_WILDCARD_NODE) ||
(thePattern->pnType == MF_VARIABLE_NODE)) &&
(thePattern->right == NULL) && (tempPattern != NULL))
{ endSlot = true; }
else
{ endSlot = false; }
newNode = FindObjectPatternNode(currentLevel,thePattern,&nodeSlotGroup,endSlot,false);
if (newNode == NULL)
{ newNode = CreateNewObjectPatternNode(theEnv,thePattern,nodeSlotGroup,lastLevel,endSlot,false); }
if (thePattern->constantSelector != NULL)
{
currentLevel = newNode->nextLevel;
lastLevel = newNode;
newNode = FindObjectPatternNode(currentLevel,thePattern,&nodeSlotGroup,endSlot,true);
if (newNode == NULL)
{ newNode = CreateNewObjectPatternNode(theEnv,thePattern,nodeSlotGroup,lastLevel,endSlot,true); }
}
if ((thePattern->right == NULL) && (tempPattern != NULL))
{
thePattern = tempPattern;
tempPattern = NULL;
}
lastLevel = newNode;
currentLevel = newNode->nextLevel;
thePattern = thePattern->right;
}
while ((thePattern != NULL) ? (thePattern->userData == NULL) : false);
newAlphaNode = lastLevel->alphaNode;
while (newAlphaNode != NULL)
{
if ((newClassBitMap == newAlphaNode->classbmp) &&
(newSlotBitMap == newAlphaNode->slotbmp) &&
IdenticalExpression(newAlphaNode->header.rightHash,rightHash))
return((struct patternNodeHeader *) newAlphaNode);
newAlphaNode = newAlphaNode->nxtInGroup;
}
newAlphaNode = get_struct(theEnv,objectAlphaNode);
InitializePatternHeader(theEnv,&newAlphaNode->header);
newAlphaNode->header.rightHash = AddHashedExpression(theEnv,rightHash);
newAlphaNode->matchTimeTag = 0L;
newAlphaNode->patternNode = lastLevel;
newAlphaNode->classbmp = newClassBitMap;
IncrementBitMapCount(newClassBitMap);
MarkBitMapClassesBusy(theEnv,newClassBitMap,1);
newAlphaNode->slotbmp = newSlotBitMap;
if (newSlotBitMap != NULL)
IncrementBitMapCount(newSlotBitMap);
newAlphaNode->bsaveID = 0L;
newAlphaNode->nxtInGroup = lastLevel->alphaNode;
lastLevel->alphaNode = newAlphaNode;
newAlphaNode->nxtTerminal = ObjectNetworkTerminalPointer(theEnv);
SetObjectNetworkTerminalPointer(theEnv,newAlphaNode);
cbmp = (CLASS_BITMAP *) newClassBitMap->contents;
for (i = 0; i <= cbmp->maxid; i++)
{
if (TestBitMap(cbmp->map,i))
{
relevantDefclass = DefclassData(theEnv)->ClassIDMap[i];
newAlphaLink = get_struct(theEnv, classAlphaLink);
newAlphaLink->alphaNode = newAlphaNode;
newAlphaLink->next = relevantDefclass->relevant_terminal_alpha_nodes;
relevantDefclass->relevant_terminal_alpha_nodes = newAlphaLink;
}
}
return((struct patternNodeHeader *) newAlphaNode);
}
static OBJECT_PATTERN_NODE *FindObjectPatternNode(
OBJECT_PATTERN_NODE *listOfNodes,
struct lhsParseNode *thePattern,
OBJECT_PATTERN_NODE **nodeSlotGroup,
bool endSlot,
bool constantSelector)
{
struct expr *compareTest;
*nodeSlotGroup = NULL;
if (constantSelector)
{ compareTest = thePattern->constantValue; }
else if (thePattern->constantSelector != NULL)
{ compareTest = thePattern->constantSelector; }
else
{ compareTest = thePattern->networkTest; }
while (listOfNodes != NULL)
{
if (((thePattern->pnType == MF_WILDCARD_NODE) || (thePattern->pnType == MF_VARIABLE_NODE)) ?
listOfNodes->multifieldNode : (listOfNodes->multifieldNode == 0))
{
if ((thePattern->slotNumber == listOfNodes->slotNameID) &&
(thePattern->index == listOfNodes->whichField) &&
(thePattern->singleFieldsAfter == listOfNodes->leaveFields) &&
(endSlot == listOfNodes->endSlot) &&
IdenticalExpression(listOfNodes->networkTest,compareTest))
return(listOfNodes);
}
if ((*nodeSlotGroup == NULL) &&
(thePattern->index == listOfNodes->whichField) &&
(thePattern->slotNumber == listOfNodes->slotNameID))
*nodeSlotGroup = listOfNodes;
listOfNodes = listOfNodes->rightNode;
}
return NULL;
}
static OBJECT_PATTERN_NODE *CreateNewObjectPatternNode(
Environment *theEnv,
struct lhsParseNode *thePattern,
OBJECT_PATTERN_NODE *nodeSlotGroup,
OBJECT_PATTERN_NODE *upperLevel,
bool endSlot,
bool constantSelector)
{
OBJECT_PATTERN_NODE *newNode,*prvNode,*curNode;
newNode = get_struct(theEnv,objectPatternNode);
newNode->blocked = false;
newNode->multifieldNode = false;
newNode->alphaNode = NULL;
newNode->matchTimeTag = 0L;
newNode->nextLevel = NULL;
newNode->rightNode = NULL;
newNode->leftNode = NULL;
newNode->bsaveID = 0L;
if ((thePattern->constantSelector != NULL) && (! constantSelector))
{ newNode->selector = true; }
else
{ newNode->selector = false; }
if (constantSelector)
{ newNode->networkTest = AddHashedExpression(theEnv,thePattern->constantValue); }
else if (thePattern->constantSelector != NULL)
{ newNode->networkTest = AddHashedExpression(theEnv,thePattern->constantSelector); }
else
{ newNode->networkTest = AddHashedExpression(theEnv,thePattern->networkTest); }
newNode->whichField = thePattern->index;
newNode->leaveFields = thePattern->singleFieldsAfter;
newNode->slotNameID = thePattern->slotNumber;
if ((thePattern->pnType == MF_WILDCARD_NODE) || (thePattern->pnType == MF_VARIABLE_NODE))
newNode->multifieldNode = true;
newNode->endSlot = endSlot;
newNode->lastLevel = upperLevel;
if ((upperLevel != NULL) && (upperLevel->selector))
{ AddHashedPatternNode(theEnv,upperLevel,newNode,newNode->networkTest->type,newNode->networkTest->value); }
if (nodeSlotGroup == NULL)
{
if (upperLevel == NULL)
{
newNode->rightNode = ObjectNetworkPointer(theEnv);
SetObjectNetworkPointer(theEnv,newNode);
}
else
{
newNode->rightNode = upperLevel->nextLevel;
upperLevel->nextLevel = newNode;
}
if (newNode->rightNode != NULL)
newNode->rightNode->leftNode = newNode;
return(newNode);
}
prvNode = NULL;
curNode = nodeSlotGroup;
while ((curNode == NULL) ? false :
(curNode->slotNameID == nodeSlotGroup->slotNameID) &&
(curNode->whichField == nodeSlotGroup->whichField))
{
if ((curNode->networkTest == NULL) ? false :
((curNode->networkTest->type != OBJ_PN_CONSTANT) ? false :
((struct ObjectCmpPNConstant *) curNode->networkTest->bitMapValue->contents)->pass))
break;
prvNode = curNode;
curNode = curNode->rightNode;
}
if (curNode != NULL)
{
newNode->leftNode = curNode->leftNode;
newNode->rightNode = curNode;
if (curNode->leftNode != NULL)
curNode->leftNode->rightNode = newNode;
else if (curNode->lastLevel != NULL)
curNode->lastLevel->nextLevel = newNode;
else
SetObjectNetworkPointer(theEnv,newNode);
curNode->leftNode = newNode;
}
else
{
newNode->leftNode = prvNode;
prvNode->rightNode = newNode;
}
return(newNode);
}
static void DetachObjectPattern(
Environment *theEnv,
struct patternNodeHeader *thePattern)
{
OBJECT_ALPHA_NODE *alphaPtr,*prv,*terminalPtr;
OBJECT_PATTERN_NODE *patternPtr,*upperLevel;
alphaPtr = (OBJECT_ALPHA_NODE *) thePattern;
ClearObjectPatternMatches(theEnv,alphaPtr);
if (! ConstructData(theEnv)->ClearInProgress)
{
CLASS_BITMAP *cbmp;
unsigned int i;
Defclass *relevantDefclass;
CLASS_ALPHA_LINK *alphaLink, *lastAlpha;
cbmp = (CLASS_BITMAP *) alphaPtr->classbmp->contents;
for (i = 0; i <= cbmp->maxid; i++)
{
if (TestBitMap(cbmp->map,i))
{
relevantDefclass = DefclassData(theEnv)->ClassIDMap[i];
for (lastAlpha = NULL, alphaLink = relevantDefclass->relevant_terminal_alpha_nodes;
alphaLink != NULL;
lastAlpha = alphaLink, alphaLink = alphaLink->next)
{
if (alphaLink->alphaNode == alphaPtr)
{
if (lastAlpha == NULL)
{ relevantDefclass->relevant_terminal_alpha_nodes = alphaLink->next; }
else
{ lastAlpha->next = alphaLink->next; }
rtn_struct(theEnv,classAlphaLink,alphaLink);
break;
}
}
}
}
}
MarkBitMapClassesBusy(theEnv,alphaPtr->classbmp,-1);
DeleteClassBitMap(theEnv,alphaPtr->classbmp);
if (alphaPtr->slotbmp != NULL)
{ DecrementBitMapReferenceCount(theEnv,alphaPtr->slotbmp); }
prv = NULL;
terminalPtr = ObjectNetworkTerminalPointer(theEnv);
while (terminalPtr != alphaPtr)
{
prv = terminalPtr;
terminalPtr = terminalPtr->nxtTerminal;
}
if (prv == NULL)
{ SetObjectNetworkTerminalPointer(theEnv,terminalPtr->nxtTerminal); }
else
{ prv->nxtTerminal = terminalPtr->nxtTerminal; }
prv = NULL;
terminalPtr = alphaPtr->patternNode->alphaNode;
while (terminalPtr != alphaPtr)
{
prv = terminalPtr;
terminalPtr = terminalPtr->nxtInGroup;
}
if (prv == NULL)
{
if (alphaPtr->nxtInGroup != NULL)
{
alphaPtr->patternNode->alphaNode = alphaPtr->nxtInGroup;
RemoveHashedExpression(theEnv,alphaPtr->header.rightHash);
rtn_struct(theEnv,objectAlphaNode,alphaPtr);
return;
}
}
else
{
prv->nxtInGroup = alphaPtr->nxtInGroup;
RemoveHashedExpression(theEnv,alphaPtr->header.rightHash);
rtn_struct(theEnv,objectAlphaNode,alphaPtr);
return;
}
alphaPtr->patternNode->alphaNode = NULL;
RemoveHashedExpression(theEnv,alphaPtr->header.rightHash);
upperLevel = alphaPtr->patternNode;
rtn_struct(theEnv,objectAlphaNode,alphaPtr);
if (upperLevel->nextLevel != NULL)
return;
while (upperLevel != NULL)
{
if ((upperLevel->leftNode == NULL) &&
(upperLevel->rightNode == NULL))
{
patternPtr = upperLevel;
upperLevel = patternPtr->lastLevel;
if (upperLevel == NULL)
SetObjectNetworkPointer(theEnv,NULL);
else
{
if (upperLevel->selector)
{ RemoveHashedPatternNode(theEnv,upperLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); }
upperLevel->nextLevel = NULL;
if (upperLevel->alphaNode != NULL)
upperLevel = NULL;
}
RemoveHashedExpression(theEnv,(Expression *) patternPtr->networkTest);
rtn_struct(theEnv,objectPatternNode,patternPtr);
}
else if (upperLevel->leftNode != NULL)
{
patternPtr = upperLevel;
if ((patternPtr->lastLevel != NULL) &&
(patternPtr->lastLevel->selector))
{ RemoveHashedPatternNode(theEnv,patternPtr->lastLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); }
upperLevel->leftNode->rightNode = upperLevel->rightNode;
if (upperLevel->rightNode != NULL)
{ upperLevel->rightNode->leftNode = upperLevel->leftNode; }
RemoveHashedExpression(theEnv,(Expression *) patternPtr->networkTest);
rtn_struct(theEnv,objectPatternNode,patternPtr);
upperLevel = NULL;
}
else
{
patternPtr = upperLevel;
upperLevel = upperLevel->lastLevel;
if (upperLevel == NULL)
{ SetObjectNetworkPointer(theEnv,patternPtr->rightNode); }
else
{
if (upperLevel->selector)
{ RemoveHashedPatternNode(theEnv,upperLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); }
upperLevel->nextLevel = patternPtr->rightNode;
}
patternPtr->rightNode->leftNode = NULL;
RemoveHashedExpression(theEnv,(Expression *) patternPtr->networkTest);
rtn_struct(theEnv,objectPatternNode,patternPtr);
upperLevel = NULL;
}
}
}
static void ClearObjectPatternMatches(
Environment *theEnv,
OBJECT_ALPHA_NODE *alphaPtr)
{
Instance *ins;
IGARBAGE *igrb;
ins = InstanceData(theEnv)->InstanceList;
while (ins != NULL)
{
RemoveObjectPartialMatches(theEnv,ins,(struct patternNodeHeader *) alphaPtr);
ins = ins->nxtList;
}
igrb = InstanceData(theEnv)->InstanceGarbageList;
while (igrb != NULL)
{
RemoveObjectPartialMatches(theEnv,igrb->ins,(struct patternNodeHeader *) alphaPtr);
igrb = igrb->nxt;
}
}
static void RemoveObjectPartialMatches(
Environment *theEnv,
Instance *ins,
struct patternNodeHeader *phead)
{
struct patternMatch *match_before, *match_ptr;
match_before = NULL;
match_ptr = (struct patternMatch *) ins->partialMatchList;
while (match_ptr != NULL)
{
if (match_ptr->matchingPattern == phead)
{
ins->busy--;
if (match_before == NULL)
{
ins->partialMatchList = (void *) match_ptr->next;
rtn_struct(theEnv,patternMatch,match_ptr);
match_ptr = (struct patternMatch *) ins->partialMatchList;
}
else
{
match_before->next = match_ptr->next;
rtn_struct(theEnv,patternMatch,match_ptr);
match_ptr = match_before->next;
}
}
else
{
match_before = match_ptr;
match_ptr = match_ptr->next;
}
}
}
static bool CheckDuplicateSlots(
Environment *theEnv,
struct lhsParseNode *nodeList,
CLIPSLexeme *slotName)
{
while (nodeList != NULL)
{
if (nodeList->slot == slotName)
{
PrintErrorID(theEnv,"OBJRTBLD",4,true);
WriteString(theEnv,STDERR,"Multiple restrictions on attribute '");
WriteString(theEnv,STDERR,slotName->contents);
WriteString(theEnv,STDERR,"' not allowed.\n");
return true;
}
nodeList = nodeList->right;
}
return false;
}
static struct lhsParseNode *ParseClassRestriction(
Environment *theEnv,
const char *readSource,
struct token *theToken)
{
struct lhsParseNode *tmpNode;
CLIPSLexeme *rln;
CONSTRAINT_RECORD *rv;
rv = GetConstraintRecord(theEnv);
rv->anyAllowed = 0;
rv->symbolsAllowed = 1;
rln = theToken->lexemeValue;
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
tmpNode = RestrictionParse(theEnv,readSource,theToken,false,rln,ISA_ID,rv,0);
if (tmpNode == NULL)
{
RemoveConstraint(theEnv,rv);
return NULL;
}
if ((theToken->tknType != RIGHT_PARENTHESIS_TOKEN) ||
(tmpNode->pnType == MF_WILDCARD_NODE) ||
(tmpNode->pnType == MF_VARIABLE_NODE))
{
PPBackup(theEnv);
if (theToken->tknType != RIGHT_PARENTHESIS_TOKEN)
{
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken->printForm);
}
SyntaxErrorMessage(theEnv,"class restriction in object pattern");
ReturnLHSParseNodes(theEnv,tmpNode);
RemoveConstraint(theEnv,rv);
return NULL;
}
tmpNode->derivedConstraints = 1;
return(tmpNode);
}
static struct lhsParseNode *ParseNameRestriction(
Environment *theEnv,
const char *readSource,
struct token *theToken)
{
struct lhsParseNode *tmpNode;
CLIPSLexeme *rln;
CONSTRAINT_RECORD *rv;
rv = GetConstraintRecord(theEnv);
rv->anyAllowed = 0;
rv->instanceNamesAllowed = 1;
rln = theToken->lexemeValue;
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
tmpNode = RestrictionParse(theEnv,readSource,theToken,false,rln,NAME_ID,rv,0);
if (tmpNode == NULL)
{
RemoveConstraint(theEnv,rv);
return NULL;
}
if ((theToken->tknType != RIGHT_PARENTHESIS_TOKEN) ||
(tmpNode->pnType == MF_WILDCARD_NODE) ||
(tmpNode->pnType == MF_VARIABLE_NODE))
{
PPBackup(theEnv);
if (theToken->tknType != RIGHT_PARENTHESIS_TOKEN)
{
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken->printForm);
}
SyntaxErrorMessage(theEnv,"name restriction in object pattern");
ReturnLHSParseNodes(theEnv,tmpNode);
RemoveConstraint(theEnv,rv);
return NULL;
}
tmpNode->derivedConstraints = 1;
return(tmpNode);
}
static struct lhsParseNode *ParseSlotRestriction(
Environment *theEnv,
const char *readSource,
struct token *theToken,
CONSTRAINT_RECORD *slotConstraints,
bool multip)
{
struct lhsParseNode *tmpNode;
CLIPSLexeme *slotName;
slotName = theToken->lexemeValue;
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
tmpNode = RestrictionParse(theEnv,readSource,theToken,multip,slotName,FindSlotNameID(theEnv,slotName),
slotConstraints,1);
if (tmpNode == NULL)
{
RemoveConstraint(theEnv,slotConstraints);
return NULL;
}
if (theToken->tknType != RIGHT_PARENTHESIS_TOKEN)
{
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken->printForm);
SyntaxErrorMessage(theEnv,"object slot pattern");
ReturnLHSParseNodes(theEnv,tmpNode);
RemoveConstraint(theEnv,slotConstraints);
return NULL;
}
if ((tmpNode->bottom == NULL) && (tmpNode->multifieldSlot))
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
}
tmpNode->derivedConstraints = 1;
return(tmpNode);
}
static CLASS_BITMAP *NewClassBitMap(
Environment *theEnv,
unsigned short maxid,
bool set)
{
CLASS_BITMAP *bmp;
size_t size;
size = sizeof(CLASS_BITMAP) + (sizeof(char) * (maxid / BITS_PER_BYTE));
bmp = (CLASS_BITMAP *) gm2(theEnv,size);
ClearBitString(bmp,size);
bmp->maxid = (unsigned short) maxid;
InitializeClassBitMap(theEnv,bmp,set);
return bmp;
}
static void InitializeClassBitMap(
Environment *theEnv,
CLASS_BITMAP *bmp,
bool set)
{
unsigned short i, bytes;
Defclass *cls;
Defmodule *currentModule;
bytes = bmp->maxid / BITS_PER_BYTE + 1;
while (bytes > 0)
{
bmp->map[bytes - 1] = (char) 0;
bytes--;
}
if (set)
{
currentModule = GetCurrentModule(theEnv);
for (i = 0 ; i <= bmp->maxid ; i++)
{
cls = DefclassData(theEnv)->ClassIDMap[i];
if ((cls != NULL) ? DefclassInScope(theEnv,cls,currentModule) : false)
{
if (cls->reactive && (cls->abstract == 0))
SetBitMap(bmp->map,i);
}
}
}
}
static void DeleteIntermediateClassBitMap(
Environment *theEnv,
CLASS_BITMAP *bmp)
{
rm(theEnv,bmp,ClassBitMapSize(bmp));
}
static void *CopyClassBitMap(
Environment *theEnv,
void *gset)
{
#if MAC_XCD
#pragma unused(theEnv)
#endif
if (gset != NULL)
IncrementBitMapCount(gset);
return(gset);
}
static void DeleteClassBitMap(
Environment *theEnv,
void *gset)
{
if (gset == NULL)
return;
DecrementBitMapReferenceCount(theEnv,(CLIPSBitMap *) gset);
}
static void MarkBitMapClassesBusy(
Environment *theEnv,
CLIPSBitMap *bmphn,
int offset)
{
CLASS_BITMAP *bmp;
unsigned short i;
Defclass *cls;
if (ConstructData(theEnv)->ClearInProgress)
return;
bmp = (CLASS_BITMAP *) bmphn->contents;
for (i = 0 ; i <= bmp->maxid ; i++)
if (TestBitMap(bmp->map,i))
{
cls = DefclassData(theEnv)->ClassIDMap[i];
cls->busy += (unsigned int) offset;
}
}
static bool EmptyClassBitMap(
CLASS_BITMAP *bmp)
{
unsigned short bytes;
bytes = (unsigned short) (bmp->maxid / BITS_PER_BYTE + 1);
while (bytes > 0)
{
if (bmp->map[bytes - 1] != (char) 0)
return false;
bytes--;
}
return true;
}
static bool IdenticalClassBitMap(
CLASS_BITMAP *cs1,
CLASS_BITMAP *cs2)
{
unsigned short i;
if (cs1->maxid != cs2->maxid)
return false;
for (i = 0 ; i < (cs1->maxid / BITS_PER_BYTE + 1) ; i++)
if (cs1->map[i] != cs2->map[i])
return false;
return true;
}
static bool ProcessClassRestriction(
Environment *theEnv,
CLASS_BITMAP *clsset,
struct lhsParseNode **classRestrictions,
bool recursiveCall)
{
struct lhsParseNode *chk,**oraddr;
CLASS_BITMAP *tmpset1,*tmpset2;
bool constant_restriction = true;
if (*classRestrictions == NULL)
{
if (recursiveCall)
InitializeClassBitMap(theEnv,clsset,true);
return true;
}
tmpset1 = NewClassBitMap(theEnv,DefclassData(theEnv)->MaxClassID - 1,1);
tmpset2 = NewClassBitMap(theEnv,DefclassData(theEnv)->MaxClassID - 1,0);
for (chk = *classRestrictions ; chk != NULL ; chk = chk->right)
{
if (chk->pnType == SYMBOL_NODE)
{
const char *className = chk->lexemeValue->contents;
chk->value = LookupDefclassByMdlOrScope(theEnv,className);
if (chk->value == NULL)
{
PrintErrorID(theEnv,"OBJRTBLD",5,false);
WriteString(theEnv,STDERR,"Undefined class '");
WriteString(theEnv,STDERR,className);
WriteString(theEnv,STDERR,"' in object pattern.\n");
DeleteIntermediateClassBitMap(theEnv,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset2);
return false;
}
if (chk->negated)
{
InitializeClassBitMap(theEnv,tmpset2,true);
MarkBitMapSubclasses(tmpset2->map,(Defclass *) chk->value,0);
}
else
{
InitializeClassBitMap(theEnv,tmpset2,false);
MarkBitMapSubclasses(tmpset2->map,(Defclass *) chk->value,1);
}
IntersectClassBitMaps(tmpset1,tmpset2);
}
else
constant_restriction = false;
}
if (EmptyClassBitMap(tmpset1))
{
PrintErrorID(theEnv,"OBJRTBLD",2,false);
WriteString(theEnv,STDERR,"No objects of existing classes can satisfy ");
WriteString(theEnv,STDERR,"'is-a' restriction in object pattern.\n");
DeleteIntermediateClassBitMap(theEnv,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset2);
return false;
}
if (constant_restriction)
{
chk = *classRestrictions;
*classRestrictions = chk->bottom;
chk->bottom = NULL;
ReturnLHSParseNodes(theEnv,chk);
oraddr = classRestrictions;
}
else
oraddr = &(*classRestrictions)->bottom;
UnionClassBitMaps(clsset,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset2);
return(ProcessClassRestriction(theEnv,clsset,oraddr,false));
}
static CONSTRAINT_RECORD *ProcessSlotRestriction(
Environment *theEnv,
CLASS_BITMAP *clsset,
CLIPSLexeme *slotName,
bool *multip)
{
Defclass *cls;
int si;
CONSTRAINT_RECORD *totalConstraints = NULL,*tmpConstraints;
unsigned i;
*multip = false;
for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)
for (cls = DefclassData(theEnv)->ClassTable[i] ; cls != NULL ; cls = cls->nxtHash)
{
if (TestBitMap(clsset->map,cls->id))
{
si = FindInstanceTemplateSlot(theEnv,cls,slotName);
if ((si != -1) ? cls->instanceTemplate[si]->reactive : false)
{
if (cls->instanceTemplate[si]->multiple)
*multip = true;
tmpConstraints =
UnionConstraints(theEnv,cls->instanceTemplate[si]->constraint,totalConstraints);
RemoveConstraint(theEnv,totalConstraints);
totalConstraints = tmpConstraints;
}
else
ClearBitMap(clsset->map,cls->id);
}
}
return(totalConstraints);
}
static void IntersectClassBitMaps(
CLASS_BITMAP *cs1,
CLASS_BITMAP *cs2)
{
unsigned short bytes;
bytes = (unsigned short) (cs2->maxid / BITS_PER_BYTE + 1);
while (bytes > 0)
{
cs1->map[bytes - 1] &= cs2->map[bytes - 1];
bytes--;
}
}
static void UnionClassBitMaps(
CLASS_BITMAP *cs1,
CLASS_BITMAP *cs2)
{
unsigned short bytes;
bytes = (unsigned short) (cs2->maxid / BITS_PER_BYTE + 1);
while (bytes > 0)
{
cs1->map[bytes - 1] |= cs2->map[bytes - 1];
bytes--;
}
}
static CLASS_BITMAP *PackClassBitMap(
Environment *theEnv,
CLASS_BITMAP *oldset)
{
unsigned short newmaxid;
CLASS_BITMAP *newset;
for (newmaxid = oldset->maxid ; newmaxid > 0 ; newmaxid--)
if (TestBitMap(oldset->map,newmaxid))
break;
if (newmaxid != oldset->maxid)
{
newset = NewClassBitMap(theEnv,newmaxid,0);
GenCopyMemory(char,newmaxid / BITS_PER_BYTE + 1,newset->map,oldset->map);
DeleteIntermediateClassBitMap(theEnv,oldset);
}
else
newset = oldset;
return(newset);
}
static struct lhsParseNode *FilterObjectPattern(
Environment *theEnv,
struct patternParser *selfPatternType,
struct lhsParseNode *unfilteredSlots,
struct lhsParseNode **bitmap_slot,
struct lhsParseNode **isa_slot,
struct lhsParseNode **name_slot)
{
struct lhsParseNode *prv,*cur;
*isa_slot = NULL;
*name_slot = NULL;
*bitmap_slot = GetLHSParseNode(theEnv);
(*bitmap_slot)->pnType = SF_WILDCARD_NODE;
(*bitmap_slot)->slot = DefclassData(theEnv)->ISA_SYMBOL;
(*bitmap_slot)->slotNumber = ISA_ID;
(*bitmap_slot)->index = 1;
(*bitmap_slot)->patternType = selfPatternType;
(*bitmap_slot)->userData = unfilteredSlots->userData;
unfilteredSlots->userData = NULL;
prv = NULL;
cur = unfilteredSlots;
while (cur != NULL)
{
if (cur->slot == DefclassData(theEnv)->ISA_SYMBOL)
*isa_slot = cur;
else if (cur->slot == DefclassData(theEnv)->NAME_SYMBOL)
*name_slot = cur;
prv = cur;
cur = cur->right;
}
if (prv == NULL)
unfilteredSlots = *bitmap_slot;
else
prv->right = *bitmap_slot;
return(unfilteredSlots);
}
static CLIPSBitMap *FormSlotBitMap(
Environment *theEnv,
struct lhsParseNode *thePattern)
{
struct lhsParseNode *node;
unsigned short maxSlotID = USHRT_MAX;
unsigned size;
SLOT_BITMAP *bmp;
CLIPSBitMap *hshBmp;
for (node = thePattern ; node != NULL ; node = node->right)
{
if (((node->slotNumber > maxSlotID) ||
(maxSlotID == USHRT_MAX)) &&
(node->slotNumber != UNSPECIFIED_SLOT))
{ maxSlotID = node->slotNumber; }
}
if ((maxSlotID == ISA_ID) ||
(maxSlotID == NAME_ID) ||
(maxSlotID == USHRT_MAX))
{ return NULL; }
size = (sizeof(SLOT_BITMAP) + (sizeof(char) * (maxSlotID / BITS_PER_BYTE)));
bmp = (SLOT_BITMAP *) gm2(theEnv,size);
ClearBitString(bmp,size);
bmp->maxid = (unsigned short) maxSlotID;
for (node = thePattern ; node != NULL ; node = node->right)
{ SetBitMap(bmp->map,node->slotNumber); }
hshBmp = (CLIPSBitMap *) AddBitMap(theEnv,bmp,SlotBitMapSize(bmp));
rm(theEnv,bmp,size);
return hshBmp;
}
static struct lhsParseNode *RemoveSlotExistenceTests(
Environment *theEnv,
struct lhsParseNode *thePattern,
CLIPSBitMap **bmp)
{
struct lhsParseNode *tempPattern = thePattern;
struct lhsParseNode *lastPattern = NULL, *head = thePattern;
while (tempPattern != NULL)
{
if (tempPattern->userData != NULL)
{
*bmp = (CLIPSBitMap *) tempPattern->userData;
lastPattern = tempPattern;
tempPattern = tempPattern->right;
}
else if (((tempPattern->pnType == SF_WILDCARD_NODE) ||
(tempPattern->pnType == SF_VARIABLE_NODE)) &&
(tempPattern->networkTest == NULL))
{
if (lastPattern != NULL) lastPattern->right = tempPattern->right;
else head = tempPattern->right;
tempPattern->right = NULL;
ReturnLHSParseNodes(theEnv,tempPattern);
if (lastPattern != NULL) tempPattern = lastPattern->right;
else tempPattern = head;
}
else if (((tempPattern->pnType == MF_WILDCARD_NODE) || (tempPattern->pnType == MF_VARIABLE_NODE)) &&
(tempPattern->multifieldSlot == false) &&
(tempPattern->networkTest == NULL) &&
(tempPattern->multiFieldsBefore == 0) &&
(tempPattern->multiFieldsAfter == 0))
{
if (lastPattern != NULL) lastPattern->right = tempPattern->right;
else head = tempPattern->right;
tempPattern->right = NULL;
ReturnLHSParseNodes(theEnv,tempPattern);
if (lastPattern != NULL) tempPattern = lastPattern->right;
else tempPattern = head;
}
else if (((tempPattern->pnType == MF_WILDCARD_NODE) || (tempPattern->pnType == MF_VARIABLE_NODE)) &&
(tempPattern->multifieldSlot == false) &&
(tempPattern->networkTest != NULL) &&
(tempPattern->multiFieldsBefore == 0) &&
(tempPattern->multiFieldsAfter == 0))
{
tempPattern->pnType = SF_WILDCARD_NODE;
lastPattern = tempPattern;
tempPattern = tempPattern->right;
}
else if ((tempPattern->pnType == MF_WILDCARD_NODE) &&
(tempPattern->multifieldSlot == true) &&
(tempPattern->bottom == NULL))
{
tempPattern->pnType = SF_WILDCARD_NODE;
GenObjectZeroLengthTest(theEnv,tempPattern);
tempPattern->multifieldSlot = false;
lastPattern = tempPattern;
tempPattern = tempPattern->right;
}
else if ((tempPattern->pnType == MF_WILDCARD_NODE) &&
(tempPattern->multifieldSlot == true))
{
GenObjectLengthTest(theEnv,tempPattern->bottom);
tempPattern->bottom = RemoveSlotExistenceTests(theEnv,tempPattern->bottom,bmp);
if (tempPattern->bottom == NULL)
{
if (lastPattern != NULL) lastPattern->right = tempPattern->right;
else head = tempPattern->right;
tempPattern->right = NULL;
ReturnLHSParseNodes(theEnv,tempPattern);
if (lastPattern != NULL) tempPattern = lastPattern->right;
else tempPattern = head;
}
else
{
lastPattern = tempPattern;
tempPattern = tempPattern->right;
}
}
else
{
lastPattern = tempPattern;
tempPattern = tempPattern->right;
}
}
return(head);
}
#endif
static Expression *ObjectMatchDelayParse(
Environment *theEnv,
struct expr *top,
const char *infile)
{
struct token tkn;
IncrementIndentDepth(theEnv,3);
PPCRAndIndent(theEnv);
top->argList = GroupActions(theEnv,infile,&tkn,true,NULL,false);
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,tkn.printForm);
DecrementIndentDepth(theEnv,3);
if (top->argList == NULL)
{
ReturnExpression(theEnv,top);
return NULL;
}
return(top);
}
#if (! BLOAD_ONLY) && (! RUN_TIME)
static void MarkObjectPtnIncrementalReset(
Environment *theEnv,
struct patternNodeHeader *thePattern,
bool value)
{
#if MAC_XCD
#pragma unused(theEnv)
#endif
if (thePattern->initialize == false)
return;
thePattern->initialize = value;
}
static void ObjectIncrementalReset(
Environment *theEnv)
{
Instance *ins;
for (ins = InstanceData(theEnv)->InstanceList ; ins != NULL ; ins = ins->nxtList)
ObjectNetworkAction(theEnv,OBJECT_ASSERT,ins,-1);
}
#endif
#endif