globle int ParseDeftemplate( void *theEnv, char *readSource) { #if (MAC_MCW || IBM_MCW) && (RUN_TIME || BLOAD_ONLY) #pragma unused(readSource) #endif #if (! RUN_TIME) && (! BLOAD_ONLY) SYMBOL_HN *deftemplateName; struct deftemplate *newDeftemplate; struct templateSlot *slots; struct token inputToken; /*================================================*/ /* Initialize pretty print and error information. */ /*================================================*/ DeftemplateData(theEnv)->DeftemplateError = FALSE; SetPPBufferStatus(theEnv,ON); FlushPPBuffer(theEnv); SavePPBuffer(theEnv,"(deftemplate "); /*==============================================================*/ /* Deftemplates can not be added when a binary image is loaded. */ /*==============================================================*/ #if BLOAD || BLOAD_AND_BSAVE if ((Bloaded(theEnv) == TRUE) && (! ConstructData(theEnv)->CheckSyntaxMode)) { CannotLoadWithBloadMessage(theEnv,"deftemplate"); return(TRUE); } #endif /*=======================================================*/ /* Parse the name and comment fields of the deftemplate. */ /*=======================================================*/ #if DEBUGGING_FUNCTIONS DeftemplateData(theEnv)->DeletedTemplateDebugFlags = 0; #endif deftemplateName = GetConstructNameAndComment(theEnv,readSource,&inputToken,"deftemplate", EnvFindDeftemplate,EnvUndeftemplate,"%", TRUE,TRUE,DEFMODULE_CONSTRUCT); if (deftemplateName == NULL) return(TRUE); if (ReservedPatternSymbol(theEnv,ValueToString(deftemplateName),"deftemplate")) { ReservedPatternSymbolErrorMsg(theEnv,ValueToString(deftemplateName),"a deftemplate name"); return(TRUE); } /*===========================================*/ /* Parse the slot fields of the deftemplate. */ /*===========================================*/ slots = SlotDeclarations(theEnv,readSource,&inputToken); if (DeftemplateData(theEnv)->DeftemplateError == TRUE) return(TRUE); /*==============================================*/ /* If we're only checking syntax, don't add the */ /* successfully parsed deftemplate to the KB. */ /*==============================================*/ if (ConstructData(theEnv)->CheckSyntaxMode) { ReturnSlots(theEnv,slots); return(FALSE); } /*=====================================*/ /* Create a new deftemplate structure. */ /*=====================================*/ newDeftemplate = get_struct(theEnv,deftemplate); newDeftemplate->header.name = deftemplateName; newDeftemplate->header.next = NULL; newDeftemplate->header.usrData = NULL; newDeftemplate->slotList = slots; newDeftemplate->implied = FALSE; newDeftemplate->numberOfSlots = 0; newDeftemplate->busyCount = 0; newDeftemplate->watch = 0; newDeftemplate->inScope = TRUE; newDeftemplate->patternNetwork = NULL; newDeftemplate->factList = NULL; newDeftemplate->lastFact = NULL; newDeftemplate->header.whichModule = (struct defmoduleItemHeader *) GetModuleItem(theEnv,NULL,DeftemplateData(theEnv)->DeftemplateModuleIndex); /*================================*/ /* Determine the number of slots. */ /*================================*/ while (slots != NULL) { newDeftemplate->numberOfSlots++; slots = slots->next; } /*====================================*/ /* Store pretty print representation. */ /*====================================*/ if (EnvGetConserveMemory(theEnv) == TRUE) { newDeftemplate->header.ppForm = NULL; } else { newDeftemplate->header.ppForm = CopyPPBuffer(theEnv); } /*=======================================================================*/ /* If a template is redefined, then we want to restore its watch status. */ /*=======================================================================*/ #if DEBUGGING_FUNCTIONS if ((BitwiseTest(DeftemplateData(theEnv)->DeletedTemplateDebugFlags,0)) || EnvGetWatchItem(theEnv,"facts")) { EnvSetDeftemplateWatch(theEnv,ON,(void *) newDeftemplate); } #endif /*==============================================*/ /* Add deftemplate to the list of deftemplates. */ /*==============================================*/ AddConstructToModule(&newDeftemplate->header); InstallDeftemplate(theEnv,newDeftemplate); #else #if MAC_MCW || IBM_MCW || MAC_XCD #pragma unused(theEnv) #endif #endif return(FALSE); }
globle struct expr *GetRHSPattern( char *readSource, struct token *tempToken, int *error, int constantsOnly, int readFirstParen, int checkFirstParen, int endType) { struct expr *lastOne = NULL; struct expr *nextOne, *firstOne, *argHead = NULL; int printError, count; struct deftemplate *theDeftemplate; struct symbolHashNode *templateName; /*=================================================*/ /* Get the opening parenthesis of the RHS pattern. */ /*=================================================*/ *error = FALSE; if (readFirstParen) GetToken(readSource,tempToken); if (checkFirstParen) { if (tempToken->type == endType) return(NULL); if (tempToken->type != LPAREN) { SyntaxErrorMessage("RHS patterns"); *error = TRUE; return(NULL); } } /*======================================================*/ /* The first field of an asserted fact must be a symbol */ /* (but not = or : which have special significance). */ /*======================================================*/ GetToken(readSource,tempToken); if (tempToken->type != SYMBOL) { SyntaxErrorMessage("first field of a RHS pattern"); *error = TRUE; return(NULL); } else if ((strcmp(ValueToString(tempToken->value),"=") == 0) || (strcmp(ValueToString(tempToken->value),":") == 0)) { SyntaxErrorMessage("first field of a RHS pattern"); *error = TRUE; return(NULL); } /*=========================================================*/ /* Check to see if the relation name is a reserved symbol. */ /*=========================================================*/ templateName = (struct symbolHashNode *) tempToken->value; if (ReservedPatternSymbol(ValueToString(templateName),NULL)) { ReservedPatternSymbolErrorMsg(ValueToString(templateName),"a relation name"); *error = TRUE; return(NULL); } /*============================================================*/ /* A module separator in the name is illegal in this context. */ /*============================================================*/ if (FindModuleSeparator(ValueToString(templateName))) { IllegalModuleSpecifierMessage(); *error = TRUE; return(NULL); } /*=============================================================*/ /* Determine if there is an associated deftemplate. If so, let */ /* the deftemplate parsing functions parse the RHS pattern and */ /* then return the fact pattern that was parsed. */ /*=============================================================*/ theDeftemplate = (struct deftemplate *) FindImportedConstruct("deftemplate",NULL,ValueToString(templateName), &count,TRUE,NULL); if (count > 1) { AmbiguousReferenceErrorMessage("deftemplate",ValueToString(templateName)); *error = TRUE; return(NULL); } /*======================================================*/ /* If no deftemplate exists with the specified relation */ /* name, then create an implied deftemplate. */ /*======================================================*/ if (theDeftemplate == NULL) #if (! BLOAD_ONLY) && (! RUN_TIME) { #if BLOAD || BLOAD_AND_BSAVE if ((Bloaded()) && (! CheckSyntaxMode)) { NoSuchTemplateError(ValueToString(templateName)); *error = TRUE; return(NULL); } #endif #if DEFMODULE_CONSTRUCT if (FindImportExportConflict("deftemplate",((struct defmodule *) GetCurrentModule()),ValueToString(templateName))) { ImportExportConflictMessage("implied deftemplate",ValueToString(templateName),NULL,NULL); *error = TRUE; return(NULL); } #endif if (! CheckSyntaxMode) { theDeftemplate = CreateImpliedDeftemplate((SYMBOL_HN *) templateName,TRUE); } } #else { NoSuchTemplateError(ValueToString(templateName)); *error = TRUE; return(NULL); } #endif /*=========================================*/ /* If an explicit deftemplate exists, then */ /* parse the fact as a deftemplate fact. */ /*=========================================*/ if ((theDeftemplate != NULL) && (theDeftemplate->implied == FALSE)) { firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate); firstOne->nextArg = ParseAssertTemplate(readSource,tempToken, error,endType, constantsOnly,theDeftemplate); if (*error) { ReturnExpression(firstOne); firstOne = NULL; } return(firstOne); } /*========================================*/ /* Parse the fact as an ordered RHS fact. */ /*========================================*/ firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate); #if (! RUN_TIME) && (! BLOAD_ONLY) SavePPBuffer(" "); #endif while ((nextOne = GetAssertArgument(readSource,tempToken, error,endType,constantsOnly,&printError)) != NULL) { if (argHead == NULL) argHead = nextOne; else lastOne->nextArg = nextOne; lastOne = nextOne; #if (! RUN_TIME) && (! BLOAD_ONLY) SavePPBuffer(" "); #endif } /*===========================================================*/ /* If an error occurred, set the error flag and return NULL. */ /*===========================================================*/ if (*error) { if (printError) SyntaxErrorMessage("RHS patterns"); ReturnExpression(firstOne); ReturnExpression(argHead); return(NULL); } /*=====================================*/ /* Fix the pretty print representation */ /* of the RHS ordered fact. */ /*=====================================*/ #if (! RUN_TIME) && (! BLOAD_ONLY) PPBackup(); PPBackup(); SavePPBuffer(tempToken->printForm); #endif /*==========================================================*/ /* Ordered fact assertions are processed by stuffing all of */ /* the fact's proposition (except the relation name) into a */ /* single multifield slot. */ /*==========================================================*/ firstOne->nextArg = GenConstant(FACT_STORE_MULTIFIELD,AddBitMap("\0",1)); firstOne->nextArg->argList = argHead; /*==============================*/ /* Return the RHS ordered fact. */ /*==============================*/ return(firstOne); }
globle struct expr *GetRHSPattern( char *readSource, struct token *tempToken, int *error, int constantsOnly, int readFirstParen, int checkFirstParen, int endType) { struct expr *lastOne = NULL; struct expr *nextOne, *firstOne, *argHead = NULL; int printError, count; struct deftemplate *theDeftemplate; struct symbolHashNode *templateName; /*=================================================*/ /* Get the opening parenthesis of the RHS pattern. */ /*=================================================*/ *error = FALSE; if (readFirstParen) GetToken(readSource,tempToken); if (checkFirstParen) { if (tempToken->type == endType) return(NULL); if (tempToken->type != LPAREN) { SyntaxErrorMessage("RHS patterns"); *error = TRUE; return(NULL); } } /*======================================================*/ /* The first field of an asserted fact must be a symbol */ /* (but not = or : which have special significance). */ /*======================================================*/ GetToken(readSource,tempToken); if (tempToken->type != SYMBOL) { SyntaxErrorMessage("first field of a RHS pattern"); *error = TRUE; return(NULL); } else if ((strcmp(ValueToString(tempToken->value),"=") == 0) || (strcmp(ValueToString(tempToken->value),":") == 0)) { SyntaxErrorMessage("first field of a RHS pattern"); *error = TRUE; return(NULL); } /*=========================================================*/ /* Check to see if the relation name is a reserved symbol. */ /*=========================================================*/ templateName = (struct symbolHashNode *) tempToken->value; if (ReservedPatternSymbol(ValueToString(templateName),NULL)) { ReservedPatternSymbolErrorMsg(ValueToString(templateName),"a relation name"); *error = TRUE; return(NULL); } /*============================================================*/ /* A module separator in the name is illegal in this context. */ /*============================================================*/ if (FindModuleSeparator(ValueToString(templateName))) { IllegalModuleSpecifierMessage(); *error = TRUE; return(NULL); } /*=============================================================*/ /* Determine if there is an associated deftemplate. If so, let */ /* the deftemplate parsing functions parse the RHS pattern and */ /* then return the fact pattern that was parsed. */ /*=============================================================*/ theDeftemplate = (struct deftemplate *) FindImportedConstruct("deftemplate",NULL,ValueToString(templateName), &count,TRUE,NULL); if (count > 1) { AmbiguousReferenceErrorMessage("deftemplate",ValueToString(templateName)); *error = TRUE; return(NULL); } /*======================================================*/ /* If no deftemplate exists with the specified relation */ /* name, then create an implied deftemplate. */ /*======================================================*/ if (theDeftemplate == NULL) #if (! BLOAD_ONLY) && (! RUN_TIME) { #if BLOAD || BLOAD_AND_BSAVE if ((Bloaded()) && (! CheckSyntaxMode)) { NoSuchTemplateError(ValueToString(templateName)); *error = TRUE; return(NULL); } #endif #if DEFMODULE_CONSTRUCT if (FindImportExportConflict("deftemplate",((struct defmodule *) GetCurrentModule()),ValueToString(templateName))) { ImportExportConflictMessage("implied deftemplate",ValueToString(templateName),NULL,NULL); *error = TRUE; return(NULL); } #endif if (! CheckSyntaxMode) { theDeftemplate = CreateImpliedDeftemplate((SYMBOL_HN *) templateName,TRUE); } } #else { NoSuchTemplateError(ValueToString(templateName)); *error = TRUE; return(NULL); } #endif /*=========================================*/ /* If an explicit deftemplate exists, then */ /* parse the fact as a deftemplate fact. */ /*=========================================*/ if ((theDeftemplate != NULL) && (theDeftemplate->implied == FALSE)) { firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate); #if FUZZY_DEFTEMPLATES if (theDeftemplate->fuzzyTemplate != NULL) firstOne->nextArg = ParseAssertFuzzyFact(readSource,tempToken, error,endType, constantsOnly,theDeftemplate, TRUE); else #endif firstOne->nextArg = ParseAssertTemplate(readSource,tempToken, error,endType, constantsOnly,theDeftemplate); if (*error) { ReturnExpression(firstOne); firstOne = NULL; } #if CERTAINTY_FACTORS else { /* if certaintly factors allowed then the next item after a fact specifier COULD be a certainty factor spec --- CF x.xxx */ SavePPBuffer(" "); GetToken(readSource,tempToken); if ((tempToken->type == SYMBOL) && ((strcmp(ValueToString(tempToken->value),"CF") == 0) || (strcmp(ValueToString(tempToken->value),"cf") == 0)) ) { struct expr *CFexpr; /* expecting a certainty factor (float) expression */ /* tokenToFloatExpression expect 1st token already read */ SavePPBuffer(" "); GetToken(readSource,tempToken); CFexpr = tokenToFloatExpression(readSource,tempToken,error,constantsOnly); if (*error) { ReturnExpression(firstOne); return( NULL ); } if (CFexpr->type == FLOAT) /* if constant -- check range */ { double cfval = ValueToDouble(CFexpr->value); if (cfval > 1.0 || cfval < 0.0) { *error = TRUE; ReturnExpression(CFexpr); cfRangeError(); ReturnExpression(firstOne); return( NULL ); } } /* store the CF expression in the argList of the DEFTEMPLATE_PTR expr */ firstOne->argList = CFexpr; } else { /* Do an 'UnGetToken' function here to undo the lookahead for a CF. Also need to PPBackup over the space added before reading the potential CF expression -- UnGetToken does one PPBackup over the token which was added to the PP Buffer */ UnGetToken(tempToken); PPBackup(); } } #endif return(firstOne); } /*========================================*/ /* Parse the fact as an ordered RHS fact. */ /*========================================*/ firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate); #if FUZZY_DEFTEMPLATES /*=============================================*/ /* Fuzzy facts parsed differently */ /*=============================================*/ if (theDeftemplate->fuzzyTemplate != NULL) { firstOne->nextArg = ParseAssertFuzzyFact(readSource,tempToken, error,endType, constantsOnly,theDeftemplate, TRUE); if (*error) { ReturnExpression(firstOne); return(NULL); } } else { /* --- matches } below with FUZZY_DEFTEMPLATES */ #endif /* FUZZY_DEFTEMPLATES */ #if (! RUN_TIME) && (! BLOAD_ONLY) SavePPBuffer(" "); #endif while ((nextOne = GetAssertArgument(readSource,tempToken, error,endType,constantsOnly,&printError)) != NULL) { if (argHead == NULL) argHead = nextOne; else lastOne->nextArg = nextOne; lastOne = nextOne; #if (! RUN_TIME) && (! BLOAD_ONLY) SavePPBuffer(" "); #endif } /*===========================================================*/ /* If an error occurred, set the error flag and return NULL. */ /*===========================================================*/ if (*error) { if (printError) SyntaxErrorMessage("RHS patterns"); ReturnExpression(firstOne); ReturnExpression(argHead); return(NULL); } /*=====================================*/ /* Fix the pretty print representation */ /* of the RHS ordered fact. */ /*=====================================*/ #if (! RUN_TIME) && (! BLOAD_ONLY) PPBackup(); PPBackup(); SavePPBuffer(tempToken->printForm); #endif /*==========================================================*/ /* Ordered fact assertions are processed by stuffing all of */ /* the fact's proposition (except the relation name) into a */ /* single multifield slot. */ /*==========================================================*/ firstOne->nextArg = GenConstant(FACT_STORE_MULTIFIELD,AddBitMap("\0",1)); firstOne->nextArg->argList = argHead; #if FUZZY_DEFTEMPLATES } /* --- matches else { above with FUZZY_DEFTEMPLATES */ #endif #if CERTAINTY_FACTORS /* if certaintly factors allowed then the next item after a fact specifier could be a certainty factor spec --- CF x.xxx */ #if (! RUN_TIME) && (! BLOAD_ONLY) SavePPBuffer(" "); #endif GetToken(readSource,tempToken); if ((tempToken->type == SYMBOL) && ((strcmp(ValueToString(tempToken->value),"CF") == 0) || (strcmp(ValueToString(tempToken->value),"cf") == 0)) ) { struct expr *CFexpr; /* expecting a certainty factor (float) expression */ /* tokenToFloatExpression expect 1st token already read */ #if (! RUN_TIME) && (! BLOAD_ONLY) SavePPBuffer(" "); #endif GetToken(readSource,tempToken); CFexpr = tokenToFloatExpression(readSource,tempToken,error,constantsOnly); if (*error) { ReturnExpression(firstOne); return( NULL ); } if (CFexpr->type == FLOAT) /* if constant -- check range */ { double cfval = ValueToDouble(CFexpr->value); if (cfval > 1.0 || cfval < 0.0) { *error = TRUE; ReturnExpression(CFexpr); cfRangeError(); ReturnExpression(firstOne); return( NULL ); } } /* store the CF expression in the argList of the DEFTEMPLATE_PTR expr */ firstOne->argList = CFexpr; } else { /* Do an 'UnGetToken' function here to undo the lookahead for a CF. Also need to PPBackup over the space added before reading the potential CF expression -- UnGetToken does one PPBackup over the token which was added to the PP Buffer */ UnGetToken(tempToken); #if (! RUN_TIME) && (! BLOAD_ONLY) PPBackup(); #endif } #endif /* CERTAINTY_FACTORS */ /*==============================*/ /* Return the RHS ordered fact. */ /*==============================*/ return(firstOne); }