globle void FactsIncrementalReset( void *theEnv) { struct fact *factPtr; for (factPtr = (struct fact *) EnvGetNextFact(theEnv,NULL); factPtr != NULL; factPtr = (struct fact *) EnvGetNextFact(theEnv,factPtr)) { FactPatternMatch(theEnv,factPtr, factPtr->whichDeftemplate->patternNetwork, 0,NULL,NULL); } }
globle intBool ValidateFactIntegrity(void *theEnv) { struct fact *theFact; struct multifield *theSegment; int i; SYMBOL_HN *theSymbol; FLOAT_HN *theFloat; INTEGER_HN *theInteger; if (((struct environmentData *) theEnv)->initialized == FALSE) { return TRUE; } for (theFact = (struct fact *) EnvGetNextFact(theEnv,NULL); theFact != NULL; theFact = (struct fact *) EnvGetNextFact(theEnv,theFact)) { if (theFact->factHeader.busyCount <= 0) { return FALSE; } theSegment = &theFact->theProposition; for (i = 0 ; i < (int) theSegment->multifieldLength ; i++) { if ((theSegment->theFields[i].type == SYMBOL) || (theSegment->theFields[i].type == STRING) || (theSegment->theFields[i].type == INSTANCE_NAME)) { theSymbol = theSegment->theFields[i].value; if (theSymbol->count <= 0) { return FALSE; } } if (theSegment->theFields[i].type == INTEGER) { theInteger = theSegment->theFields[i].value; if (theInteger->count <= 0) { return FALSE; } } if (theSegment->theFields[i].type == FLOAT) { theFloat = theSegment->theFields[i].value; if (theFloat->count <= 0) { return FALSE; } } } } return TRUE; }
globle void FactsIncrementalReset( void *theEnv) { struct fact *factPtr; for (factPtr = (struct fact *) EnvGetNextFact(theEnv,NULL); factPtr != NULL; factPtr = (struct fact *) EnvGetNextFact(theEnv,factPtr)) { EngineData(theEnv)->JoinOperationInProgress = TRUE; FactPatternMatch(theEnv,factPtr, factPtr->whichDeftemplate->patternNetwork, 0,NULL,NULL); EngineData(theEnv)->JoinOperationInProgress = FALSE; } }
/******************************************************************************* Name: PrintChangedFacts Description: Update the fact window Arguments: None Returns: *******************************************************************************/ int PrintChangedFacts() { void *theEnv = GetCurrentEnvironment(); void *fact_ptr; char buffer[MAX_CHAR_IN_BUF]; char *name,labelBuffer[MAX_CHAR_IN_BUF]; Window FactWin; Display *theDisplay; struct defmodule* theModule = (struct defmodule *) EnvGetCurrentModule(theEnv); /* Change the name of the window to the current module */ FactWin = XtWindow(facts); theDisplay = XtDisplay(facts); if(theModule != NULL) { name = EnvGetDefmoduleName(theEnv,theModule); strcpy(labelBuffer,"Fact Window("); strcat(labelBuffer,name); strcat(labelBuffer,")"); } else { strcpy(labelBuffer,"Fact Window"); } XStoreName(theDisplay,FactWin,labelBuffer); /* Clear the old contents */ XtSetArg(TheArgs[0], XtNstring, ""); XtSetValues(facts_text, TheArgs, 1); XawAsciiSourceFreeString(XawTextGetSource(facts_text)); /* Print the new fact list */ fact_ptr = EnvGetNextFact(theEnv,NULL); while (fact_ptr != NULL) { EnvGetFactPPForm(theEnv,buffer,MAX_CHAR_IN_BUF - 1,fact_ptr); EnvPrintRouter(theEnv,"xfacts",buffer); EnvPrintRouter(theEnv,"xfacts", "\n"); fact_ptr = EnvGetNextFact(theEnv,fact_ptr); } return 0; }
Fact::pointer Fact::next( ) { void* next_fact; if ( !m_cobj ) return Fact::pointer(); // Can't call EnvGetNextFact on a fact that has been retracted if ( ! this->exists() ) return Fact::pointer(); next_fact = EnvGetNextFact( m_environment.cobj(), m_cobj ); if ( next_fact ) return Fact::create( m_environment, next_fact ); else return Fact::pointer(); }
static void ClearPatternMatches( void *theEnv, struct factPatternNode *patternPtr) { struct fact *theFact; struct patternMatch *lastMatch, *theMatch; /*===========================================*/ /* Loop through every fact in the fact list. */ /*===========================================*/ for (theFact = (struct fact *) EnvGetNextFact(theEnv,NULL); theFact != NULL; theFact = (struct fact *) EnvGetNextFact(theEnv,theFact)) { /*========================================*/ /* Loop through every match for the fact. */ /*========================================*/ lastMatch = NULL; theMatch = (struct patternMatch *) theFact->list; while (theMatch != NULL) { /*================================================*/ /* If the match is for the pattern being deleted, */ /* then remove the match. */ /*================================================*/ if (theMatch->matchingPattern == (struct patternNodeHeader *) patternPtr) { if (lastMatch == NULL) { /*=====================================*/ /* Remove the first match of the fact. */ /*=====================================*/ theFact->list = (void *) theMatch->next; rtn_struct(theEnv,patternMatch,theMatch); theMatch = (struct patternMatch *) theFact->list; } else { /*===================================*/ /* Remove a match for the fact which */ /* follows the first match. */ /*===================================*/ lastMatch->next = theMatch->next; rtn_struct(theEnv,patternMatch,theMatch); theMatch = lastMatch->next; } } /*====================================================*/ /* If the match is not for the pattern being deleted, */ /* then move on to the next match for the fact. */ /*====================================================*/ else { lastMatch = theMatch; theMatch = theMatch->next; } } } }
globle void EnvGetFactList( void *theEnv, DATA_OBJECT_PTR returnValue, void *vTheModule) { struct fact *theFact; unsigned long count; struct multifield *theList; struct defmodule *theModule = (struct defmodule *) vTheModule; /*==========================*/ /* Save the current module. */ /*==========================*/ SaveCurrentModule(theEnv); /*============================================*/ /* Count the number of facts to be retrieved. */ /*============================================*/ if (theModule == NULL) { for (theFact = (struct fact *) EnvGetNextFact(theEnv,NULL), count = 0; theFact != NULL; theFact = (struct fact *) EnvGetNextFact(theEnv,theFact), count++) { /* Do Nothing */ } } else { EnvSetCurrentModule(theEnv,(void *) theModule); UpdateDeftemplateScope(theEnv); for (theFact = (struct fact *) GetNextFactInScope(theEnv,NULL), count = 0; theFact != NULL; theFact = (struct fact *) GetNextFactInScope(theEnv,theFact), count++) { /* Do Nothing */ } } /*===========================================================*/ /* Create the multifield value to store the construct names. */ /*===========================================================*/ SetpType(returnValue,MULTIFIELD); SetpDOBegin(returnValue,1); SetpDOEnd(returnValue,(long) count); theList = (struct multifield *) EnvCreateMultifield(theEnv,count); SetpValue(returnValue,(void *) theList); /*==================================================*/ /* Store the fact pointers in the multifield value. */ /*==================================================*/ if (theModule == NULL) { for (theFact = (struct fact *) EnvGetNextFact(theEnv,NULL), count = 1; theFact != NULL; theFact = (struct fact *) EnvGetNextFact(theEnv,theFact), count++) { SetMFType(theList,count,FACT_ADDRESS); SetMFValue(theList,count,(void *) theFact); } } else { for (theFact = (struct fact *) GetNextFactInScope(theEnv,NULL), count = 1; theFact != NULL; theFact = (struct fact *) GetNextFactInScope(theEnv,theFact), count++) { SetMFType(theList,count,FACT_ADDRESS); SetMFValue(theList,count,(void *) theFact); } } /*=============================*/ /* Restore the current module. */ /*=============================*/ RestoreCurrentModule(theEnv); UpdateDeftemplateScope(theEnv); }
globle void EnvFacts( void *theEnv, char *logicalName, void *vTheModule, long long start, long long end, long long max) { struct fact *factPtr; long count = 0; struct defmodule *oldModule, *theModule = (struct defmodule *) vTheModule; int allModules = FALSE; /*==========================*/ /* Save the current module. */ /*==========================*/ oldModule = ((struct defmodule *) EnvGetCurrentModule(theEnv)); /*=========================================================*/ /* Determine if facts from all modules are to be displayed */ /* or just facts from the current module. */ /*=========================================================*/ if (theModule == NULL) allModules = TRUE; else EnvSetCurrentModule(theEnv,(void *) theModule); /*=====================================*/ /* Get the first fact to be displayed. */ /*=====================================*/ if (allModules) factPtr = (struct fact *) EnvGetNextFact(theEnv,NULL); else factPtr = (struct fact *) GetNextFactInScope(theEnv,NULL); /*===============================*/ /* Display facts until there are */ /* no more facts to display. */ /*===============================*/ while (factPtr != NULL) { /*==================================================*/ /* Abort the display of facts if the Halt Execution */ /* flag has been set (normally by user action). */ /*==================================================*/ if (GetHaltExecution(theEnv) == TRUE) { EnvSetCurrentModule(theEnv,(void *) oldModule); return; } /*===============================================*/ /* If the maximum fact index of facts to display */ /* has been reached, then stop displaying facts. */ /*===============================================*/ if ((factPtr->factIndex > end) && (end != UNSPECIFIED)) { PrintTally(theEnv,logicalName,count,(char*)"fact",(char*)"facts"); EnvSetCurrentModule(theEnv,(void *) oldModule); return; } /*================================================*/ /* If the maximum number of facts to be displayed */ /* has been reached, then stop displaying facts. */ /*================================================*/ if (max == 0) { PrintTally(theEnv,logicalName,count,(char*)"fact",(char*)"facts"); EnvSetCurrentModule(theEnv,(void *) oldModule); return; } /*======================================================*/ /* If the index of the fact is greater than the minimum */ /* starting fact index, then display the fact. */ /*======================================================*/ if (factPtr->factIndex >= start) { PrintFactWithIdentifier(theEnv,logicalName,factPtr); EnvPrintRouter(theEnv,logicalName,(char*)"\n"); count++; if (max > 0) max--; } /*========================================*/ /* Proceed to the next fact to be listed. */ /*========================================*/ if (allModules) factPtr = (struct fact *) EnvGetNextFact(theEnv,factPtr); else factPtr = (struct fact *) GetNextFactInScope(theEnv,factPtr); } /*===================================================*/ /* Print the total of the number of facts displayed. */ /*===================================================*/ PrintTally(theEnv,logicalName,count,(char*)"fact",(char*)"facts"); /*=============================*/ /* Restore the current module. */ /*=============================*/ EnvSetCurrentModule(theEnv,(void *) oldModule); }
static void DuplicateModifyCommand( void *theEnv, int retractIt, DATA_OBJECT_PTR returnValue) { long int factNum; struct fact *oldFact, *newFact, *theFact; struct expr *testPtr; DATA_OBJECT computeResult; struct deftemplate *templatePtr; struct templateSlot *slotPtr; int i, position, found; /*===================================================*/ /* Set the default return value to the symbol FALSE. */ /*===================================================*/ SetpType(returnValue,SYMBOL); SetpValue(returnValue,SymbolData(theEnv)->FalseSymbol); /*==================================================*/ /* Evaluate the first argument which is used to get */ /* a pointer to the fact to be modified/duplicated. */ /*==================================================*/ testPtr = GetFirstArgument(); EvaluateExpression(theEnv,testPtr,&computeResult); /*==============================================================*/ /* If an integer is supplied, then treat it as a fact-index and */ /* search the fact-list for the fact with that fact-index. */ /*==============================================================*/ if (computeResult.type == INTEGER) { factNum = ValueToLong(computeResult.value); if (factNum < 0) { if (retractIt) ExpectedTypeError2(theEnv,"modify",1); else ExpectedTypeError2(theEnv,"duplicate",1); SetEvaluationError(theEnv,TRUE); return; } oldFact = (struct fact *) EnvGetNextFact(theEnv,NULL); while (oldFact != NULL) { if (oldFact->factIndex == factNum) { break; } else { oldFact = oldFact->nextFact; } } if (oldFact == NULL) { char tempBuffer[20]; sprintf(tempBuffer,"f-%ld",factNum); CantFindItemErrorMessage(theEnv,"fact",tempBuffer); return; } } /*==========================================*/ /* Otherwise, if a pointer is supplied then */ /* no lookup is required. */ /*==========================================*/ else if (computeResult.type == FACT_ADDRESS) { oldFact = (struct fact *) computeResult.value; } /*===========================================*/ /* Otherwise, the first argument is invalid. */ /*===========================================*/ else { if (retractIt) ExpectedTypeError2(theEnv,"modify",1); else ExpectedTypeError2(theEnv,"duplicate",1); SetEvaluationError(theEnv,TRUE); return; } /*==================================*/ /* See if it is a deftemplate fact. */ /*==================================*/ templatePtr = oldFact->whichDeftemplate; if (templatePtr->implied) return; /*================================================================*/ /* Duplicate the values from the old fact (skipping multifields). */ /*================================================================*/ newFact = (struct fact *) CreateFactBySize(theEnv,oldFact->theProposition.multifieldLength); newFact->whichDeftemplate = templatePtr; for (i = 0; i < (int) oldFact->theProposition.multifieldLength; i++) { newFact->theProposition.theFields[i].type = oldFact->theProposition.theFields[i].type; if (newFact->theProposition.theFields[i].type != MULTIFIELD) { newFact->theProposition.theFields[i].value = oldFact->theProposition.theFields[i].value; } else { newFact->theProposition.theFields[i].value = NULL; } } /*========================*/ /* Start replacing slots. */ /*========================*/ testPtr = testPtr->nextArg; while (testPtr != NULL) { /*============================================================*/ /* If the slot identifier is an integer, then the slot was */ /* previously identified and its position within the template */ /* was stored. Otherwise, the position of the slot within the */ /* deftemplate has to be determined by comparing the name of */ /* the slot against the list of slots for the deftemplate. */ /*============================================================*/ if (testPtr->type == INTEGER) { position = (int) ValueToLong(testPtr->value); } else { found = FALSE; position = 0; slotPtr = templatePtr->slotList; while (slotPtr != NULL) { if (slotPtr->slotName == (SYMBOL_HN *) testPtr->value) { found = TRUE; slotPtr = NULL; } else { slotPtr = slotPtr->next; position++; } } if (! found) { InvalidDeftemplateSlotMessage(theEnv,ValueToString(testPtr->value), ValueToString(templatePtr->header.name)); SetEvaluationError(theEnv,TRUE); ReturnFact(theEnv,newFact); return; } } /*===================================================*/ /* If a single field slot is being replaced, then... */ /*===================================================*/ if (newFact->theProposition.theFields[position].type != MULTIFIELD) { /*======================================================*/ /* If the list of values to store in the slot is empty */ /* or contains more than one member than an error has */ /* occured because a single field slot can only contain */ /* a single value. */ /*======================================================*/ if ((testPtr->argList == NULL) ? TRUE : (testPtr->argList->nextArg != NULL)) { MultiIntoSingleFieldSlotError(theEnv,GetNthSlot(templatePtr,position),templatePtr); ReturnFact(theEnv,newFact); return; } /*===================================================*/ /* Evaluate the expression to be stored in the slot. */ /*===================================================*/ EvaluateExpression(theEnv,testPtr->argList,&computeResult); SetEvaluationError(theEnv,FALSE); /*====================================================*/ /* If the expression evaluated to a multifield value, */ /* then an error occured since a multifield value can */ /* not be stored in a single field slot. */ /*====================================================*/ if (computeResult.type == MULTIFIELD) { ReturnFact(theEnv,newFact); MultiIntoSingleFieldSlotError(theEnv,GetNthSlot(templatePtr,position),templatePtr); return; } /*=============================*/ /* Store the value in the slot */ /*=============================*/ newFact->theProposition.theFields[position].type = computeResult.type; newFact->theProposition.theFields[position].value = computeResult.value; } /*=================================*/ /* Else replace a multifield slot. */ /*=================================*/ else { /*======================================*/ /* Determine the new value of the slot. */ /*======================================*/ StoreInMultifield(theEnv,&computeResult,testPtr->argList,FALSE); SetEvaluationError(theEnv,FALSE); /*=============================*/ /* Store the value in the slot */ /*=============================*/ newFact->theProposition.theFields[position].type = computeResult.type; newFact->theProposition.theFields[position].value = computeResult.value; } testPtr = testPtr->nextArg; } /*=====================================*/ /* Copy the multifield values from the */ /* old fact that were not replaced. */ /*=====================================*/ for (i = 0; i < (int) oldFact->theProposition.multifieldLength; i++) { if ((newFact->theProposition.theFields[i].type == MULTIFIELD) && (newFact->theProposition.theFields[i].value == NULL)) { newFact->theProposition.theFields[i].value = CopyMultifield(theEnv,(struct multifield *) oldFact->theProposition.theFields[i].value); } } /*======================================*/ /* Perform the duplicate/modify action. */ /*======================================*/ if (retractIt) EnvRetract(theEnv,oldFact); theFact = (struct fact *) EnvAssert(theEnv,newFact); /*========================================*/ /* The asserted fact is the return value. */ /*========================================*/ if (theFact != NULL) { SetpDOBegin(returnValue,1); SetpDOEnd(returnValue,theFact->theProposition.multifieldLength); SetpType(returnValue,FACT_ADDRESS); SetpValue(returnValue,(void *) theFact); } return; }