globle struct expr *ParseAssertTemplate( char *readSource, struct token *theToken, int *error, int endType, int constantsOnly, struct deftemplate *theDeftemplate) { struct expr *firstSlot, *lastSlot, *nextSlot; struct expr *firstArg, *tempSlot; struct templateSlot *slotPtr; firstSlot = NULL; lastSlot = NULL; /*==============================================*/ /* Parse each of the slot fields in the assert. */ /*==============================================*/ while ((slotPtr = ParseSlotLabel(readSource,theToken,theDeftemplate,error,endType)) != NULL) { /*========================================================*/ /* Check to see that the slot hasn't already been parsed. */ /*========================================================*/ for (tempSlot = firstSlot; tempSlot != NULL; tempSlot = tempSlot->nextArg) { if (tempSlot->value == (void *) slotPtr->slotName) { AlreadyParsedErrorMessage("slot ",ValueToString(slotPtr->slotName)); *error = TRUE; ReturnExpression(firstSlot); return(NULL); } } #if FUZZY_DEFTEMPLATES /* If the slot was bloaded, there is now an optimisation:- it will only have a constraint record if it was saved with one. Therefore, the test below must first check for the record before checking fuzzy constraints. DPW 20/5/01 */ if ((slotPtr->constraints != NULL) && (slotPtr->constraints->fuzzyValuesAllowed)) { struct expr *newField; struct deftemplate *theFuzzyDeftemplate; /* Fuzzy Deftemplates don't store deftemplate ptr in restrictionList */ if (slotPtr->constraints->fuzzyValueRestriction) theFuzzyDeftemplate = (struct deftemplate *) slotPtr->constraints->restrictionList->value; else theFuzzyDeftemplate = theDeftemplate; newField = ParseAssertFuzzyFact(readSource,theToken, error,endType,constantsOnly, theFuzzyDeftemplate, TRUE); /* note: ParseAssertFuzzyFact will have read the ')' of the slot */ /*=========================================================*/ /* Build and return a structure describing the slot value. */ /*=========================================================*/ if (*error == FALSE) { nextSlot = GenConstant(SYMBOL,slotPtr->slotName); nextSlot->argList = newField; } } else nextSlot = ParseAssertSlotValues(readSource,theToken, slotPtr,error,constantsOnly); #else /*============================================*/ /* Parse the values to be stored in the slot. */ /*============================================*/ nextSlot = ParseAssertSlotValues(readSource,theToken, slotPtr,error,constantsOnly); #endif /* FUZZY_DEFTEMPLATES */ if (*error) { ReturnExpression(firstSlot); return(NULL); } /*============================================*/ /* Check to see if the values to be stored in */ /* the slot violate the slot's constraints. */ /*============================================*/ if (CheckRHSSlotTypes(nextSlot->argList,slotPtr,"assert") == 0) { *error = TRUE; ReturnExpression(firstSlot); ReturnExpression(nextSlot); return(NULL); } /*===================================================*/ /* Add the slot to the list of slots already parsed. */ /*===================================================*/ if (lastSlot == NULL) { firstSlot = nextSlot; } else { lastSlot->nextArg = nextSlot; } lastSlot = nextSlot; } /*=================================================*/ /* Return if an error occured parsing a slot name. */ /*=================================================*/ if (*error) { ReturnExpression(firstSlot); return(NULL); } /*=============================================================*/ /* Reorder the arguments to the order used by the deftemplate. */ /*=============================================================*/ firstArg = ReorderAssertSlotValues(theDeftemplate->slotList,firstSlot,error); ReturnExpression(firstSlot); /*==============================*/ /* Return the assert arguments. */ /*==============================*/ return(firstArg); }
globle BOOLEAN UpdateModifyDuplicate( void *theEnv, struct expr *top, char *name, void *vTheLHS) { struct expr *functionArgs, *tempArg; SYMBOL_HN *templateName; struct deftemplate *theDeftemplate; struct templateSlot *slotPtr; short position; /*========================================*/ /* Determine the fact-address or index to */ /* be retracted by the modify command. */ /*========================================*/ functionArgs = top->argList; if (functionArgs->type == SF_VARIABLE) { templateName = FindTemplateForFactAddress((SYMBOL_HN *) functionArgs->value, (struct lhsParseNode *) vTheLHS); if (templateName == NULL) return(TRUE); } else { return(TRUE); } /*========================================*/ /* Make sure that the fact being modified */ /* has a corresponding deftemplate. */ /*========================================*/ theDeftemplate = (struct deftemplate *) LookupConstruct(theEnv,DeftemplateData(theEnv)->DeftemplateConstruct, ValueToString(templateName), FALSE); if (theDeftemplate == NULL) return(TRUE); if (theDeftemplate->implied) return(TRUE); /*=============================================================*/ /* Make sure all the slot names are valid for the deftemplate. */ /*=============================================================*/ tempArg = functionArgs->nextArg; while (tempArg != NULL) { /*======================*/ /* Does the slot exist? */ /*======================*/ if ((slotPtr = FindSlot(theDeftemplate,(SYMBOL_HN *) tempArg->value,&position)) == NULL) { InvalidDeftemplateSlotMessage(theEnv,ValueToString(tempArg->value), ValueToString(theDeftemplate->header.name)); return(FALSE); } /*=========================================================*/ /* Is a multifield value being put in a single field slot? */ /*=========================================================*/ if (slotPtr->multislot == FALSE) { if (tempArg->argList == NULL) { SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents); return(FALSE); } else if (tempArg->argList->nextArg != NULL) { SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents); return(FALSE); } else if ((tempArg->argList->type == MF_VARIABLE) || ((tempArg->argList->type == FCALL) ? (((struct FunctionDefinition *) tempArg->argList->value)->returnValueType == 'm') : FALSE)) { SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents); return(FALSE); } } /*======================================*/ /* Are the slot restrictions satisfied? */ /*======================================*/ if (CheckRHSSlotTypes(theEnv,tempArg->argList,slotPtr,name) == 0) return(FALSE); /*=============================================*/ /* Replace the slot with the integer position. */ /*=============================================*/ tempArg->type = INTEGER; tempArg->value = (void *) EnvAddLong(theEnv,(long) (FindSlotPosition(theDeftemplate,(SYMBOL_HN *) tempArg->value) - 1)); tempArg = tempArg->nextArg; } return(TRUE); }
globle struct expr *ParseAssertTemplate( char *readSource, struct token *theToken, int *error, int endType, int constantsOnly, struct deftemplate *theDeftemplate) { struct expr *firstSlot, *lastSlot, *nextSlot; struct expr *firstArg, *tempSlot; struct templateSlot *slotPtr; firstSlot = NULL; lastSlot = NULL; /*==============================================*/ /* Parse each of the slot fields in the assert. */ /*==============================================*/ while ((slotPtr = ParseSlotLabel(readSource,theToken,theDeftemplate,error,endType)) != NULL) { /*========================================================*/ /* Check to see that the slot hasn't already been parsed. */ /*========================================================*/ for (tempSlot = firstSlot; tempSlot != NULL; tempSlot = tempSlot->nextArg) { if (tempSlot->value == (void *) slotPtr->slotName) { AlreadyParsedErrorMessage("slot ",ValueToString(slotPtr->slotName)); *error = TRUE; ReturnExpression(firstSlot); return(NULL); } } /*============================================*/ /* Parse the values to be stored in the slot. */ /*============================================*/ nextSlot = ParseAssertSlotValues(readSource,theToken, slotPtr,error,constantsOnly); if (*error) { ReturnExpression(firstSlot); return(NULL); } /*============================================*/ /* Check to see if the values to be stored in */ /* the slot violate the slot's constraints. */ /*============================================*/ if (CheckRHSSlotTypes(nextSlot->argList,slotPtr,"assert") == 0) { *error = TRUE; ReturnExpression(firstSlot); ReturnExpression(nextSlot); return(NULL); } /*===================================================*/ /* Add the slot to the list of slots already parsed. */ /*===================================================*/ if (lastSlot == NULL) { firstSlot = nextSlot; } else { lastSlot->nextArg = nextSlot; } lastSlot = nextSlot; } /*=================================================*/ /* Return if an error occured parsing a slot name. */ /*=================================================*/ if (*error) { ReturnExpression(firstSlot); return(NULL); } /*=============================================================*/ /* Reorder the arguments to the order used by the deftemplate. */ /*=============================================================*/ firstArg = ReorderAssertSlotValues(theDeftemplate->slotList,firstSlot,error); ReturnExpression(firstSlot); /*==============================*/ /* Return the assert arguments. */ /*==============================*/ return(firstArg); }