📄 objrtfnx.c
字号:
hack = (struct ObjectCmpJoinSingleSlotVars2 *) ValueToBitMap(theValue); GetPatternObjectAndMarks(((int) hack->firstPattern) - 1,&ins1,&theMarks); GetInsMultiSlotField(&f1,ins1,(unsigned) hack->firstSlot, (unsigned) hack->fromBeginning,(unsigned) hack->offset); GetPatternObjectAndMarks(((int) hack->secondPattern) - 1,&ins2,&theMarks); is2 = GetInsSlot(ins2,hack->secondSlot); if (f1.type != is2->type) rv = hack->fail; else if (f1.value != is2->value) rv = hack->fail; else rv = hack->pass; theResult->type = SYMBOL; theResult->value = rv ? CLIPSTrueSymbol : CLIPSFalseSymbol; return(rv); }#if IBM_TBC && (! DEVELOPER)#pragma argsused#endifstatic VOID PrintJNSimpleCompareFunction3(logicalName,theValue) char *logicalName; VOID *theValue; {#if DEVELOPER struct ObjectCmpJoinSingleSlotVars3 *hack; hack = (struct ObjectCmpJoinSingleSlotVars3 *) ValueToBitMap(theValue); PrintCLIPS(logicalName,"(jslot-cmp3 "); PrintCLIPS(logicalName,hack->pass ? "p " : "n "); PrintLongInteger(logicalName,(long) hack->firstPattern); PrintCLIPS(logicalName," "); PrintCLIPS(logicalName,ValueToString(FindIDSlotName((unsigned) hack->firstSlot))); PrintCLIPS(logicalName,hack->firstFromBeginning ? " B" : " E"); PrintLongInteger(logicalName,(long) hack->firstOffset); PrintCLIPS(logicalName," "); PrintLongInteger(logicalName,(long) hack->secondPattern); PrintCLIPS(logicalName," "); PrintCLIPS(logicalName,ValueToString(FindIDSlotName((unsigned) hack->secondSlot))); PrintCLIPS(logicalName,hack->secondFromBeginning ? " B" : " E"); PrintLongInteger(logicalName,(long) hack->secondOffset); PrintCLIPS(logicalName,")");#else#if MAC_MPW || MAC_MCW#pragma unused(logicalName)#pragma unused(theValue)#endif#endif } static BOOLEAN JNSimpleCompareFunction3(theValue,theResult) VOID *theValue; DATA_OBJECT *theResult; { INSTANCE_TYPE *ins1,*ins2; struct multifieldMarker *theMarks; struct ObjectCmpJoinSingleSlotVars3 *hack; int rv; FIELD f1,f2; hack = (struct ObjectCmpJoinSingleSlotVars3 *) ValueToBitMap(theValue); GetPatternObjectAndMarks(((int) hack->firstPattern) - 1,&ins1,&theMarks); GetInsMultiSlotField(&f1,ins1,(unsigned) hack->firstSlot, (unsigned) hack->firstFromBeginning, (unsigned) hack->firstOffset); GetPatternObjectAndMarks(((int) hack->secondPattern) - 1,&ins2,&theMarks); GetInsMultiSlotField(&f2,ins2,(unsigned) hack->secondSlot, (unsigned) hack->secondFromBeginning, (unsigned) hack->secondOffset); if (f1.type != f2.type) rv = hack->fail; else if (f1.value != f2.value) rv = hack->fail; else rv = hack->pass; theResult->type = SYMBOL; theResult->value = rv ? CLIPSTrueSymbol : CLIPSFalseSymbol; return(rv); }/**************************************************** NAME : GetPatternObjectAndMarks DESCRIPTION : Finds the instance and multfiield markers corresponding to a specified pattern in the join network INPUTS : 1) The index of the desired pattern 2) A buffer to hold the instance address 3) A buffer to hold the list of multifield markers RETURNS : Nothing useful SIDE EFFECTS : Buffers set NOTES : None ****************************************************/static VOID GetPatternObjectAndMarks(pattern,theInstance,theMarkers) int pattern; INSTANCE_TYPE **theInstance; struct multifieldMarker **theMarkers; { if (GlobalRHSBinds == NULL) { *theInstance = (INSTANCE_TYPE *) get_nth_pm_match(GlobalLHSBinds,pattern)->matchingItem; *theMarkers = get_nth_pm_match(GlobalLHSBinds,pattern)->markers; } else if ((GlobalJoin->depth - 1) == pattern) { *theInstance = (INSTANCE_TYPE *) get_nth_pm_match(GlobalRHSBinds,0)->matchingItem; *theMarkers = get_nth_pm_match(GlobalRHSBinds,0)->markers; } else { *theInstance = (INSTANCE_TYPE *) get_nth_pm_match(GlobalLHSBinds,pattern)->matchingItem; *theMarkers = get_nth_pm_match(GlobalLHSBinds,pattern)->markers; } }/*************************************************** NAME : GetObjectValueGeneral DESCRIPTION : Access function for getting pattern variable values within the object pattern and join networks INPUTS : 1) The result data object buffer 2) The instance to access 3) The list of multifield markers for the pattern 4) Data for variable reference RETURNS : Nothing useful SIDE EFFECTS : Data object is filled with the values of the pattern variable NOTES : None ***************************************************/static VOID GetObjectValueGeneral(result,theInstance,theMarks,matchVar) DATA_OBJECT *result; INSTANCE_TYPE *theInstance; struct multifieldMarker *theMarks; struct ObjectMatchVar1 *matchVar; { long field, extent; /* 6.04 Bug Fix */ INSTANCE_SLOT **insSlot,*basisSlot; if (matchVar->objectAddress) { result->type = INSTANCE_ADDRESS; result->value = (VOID *) theInstance; return; } if (matchVar->whichSlot == ISA_ID) { result->type = SYMBOL; result->value = (VOID *) GetDefclassNamePointer((VOID *) theInstance->cls); return; } if (matchVar->whichSlot == NAME_ID) { result->type = INSTANCE_NAME; result->value = (VOID *) theInstance->name; return; } insSlot = &theInstance->slotAddresses [theInstance->cls->slotNameMap[matchVar->whichSlot] - 1]; /* ========================================= We need to reference the basis slots if the slot of this object has changed while the RHS was executing However, if the reference is being done by the LHS of a rule (as a consequence of an RHS action), give the pattern matcher the real value of the slot ========================================= */ if ((theInstance->basisSlots != NULL) && (!JoinOperationInProgress)) { basisSlot = theInstance->basisSlots + (insSlot - theInstance->slotAddresses); if (basisSlot->value != NULL) insSlot = &basisSlot; } /* ================================================== If we know we are accessing the entire slot, the don't bother with searching multifield markers or calculating offsets ================================================== */ if (matchVar->allFields) { result->type = (int) (*insSlot)->type; result->value = (*insSlot)->value; if (result->type == MULTIFIELD) { result->begin = 0; result->end = GetMFLength((*insSlot)->value) - 1; } return; } /* ============================================= Access a general field in a slot pattern with two or more multifield variables ============================================= */ field = CalculateSlotField(theMarks,*insSlot,matchVar->whichField,&extent); if (extent == -1) { if ((*insSlot)->desc->multiple) { result->type = GetMFType((*insSlot)->value,field); result->value = GetMFValue((*insSlot)->value,field); } else { result->type = (*insSlot)->type; result->value = (*insSlot)->value; } } else { result->type = MULTIFIELD; result->value = (*insSlot)->value; result->begin = field - 1; result->end = field + extent - 2; } } /*************************************************** NAME : GetObjectValueSimple DESCRIPTION : Access function for getting pattern variable values within the object pattern and join networks INPUTS : 1) The result data object buffer 2) The instance to access 3) Data for variable reference RETURNS : Nothing useful SIDE EFFECTS : Data object is filled with the values of the pattern variable NOTES : None ***************************************************/static VOID GetObjectValueSimple(result,theInstance,matchVar) DATA_OBJECT *result; INSTANCE_TYPE *theInstance; struct ObjectMatchVar2 *matchVar; { INSTANCE_SLOT **insSlot,*basisSlot; SEGMENT *segmentPtr; FIELD *fieldPtr; insSlot = &theInstance->slotAddresses [theInstance->cls->slotNameMap[matchVar->whichSlot] - 1]; /* ========================================= We need to reference the basis slots if the slot of this object has changed while the RHS was executing However, if the reference is being done by the LHS of a rule (as a consequence of an RHS action), give the pattern matcher the real value of the slot ========================================= */ if ((theInstance->basisSlots != NULL) && (!JoinOperationInProgress)) { basisSlot = theInstance->basisSlots + (insSlot - theInstance->slotAddresses); if (basisSlot->value != NULL) insSlot = &basisSlot; } /* Bug fix for 6.05 */ if ((*insSlot)->desc->multiple) { segmentPtr = (SEGMENT *) (*insSlot)->value; if (matchVar->fromBeginning) { if (matchVar->fromEnd) { result->type = MULTIFIELD; result->value = (VOID *) segmentPtr; result->begin = matchVar->beginningOffset; result->end = GetMFLength(segmentPtr) - (matchVar->endOffset + 1); } else { fieldPtr = &segmentPtr->theFields[matchVar->beginningOffset]; result->type = fieldPtr->type; result->value = fieldPtr->value; } } else { fieldPtr = &segmentPtr->theFields[segmentPtr->multifieldLength - (matchVar->endOffset + 1)]; result->type = fieldPtr->type; result->value = fieldPtr->value; } } else { result->type = (*insSlot)->type; result->value = (*insSlot)->value; } } /**************************************************** NAME : CalculateSlotField DESCRIPTION : Determines the actual index into the an object slot for a given pattern variable INPUTS : 1) The list of markers to examine 2) The instance slot (can be NULL) 3) The pattern index of the variable 4) A buffer in which to store the extent of the pattern variable (-1 for single-field vars) RETURNS : The actual index SIDE EFFECTS : None NOTES : None ****************************************************/static long CalculateSlotField(theMarkers,theSlot,theIndex,extent) struct multifieldMarker *theMarkers; INSTANCE_SLOT *theSlot; long theIndex; long *extent; /* 6.04 Bug Fix */ { register long actualIndex; VOID *theSlotName; actualIndex = theIndex; *extent = -1; if (theSlot == NULL) return(actualIndex); theSlotName = (VOID *) theSlot->desc->slotName->name; while (theMarkers != NULL) { if (theMarkers->where.whichSlot == theSlotName) break; theMarkers = theMarkers->next; } while ((theMarkers != NULL) ? (theMarkers->where.whichSlot == theSlotName) : CLIPS_FALSE) { if (theMarkers->whichField == theIndex) { *extent = theMarkers->endPosition - theMarkers->startPosition + 1; return(actualIndex); } if (theMarkers->whichField > theIndex) return(actualIndex); actualIndex += theMarkers->endPosition - theMarkers->startPosition; theMarkers = theMarkers->next; } return(actualIndex); }/**************************************************** NAME : GetInsMultiSlotField DESCRIPTION : Gets the values of simple single field references in multifield slots for Rete comparisons INPUTS : 1) A multifield field structure to store the type and value in 2) The instance 3) The id of the slot 4) A flag indicating if offset is from beginning or end of multifield slot 5) The offset RETURNS : The multifield field SIDE EFFECTS : None NOTES : Should only be used to access single-field reference in multifield slots for pattern and join network comparisons ****************************************************/static void GetInsMultiSlotField(theField,theInstance,theSlotID,fromBeginning,offset) FIELD *theField; INSTANCE_TYPE *theInstance; unsigned theSlotID,fromBeginning,offset; { register INSTANCE_SLOT * insSlot; register SEGMENT *theSegment; register FIELD *tmpField; insSlot = theInstance->slotAddresses [theInstance->cls->slotNameMap[theSlotID] - 1]; /* Bug fix for 6.05 */ if (insSlot->desc->multiple) { theSegment = (SEGMENT *) insSlot->value; if (fromBeginning) tmpField = &theSegment->theFields[offset]; else tmpField = &theSegment->theFields[theSegment->multifieldLength - offset - 1]; theField->type = tmpField->type; theField->value = tmpField->value; } else { theField->type = insSlot->type; theField->value = insSlot->value; } } #endif/*************************************************** NAME : DESCRIPTION : INPUTS : RETURNS : SIDE EFFECTS : NOTES : ***************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -