Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
//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);
     }
   
  }