globle void AssertCommand( void *theEnv, DATA_OBJECT_PTR rv) { struct deftemplate *theDeftemplate; struct field *theField; DATA_OBJECT theValue; struct expr *theExpression; struct templateSlot *slotPtr; struct fact *newFact; int error = FALSE; int i; struct fact *theFact; /*===================================================*/ /* Set the default return value to the symbol FALSE. */ /*===================================================*/ SetpType(rv,SYMBOL); SetpValue(rv,EnvFalseSymbol(theEnv)); /*================================*/ /* Get the deftemplate associated */ /* with the fact being asserted. */ /*================================*/ theExpression = GetFirstArgument(); theDeftemplate = (struct deftemplate *) theExpression->value; /*=======================================*/ /* Create the fact and store the name of */ /* the deftemplate as the 1st field. */ /*=======================================*/ if (theDeftemplate->implied == FALSE) { newFact = CreateFactBySize(theEnv,theDeftemplate->numberOfSlots); slotPtr = theDeftemplate->slotList; } else { newFact = CreateFactBySize(theEnv,1); if (theExpression->nextArg == NULL) { newFact->theProposition.theFields[0].type = MULTIFIELD; newFact->theProposition.theFields[0].value = CreateMultifield2(theEnv,0L); } slotPtr = NULL; } newFact->whichDeftemplate = theDeftemplate; /*===================================================*/ /* Evaluate the expression associated with each slot */ /* and store the result in the appropriate slot of */ /* the newly created fact. */ /*===================================================*/ EnvIncrementClearReadyLocks(theEnv); theField = newFact->theProposition.theFields; for (theExpression = theExpression->nextArg, i = 0; theExpression != NULL; theExpression = theExpression->nextArg, i++) { /*===================================================*/ /* Evaluate the expression to be stored in the slot. */ /*===================================================*/ EvaluateExpression(theEnv,theExpression,&theValue); /*============================================================*/ /* A multifield value can't be stored in a single field slot. */ /*============================================================*/ if ((slotPtr != NULL) ? (slotPtr->multislot == FALSE) && (theValue.type == MULTIFIELD) : FALSE) { MultiIntoSingleFieldSlotError(theEnv,slotPtr,theDeftemplate); theValue.type = SYMBOL; theValue.value = EnvFalseSymbol(theEnv); error = TRUE; } /*==============================*/ /* Store the value in the slot. */ /*==============================*/ theField[i].type = theValue.type; theField[i].value = theValue.value; /*========================================*/ /* Get the information for the next slot. */ /*========================================*/ if (slotPtr != NULL) slotPtr = slotPtr->next; } EnvDecrementClearReadyLocks(theEnv); /*============================================*/ /* If an error occured while generating the */ /* fact's slot values, then abort the assert. */ /*============================================*/ if (error) { ReturnFact(theEnv,newFact); return; } /*================================*/ /* Add the fact to the fact-list. */ /*================================*/ theFact = (struct fact *) EnvAssert(theEnv,(void *) newFact); /*========================================*/ /* The asserted fact is the return value. */ /*========================================*/ if (theFact != NULL) { SetpType(rv,FACT_ADDRESS); SetpValue(rv,(void *) theFact); } return; }
//madianyi End globle void UpdateCommand( void *theEnv, DATA_OBJECT_PTR rv) { long long factIndex; struct fact *oldFact, *newFact, *theFact; struct defrule *ExecutingRule = NULL; struct expr *testPtr; DATA_OBJECT computeResult; /*===================================================*/ /* Set the default return value to the symbol FALSE. */ /*===================================================*/ SetpType(rv,SYMBOL); SetpValue(rv,EnvFalseSymbol(theEnv)); /*==================================================*/ /* Evaluate the first argument which is used to get */ /* a pointer to the fact to be updated. */ /*==================================================*/ testPtr = GetFirstArgument(); EnvIncrementClearReadyLocks(theEnv); EvaluateExpression(theEnv,testPtr,&computeResult); EnvDecrementClearReadyLocks(theEnv); /*==============================================================*/ /* 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) { factIndex = ValueToLong(computeResult.value); if (factIndex < 0) { ExpectedTypeError1(theEnv,"update",1,"fact-address, fact-index, or the symbol *"); return; } /*================================================*/ /* See if a fact with the specified index exists. */ /*================================================*/ oldFact = FindIndexedFact(theEnv,factIndex); if (oldFact == NULL) { char tempBuffer[20]; gensprintf(tempBuffer,"f-%lld",factIndex); 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 argument has evaluated to an */ /* illegal value for the retract command. */ /*============================================*/ else { ExpectedTypeError1(theEnv,"update",1,"fact-address, fact-index, or the symbol *"); SetEvaluationError(theEnv,TRUE); } /*============================================*/ /* Retract oldFact and Assert newFact */ /*============================================*/ if (oldFact->localFact != NULL) { newFact = oldFact->localFact; //Remove oldFact from localFactList of ExecutingRule ExecutingRule = EngineData(theEnv)->ExecutingRule; if (oldFact == ExecutingRule->lastLocalFact) { ExecutingRule->lastLocalFact = oldFact->previousLocalFact; } if (oldFact->previousLocalFact == NULL) { ExecutingRule->localFactList = ExecutingRule->localFactList->nextLocalFact; if (ExecutingRule->localFactList != NULL) { ExecutingRule->localFactList->previousLocalFact = NULL; } } else { oldFact->previousLocalFact->nextLocalFact = oldFact->nextLocalFact; if (oldFact->nextLocalFact != NULL) { oldFact->nextLocalFact->previousLocalFact = oldFact->previousLocalFact; } } EnvRetract(theEnv,oldFact); theFact = (struct fact *) EnvAssert(theEnv,(void *) newFact); if (theFact != NULL) { SetpType(rv,FACT_ADDRESS); SetpValue(rv,(void *) theFact); } return; } else { ExpectedTypeError1(theEnv,"update",1,"been set before *"); SetEvaluationError(theEnv,TRUE); } }