예제 #1
0
파일: constrnt.c 프로젝트: DrItanium/maya
void InitializeConstraints(
  Environment *theEnv)
  {
#if (! RUN_TIME) && (! BLOAD_ONLY)
   int i;
#endif

   AllocateEnvironmentData(theEnv,CONSTRAINT_DATA,sizeof(struct constraintData),DeallocateConstraintData);

#if (! RUN_TIME) && (! BLOAD_ONLY)

    ConstraintData(theEnv)->ConstraintHashtable = (struct constraintRecord **)
                          gm2(theEnv,sizeof (struct constraintRecord *) *
                                    SIZE_CONSTRAINT_HASH);

    if (ConstraintData(theEnv)->ConstraintHashtable == NULL) ExitRouter(theEnv,EXIT_FAILURE);

    for (i = 0; i < SIZE_CONSTRAINT_HASH; i++) ConstraintData(theEnv)->ConstraintHashtable[i] = NULL;
#endif

#if (! RUN_TIME)
   AddUDF(theEnv,"get-dynamic-constraint-checking","b",0,0,NULL,GDCCommand,"GDCCommand",NULL);
   AddUDF(theEnv,"set-dynamic-constraint-checking","b",1,1,NULL,SDCCommand,"SDCCommand",NULL);
#endif
  }
예제 #2
0
파일: strngrtr.c 프로젝트: DrItanium/maya
static void WriteStringCallback(
  Environment *theEnv,
  const char *logicalName,
  const char *str,
  void *context)
  {
   struct stringRouter *head;

   head = FindStringRouter(theEnv,logicalName);
   if (head == NULL)
     {
      SystemError(theEnv,"ROUTER",3);
      ExitRouter(theEnv,EXIT_FAILURE);
      return;
     }

   if (head->readWriteType != WRITE_STRING) return;

   if (head->maximumPosition == 0) return;

   if ((head->currentPosition + 1) >= head->maximumPosition) return;

   genstrncpy(&head->writeString[head->currentPosition],
              str,(STD_SIZE) (head->maximumPosition - head->currentPosition) - 1);

   head->currentPosition += strlen(str);
  }
예제 #3
0
파일: strngrtr.c 프로젝트: DrItanium/maya
static int UnreadStringCallback(
  Environment *theEnv,
  const char *logicalName,
  int ch,
  void *context)
  {
   struct stringRouter *head;
#if MAC_XCD
#pragma unused(ch)
#endif

   head = FindStringRouter(theEnv,logicalName);

   if (head == NULL)
     {
      SystemError(theEnv,"ROUTER",2);
      ExitRouter(theEnv,EXIT_FAILURE);
     }

   if (head->readWriteType != READ_STRING) return 0;
   if (head->currentPosition > 0)
     { head->currentPosition--; }

   return 1;
  }
예제 #4
0
파일: strngrtr.c 프로젝트: DrItanium/maya
static int ReadStringCallback(
  Environment *theEnv,
  const char *logicalName,
  void *context)
  {
   struct stringRouter *head;
   int rc;

   head = FindStringRouter(theEnv,logicalName);
   if (head == NULL)
     {
      SystemError(theEnv,"ROUTER",1);
      ExitRouter(theEnv,EXIT_FAILURE);
     }

   if (head->readWriteType != READ_STRING) return(EOF);
   if (head->currentPosition >= head->maximumPosition)
     {
      head->currentPosition++;
      return(EOF);
     }

   rc = (unsigned char) head->readString[head->currentPosition];
   head->currentPosition++;

   return(rc);
  }
예제 #5
0
globle void InitializeFactHashTable()
   {
    int i;

    FactHashTable = (struct factHashEntry **)
                    gm2((int) sizeof (struct factHashEntry *) * SIZE_FACT_HASH);

    if (FactHashTable == NULL) ExitRouter(EXIT_FAILURE);

    for (i = 0; i < SIZE_FACT_HASH; i++) FactHashTable[i] = NULL;
   }
예제 #6
0
globle void InstallPrimitive(
  struct entityRecord *thePrimitive,
  int whichPosition)
  {
   if (PrimitivesArray[whichPosition] != NULL)
     {
      SystemError("EVALUATN",5);
      ExitRouter(EXIT_FAILURE);
     }

   PrimitivesArray[whichPosition] = thePrimitive;
  }
예제 #7
0
globle void InitExpressionPointers()
  {
   PTR_AND          = (void *) FindFunction("and");
   PTR_OR           = (void *) FindFunction("or");
   PTR_EQ           = (void *) FindFunction("eq");
   PTR_NEQ          = (void *) FindFunction("neq");
   PTR_NOT          = (void *) FindFunction("not");

   if ((PTR_AND == NULL) || (PTR_OR == NULL) ||
       (PTR_EQ == NULL) || (PTR_NEQ == NULL) || (PTR_NOT == NULL))
     {
      SystemError("EXPRESSN",1);
      ExitRouter(EXIT_FAILURE);
     }
  }
예제 #8
0
파일: strngrtr.c 프로젝트: DrItanium/maya
static void WriteStringBuilderCallback(
  Environment *theEnv,
  const char *logicalName,
  const char *str,
  void *context)
  {
   StringBuilderRouter *head;

   head = FindStringBuilderRouter(theEnv,logicalName);
   if (head == NULL)
     {
      SystemError(theEnv,"ROUTER",3);
      ExitRouter(theEnv,EXIT_FAILURE);
      return;
     }
     
   SBAppend(head->SBR,str);
  }
예제 #9
0
globle void NetworkAssert(
  struct partialMatch *binds,
  struct joinNode *join,
  int enterDirection)
  {
   struct partialMatch *lhsBinds = NULL, *rhsBinds = NULL;
   struct partialMatch *comparePMs = NULL, *newBinds;
   int exprResult;

   /*=========================================================*/
   /* If an incremental reset is being performed and the join */
   /* is not part of the network to be reset, then return.    */
   /*=========================================================*/

#if INCREMENTAL_RESET && (! BLOAD_ONLY) && (! RUN_TIME)
   if (IncrementalResetInProgress && (join->initialize == FALSE)) return;
#endif

   /*=========================================================*/
   /* If the associated LHS pattern is a not CE or the join   */
   /* is a nand join, then we need an additional field in the */
   /* partial match to keep track of the pseudo fact if one   */
   /* is created. The partial match is automatically stored   */
   /* in the beta memory and the counterf slot is used to     */
   /* determine if it is an actual partial match. If counterf */
   /* is TRUE, there are one or more fact or instances        */
   /* keeping the not or nand join from being satisfied.      */
   /*=========================================================*/

   if ((enterDirection == LHS) &&
       ((join->patternIsNegated) || (join->joinFromTheRight)))
     {
      newBinds = AddSingleMatch(binds,NULL,
                                (join->ruleToActivate == NULL) ? 0 : 1,
                                (int) join->logicalJoin);
      newBinds->notOriginf = TRUE;
      newBinds->counterf = TRUE;
      binds = newBinds;
      binds->next = join->beta;
      join->beta = binds;
     }

   /*==================================================*/
   /* Use a special routine if this is the first join. */
   /*==================================================*/

   if (join->firstJoin)
     {
      EmptyDrive(join,binds);
      return;
     }

   /*==================================================*/
   /* Initialize some variables used to indicate which */
   /* side is being compared to the new partial match. */
   /*==================================================*/

   if (enterDirection == LHS)
     {
      if (join->joinFromTheRight)
        { comparePMs = ((struct joinNode *) join->rightSideEntryStructure)->beta;}
      else
        { comparePMs = ((struct patternNodeHeader *) join->rightSideEntryStructure)->alphaMemory; }
      lhsBinds = binds;
     }
   else if (enterDirection == RHS)
     {
      if (join->patternIsNegated || join->joinFromTheRight)
        { comparePMs = join->beta; }
      else
        { comparePMs = join->lastLevel->beta; }
      rhsBinds = binds;
     }
   else
     {
      SystemError("DRIVE",1);
      ExitRouter(EXIT_FAILURE);
     }

   /*===================================================*/
   /* Compare each set of binds on the opposite side of */
   /* the join with the set of binds that entered this  */
   /* join. If the binds don't mismatch, then perform   */
   /* the appropriate action for the logic of the join. */
   /*===================================================*/

   while (comparePMs != NULL)
     {
      /*===========================================================*/
      /* Initialize some variables pointing to the partial matches */
      /* in the LHS and RHS of the join. In addition, check for    */
      /* certain conditions under which the partial match can be   */
      /* skipped since it's not a "real" partial match.            */
      /*===========================================================*/

      if (enterDirection == RHS)
        {
         lhsBinds = comparePMs;

         /*=====================================================*/
         /* The partial matches entering from the LHS of a join */
         /* are stored in the beta memory of the previous join  */
         /* (unless the current join is a join from the right   */
         /* or is attached to a not CE). If the previous join   */
         /* is a join from the right or associated with a not   */
         /* CE, then some of its partial matches in its beta    */
         /* memory will not be "real" partial matches. That is, */
         /* there may be a partial match in the alpha memory    */
         /* that prevents the partial match from satisfying the */
         /* join's conditions. If this is the case, then the    */
         /* counterf flag in the partial match will be set to   */
         /* TRUE and in this case, we move on to the next       */
         /* partial match to be checked.                        */
         /*=====================================================*/

         if (lhsBinds->counterf &&
             (join->patternIsNegated == FALSE) &&
             (join->joinFromTheRight == FALSE))
           {
            comparePMs = comparePMs->next;
            continue;
           }

        /*==================================================*/
        /* If the join is associated with a not CE or has a */
        /* join from the right, then the LHS partial match  */
        /* currently being checked may already have a       */
        /* partial match from the alpha memory preventing   */
        /* it from being satisfied. If this is the case,    */
        /* then move on to the next partial match in the    */
        /* beta memory of the join.                         */
        /*==================================================*/

        if ((join->patternIsNegated || join->joinFromTheRight) &&
            (lhsBinds->counterf))
          {
           comparePMs = comparePMs->next;
           continue;
          }
        }
      else
        { rhsBinds = comparePMs; }

      /*========================================================*/
      /* If the join has no expression associated with it, then */
      /* the new partial match derived from the LHS and RHS     */
      /* partial matches is valid. In the event that the join   */
      /* is a join from the right, it must also be checked that */
      /* the RHS partial match is the same partial match that   */
      /* the LHS partial match was generated from. Each LHS     */
      /* partial match in a join from the right corresponds     */
      /* uniquely to a partial match from the RHS of the join.  */
      /* To determine whether the LHS partial match is the one  */
      /* associated with the RHS partial match, we compare the  */
      /* the entity addresses found in the partial matches to   */
      /* make sure they're equal.                               */
      /*========================================================*/

      if (join->networkTest == NULL)
        {
         exprResult = TRUE;
         if (join->joinFromTheRight)
           {
            int i;

            for (i = 0; i < (int) (lhsBinds->bcount - 1); i++)
              {
               if (lhsBinds->binds[i].gm.theMatch != rhsBinds->binds[i].gm.theMatch)
                 {
                  exprResult = FALSE;
                  break;
                 }
              }
           }
        }

      /*=========================================================*/
      /* If the join has an expression associated with it, then  */
      /* evaluate the expression to determine if the new partial */
      /* match derived from the LHS and RHS partial matches is   */
      /* valid (i.e. variable bindings are consistent and        */
      /* predicate expressions evaluate to TRUE).                */
      /*=========================================================*/

      else
        {
         exprResult = EvaluateJoinExpression(join->networkTest,lhsBinds,rhsBinds,join);
         if (EvaluationError)
           {
            if (join->patternIsNegated) exprResult = TRUE;
            SetEvaluationError(FALSE);
           }
        }

      /*====================================================*/
      /* If the join expression evaluated to TRUE (i.e.     */
      /* there were no conflicts between variable bindings, */
      /* all tests were satisfied, etc.), then perform the  */
      /* appropriate action given the logic of this join.   */
      /*====================================================*/

      if (exprResult != FALSE)
        {
         /*==============================================*/
         /* Use the PPDrive routine when the join isn't  */
         /* associated with a not CE and it doesn't have */
         /* a join from the right.                       */
         /*==============================================*/

         if ((join->patternIsNegated == FALSE) &&
             (join->joinFromTheRight == FALSE))
           { PPDrive(lhsBinds,rhsBinds,join); }

         /*=====================================================*/
         /* Use the PNRDrive routine when the new partial match */
         /* enters from the RHS of the join and the join either */
         /* is associated with a not CE or has a join from the  */
         /* right.                                              */
         /*=====================================================*/

         else if (enterDirection == RHS)
           { PNRDrive(join,comparePMs,rhsBinds); }

         /*===========================================================*/
         /* If the new partial match entered from the LHS of the join */
         /* and the join is either associated with a not CE or the    */
         /* join has a join from the right, then mark the LHS partial */
         /* match indicating that there is a RHS partial match        */
         /* preventing this join from being satisfied. Once this has  */
         /* happened, the other RHS partial matches don't have to be  */
         /* tested since it only takes one partial match to prevent   */
         /* the LHS from being satisfied.                             */
         /*===========================================================*/

         else if (enterDirection == LHS)
           {
            binds->binds[binds->bcount - 1].gm.theValue = (void *) rhsBinds;
            comparePMs = NULL;
            continue;
           }
        }

      /*====================================*/
      /* Move on to the next partial match. */
      /*====================================*/

      comparePMs = comparePMs->next;
     }

   /*==================================================================*/
   /* If a join with an associated not CE or join from the right was   */
   /* entered from the LHS side of the join, and the join expression   */
   /* failed for all sets of matches for the new bindings on the LHS   */
   /* side (there was no RHS partial match preventing the LHS partial  */
   /* match from being satisfied), then the LHS partial match appended */
   /* with an pseudo-fact that represents the instance of the not      */
   /* pattern or join from the right that was satisfied should be sent */
   /* to the joins below this join.                                    */
   /*==================================================================*/

   if ((join->patternIsNegated || join->joinFromTheRight) &&
       (enterDirection == LHS) &&
       (binds->binds[binds->bcount - 1].gm.theValue == NULL))
     { PNLDrive(join,binds); }

   return;
  }
예제 #10
0
globle int EvaluateExpression(
  struct expr *problem,
  DATA_OBJECT_PTR returnValue)
  {
   struct expr *oldArgument;
   struct FunctionDefinition *fptr;
#if PROFILING_FUNCTIONS
   struct profileFrameInfo profileFrame;
#endif

   if (problem == NULL)
     {
      returnValue->type = SYMBOL;
      returnValue->value = FalseSymbol;
      return(EvaluationError);
     }

   switch (problem->type)
     {
      case STRING:
      case SYMBOL:
      case FLOAT:
      case INTEGER:
#if OBJECT_SYSTEM
      case INSTANCE_NAME:
      case INSTANCE_ADDRESS:
#endif
#if FUZZY_DEFTEMPLATES 
      case FUZZY_VALUE:
#endif
      case EXTERNAL_ADDRESS:
        returnValue->type = problem->type;
        returnValue->value = problem->value;
        break;

#if FUZZY_DEFTEMPLATES 
      case S_FUNCTION:
      case PI_FUNCTION:
      case Z_FUNCTION:
      case SINGLETON_EXPRESSION:
             /* At some time it may be worthwhile making this into an FCALL
                    but only when we allow user's to create functions that return
                        fuzzy values -- this may not happen
             */
                {
                  struct fuzzy_value *fvptr;
                  fvptr = getConstantFuzzyValue(problem, &EvaluationError);
          returnValue->type = FUZZY_VALUE;
                  if (fvptr != NULL)
                    {
              returnValue->value = (VOID *)AddFuzzyValue(fvptr);
                      /* AddFuzzyValue makes a copy of the fuzzy value -- so remove this one */
              rtnFuzzyValue(fvptr);
                        }
              else
                  {
                   returnValue->type = RVOID;
                   returnValue->value = CLIPSFalseSymbol;
                   SetEvaluationError(TRUE);
                  }
        }
        break;
#endif

      case FCALL:
        {
         fptr = (struct FunctionDefinition *) problem->value;

#if PROFILING_FUNCTIONS   
         StartProfile(&profileFrame,
                      &fptr->usrData,
                      ProfileUserFunctions);
#endif

         oldArgument = CurrentExpression;
         CurrentExpression = problem;

         switch(fptr->returnValueType)
           {
            case 'v' :
              (* (void (*)(void)) fptr->functionPointer)();
              returnValue->type = RVOID;
              returnValue->value = FalseSymbol;
              break;
            case 'b' :
              returnValue->type = SYMBOL;
              if ((* (int (*)(void)) fptr->functionPointer)())
                returnValue->value = TrueSymbol;
              else
                returnValue->value = FalseSymbol;
              break;
            case 'a' :
              returnValue->type = EXTERNAL_ADDRESS;
              returnValue->value =
                             (* (void *(*)(void)) fptr->functionPointer)();
              break;
            case 'i' :
              returnValue->type = INTEGER;
              returnValue->value = (void *)
                AddLong((long) (* (int (*)(void)) fptr->functionPointer)());
              break;
            case 'l' :
              returnValue->type = INTEGER;
              returnValue->value = (void *)
                 AddLong((* (long int (*)(void)) fptr->functionPointer)());
              break;
#if FUZZY_DEFTEMPLATES 
            case 'F' :
              {
                struct fuzzy_value *fvPtr;

                fvPtr = (* (struct fuzzy_value * (*)(VOID_ARG)) fptr->functionPointer)();
                if (fvPtr != NULL)
                  {
                   returnValue->type = FUZZY_VALUE;
                   returnValue->value = (VOID *)AddFuzzyValue( fvPtr );
                   /* AddFuzzyValue makes a copy of fv .. so return it */
                   rtnFuzzyValue( fvPtr );
                  }
                else
                  {
                   returnValue->type = RVOID;
                   returnValue->value = CLIPSFalseSymbol;
                  }
               }
              break;
#endif
            case 'f' :
              returnValue->type = FLOAT;
              returnValue->value = (void *)
                 AddDouble((double) (* (float (*)(void)) fptr->functionPointer)());
              break;
            case 'd' :
              returnValue->type = FLOAT;
              returnValue->value = (void *)
                 AddDouble((* (double (*)(void)) fptr->functionPointer)());
              break;
            case 's' :
              returnValue->type = STRING;
              returnValue->value = (void *)
                (* (SYMBOL_HN *(*)(void)) fptr->functionPointer)();
              break;
            case 'w' :
              returnValue->type = SYMBOL;
              returnValue->value = (void *)
                (* (SYMBOL_HN *(*)(void)) fptr->functionPointer)();
              break;
#if OBJECT_SYSTEM
            case 'x' :
              returnValue->type = INSTANCE_ADDRESS;
              returnValue->value =
                             (* (void *(*)(void)) fptr->functionPointer)();
              break;
            case 'o' :
              returnValue->type = INSTANCE_NAME;
              returnValue->value = (void *)
                (* (SYMBOL_HN *(*)(void)) fptr->functionPointer)();
              break;
#endif
            case 'c' :
              {
               char cbuff[2];

               cbuff[0] = (* (char (*)(void)) fptr->functionPointer)();
               cbuff[1] = EOS;
               returnValue->type = SYMBOL;
               returnValue->value = (void *) AddSymbol(cbuff);
               break;
              }

            case 'j' :
            case 'k' :
            case 'm' :
            case 'n' :
            case 'u' :
              (* (void (*)(DATA_OBJECT_PTR)) fptr->functionPointer)(returnValue);
              break;

            default :
               SystemError("EVALUATN",2);
               ExitRouter(EXIT_FAILURE);
               break;
            }

#if PROFILING_FUNCTIONS 
        EndProfile(&profileFrame);
#endif

        CurrentExpression = oldArgument;
        break;
        }

     case MULTIFIELD:
        returnValue->type = MULTIFIELD;
        returnValue->value = ((DATA_OBJECT_PTR) (problem->value))->value;
        returnValue->begin = ((DATA_OBJECT_PTR) (problem->value))->begin;
        returnValue->end = ((DATA_OBJECT_PTR) (problem->value))->end;
        break;

     case MF_VARIABLE:
     case SF_VARIABLE:
        if (GetBoundVariable(returnValue,(SYMBOL_HN *) problem->value) == FALSE)
          {
           PrintErrorID("EVALUATN",1,FALSE);
           PrintRouter(WERROR,"Variable ");
           PrintRouter(WERROR,ValueToString(problem->value));
           PrintRouter(WERROR," is unbound\n");
           returnValue->type = SYMBOL;
           returnValue->value = FalseSymbol;
           SetEvaluationError(TRUE);
          }
        break;

      default:
        if (PrimitivesArray[problem->type] == NULL)
          {
           SystemError("EVALUATN",3);
           ExitRouter(EXIT_FAILURE);
          }

        if (PrimitivesArray[problem->type]->copyToEvaluate)
          {
           returnValue->type = problem->type;
           returnValue->value = problem->value;
           break;
          }

        if (PrimitivesArray[problem->type]->evaluateFunction == NULL)
          {
           SystemError("EVALUATN",4);
           ExitRouter(EXIT_FAILURE);
          }

        oldArgument = CurrentExpression;
        CurrentExpression = problem;

#if PROFILING_FUNCTIONS 
        StartProfile(&profileFrame,
                     &PrimitivesArray[problem->type]->usrData,
                     ProfileUserFunctions);
#endif

        (*PrimitivesArray[problem->type]->evaluateFunction)(problem->value,returnValue);

#if PROFILING_FUNCTIONS
        EndProfile(&profileFrame);
#endif

        CurrentExpression = oldArgument;
        break;
     }

   PropagateReturnValue(returnValue);
   return(EvaluationError);
  }
예제 #11
0
static struct lhsParseNode *ConjuctiveRestrictionParse(
  char *readSource,
  struct token *theToken,
  int *error)
  {
   struct lhsParseNode *bindNode;
   struct lhsParseNode *theNode, *nextOr, *nextAnd;
   int connectorType;

   /*=====================================*/
   /* Get the first node and determine if */
   /* it is a binding variable.           */
   /*=====================================*/

   theNode = LiteralRestrictionParse(readSource,theToken,error);

   if (*error == TRUE)
     { return(NULL); }

   GetToken(readSource,theToken);

   if (((theNode->type == SF_VARIABLE) || (theNode->type == MF_VARIABLE)) &&
       (theNode->negated == FALSE) &&
       (theToken->type != OR_CONSTRAINT))
     {
      theNode->bindingVariable = TRUE;
      bindNode = theNode;
      nextOr = NULL;
      nextAnd = NULL;
     }
   else
     {
      bindNode = GetLHSParseNode();
      if (theNode->type == MF_VARIABLE) bindNode->type = MF_WILDCARD;
      else bindNode->type = SF_WILDCARD;
      bindNode->negated = FALSE;
      bindNode->bottom = theNode;
      nextOr = theNode;
      nextAnd = theNode;
     }

   /*===================================*/
   /* Process the connected constraints */
   /* within the constraint             */
   /*===================================*/

   while ((theToken->type == OR_CONSTRAINT) || (theToken->type == AND_CONSTRAINT))
     {
      /*==========================*/
      /* Get the next constraint. */
      /*==========================*/

      connectorType = theToken->type;

      GetToken(readSource,theToken);
      theNode = LiteralRestrictionParse(readSource,theToken,error);

      if (*error == TRUE)
        {
         ReturnLHSParseNodes(bindNode);
         return(NULL);
        }

      /*=======================================*/
      /* Attach the new constraint to the list */
      /* of constraints for this field.        */
      /*=======================================*/

      if (connectorType == OR_CONSTRAINT)
        {
         if (nextOr == NULL)
           { bindNode->bottom = theNode; }
         else
           { nextOr->bottom = theNode; }
         nextOr = theNode;
         nextAnd = theNode;
        }
      else if (connectorType == AND_CONSTRAINT)
        {
         if (nextAnd == NULL)
           {
            bindNode->bottom = theNode;
            nextOr = theNode;
           }
         else
           { nextAnd->right = theNode; }
         nextAnd = theNode;
        }
      else
        {
         SystemError("RULEPSR",1);
         ExitRouter(EXIT_FAILURE);
        }

      /*==================================================*/
      /* Determine if any more restrictions are connected */
      /* to the current list of restrictions.             */
      /*==================================================*/

      GetToken(readSource,theToken);
     }

   /*==========================================*/
   /* Check for illegal mixing of single and   */
   /* multifield values within the constraint. */
   /*==========================================*/

   if (CheckForVariableMixing(bindNode))
     {
      *error = TRUE;
      ReturnLHSParseNodes(bindNode);
      return(NULL);
     }

   /*========================*/
   /* Return the constraint. */
   /*========================*/

   return(bindNode);
  }
예제 #12
0
globle FILE *OpenFileIfNeeded(
  FILE *theFile,
  char *fileName,
  int fileID,
  int imageID,
  int *fileCount,
  int arrayVersion,
  FILE *headerFP,
  char *structureName,
  char *structPrefix,
  int reopenOldFile,
  struct CodeGeneratorFile *codeFile)
  {
   char arrayName[80];
   char *newName;
   int newID, newVersion;

   /*===========================================*/
   /* If a file is being reopened, use the same */
   /* version number, name, and ID as before.   */
   /*===========================================*/

   if (reopenOldFile)
     {
      if (codeFile == NULL)
        {
         SystemError("CONSCOMP",5);
         ExitRouter(EXIT_FAILURE);
        }

      newName = codeFile->filePrefix;
      newID = codeFile->id;
      newVersion = codeFile->version;
     }

   /*=====================================================*/
   /* Otherwise, use the specified version number, name,  */
   /* and ID. If the appropriate argument is supplied,    */
   /* remember these values for later reopening the file. */
   /*=====================================================*/

   else
     {
      newName = fileName;
      newVersion = *fileCount;
      newID = fileID;

      if (codeFile != NULL)
        {
         codeFile->version = newVersion;
         codeFile->filePrefix = newName;
         codeFile->id = newID;
        }
     }

   /*=========================================*/
   /* If the file is already open, return it. */
   /*=========================================*/

   if (theFile != NULL)
     {
      fprintf(theFile,",\n");
      return(theFile);
     }

   /*================*/
   /* Open the file. */
   /*================*/

   if ((theFile = NewCFile(newName,newID,newVersion,reopenOldFile)) == NULL)
     { return(NULL); }

   /*=========================================*/
   /* If this is the first time the file has  */
   /* been opened, write out the beginning of */
   /* the array variable definition.          */
   /*=========================================*/

   if (reopenOldFile == FALSE)
     {
      (*fileCount)++;
      sprintf(arrayName,"%s%d_%d",structPrefix,imageID,arrayVersion);

#if SHORT_LINK_NAMES
      if (strlen(arrayName) > 6)
        {
         PrintWarningID("CONSCOMP",2,FALSE);
         PrintRouter(WWARNING,"Array name ");
         PrintRouter(WWARNING,arrayName);
         PrintRouter(WWARNING,"exceeds 6 characters in length.\n");
         PrintRouter(WWARNING,"   This variable may be indistinguishable from another by the linker.\n");
        }
#endif
      fprintf(theFile,"%s %s[] = {\n",structureName,arrayName);
      fprintf(headerFP,"extern %s %s[];\n",structureName,arrayName);
     }
   else
     { fprintf(theFile,",\n"); }

   /*==================*/
   /* Return the file. */
   /*==================*/

   return(theFile);
  }
예제 #13
0
globle FILE *CloseFileIfNeeded(
  FILE *theFile,
  int *theCount,
  int *arrayVersion,
  int maxIndices,
  int *canBeReopened,
  struct CodeGeneratorFile *codeFile)
  {
   /*==========================================*/
   /* If the maximum number of entries for the */
   /* file hasn't been exceeded, then...       */
   /*==========================================*/

   if (*theCount < maxIndices)
     {
      /*====================================*/
      /* If the file can be reopened later, */
      /* close it. Otherwise, keep it open. */
      /*====================================*/

      if (canBeReopened != NULL)
        {
         *canBeReopened = TRUE;
         fclose(theFile);
         return(NULL);
        }

      return(theFile);
     }

   /*===========================================*/
   /* Otherwise, the number of entries allowed  */
   /* in a file has been reached. Indicate that */
   /* the file can't be reopened.               */
   /*===========================================*/

   if (canBeReopened != NULL)
     { *canBeReopened = FALSE; }

   /*===============================================*/
   /* If the file is closed, then we need to reopen */
   /* it to print the final closing right brace.    */
   /*===============================================*/

   if (theFile == NULL)
     {
      if ((canBeReopened == NULL) || (codeFile == NULL))
        {
         SystemError("CONSCOMP",3);
         ExitRouter(EXIT_FAILURE);
        }

      if (codeFile->filePrefix == NULL)
        { return(NULL); }

      theFile = NewCFile(codeFile->filePrefix,codeFile->id,codeFile->version,TRUE);
      if (theFile == NULL)
        {
         SystemError("CONSCOMP",4);
         ExitRouter(EXIT_FAILURE);
        }
     }

   /*================================*/
   /* Print the final closing brace. */
   /*================================*/

   fprintf(theFile,"};\n");
   fclose(theFile);

   /*============================================*/
   /* Update index values for subsequent writing */
   /* of data structures to files.               */
   /*============================================*/

   *theCount = 0;
   (*arrayVersion)++;

   /*=========================*/
   /* Return NULL to indicate */
   /* the file is closed.     */
   /*=========================*/

   return(NULL);
  }
예제 #14
0
/***********************************************************************
  NAME         : BloadStorageObjects
  DESCRIPTION  : This routine reads class and handler information from
                 a binary file in five chunks:
                 Class count
                 Handler count
                 Class array
                 Handler array
  INPUTS       : Notthing
  RETURNS      : Nothing useful
  SIDE EFFECTS : Arrays allocated and set
  NOTES        : This routine makes no attempt to reset any pointers
                   within the structures
                 Bload fails if there are still classes in the system!!
 ***********************************************************************/
static void BloadStorageObjects()
  {
   UNLN space;
   long counts[9];

   if ((ClassIDMap != NULL) || (MaxClassID != 0))
     {
      SystemError("OBJBIN",1);
      ExitRouter(EXIT_FAILURE);
     }
   GenRead((void *) &space,(UNLN) sizeof(UNLN));
   if (space == 0L)
     {
      ClassCount = HandlerCount = 0L;
      return;
     }
   GenRead((void *) counts,space);
   ModuleCount = counts[0];
   ClassCount = counts[1];
   LinkCount = counts[2];
   SlotNameCount = counts[3];
   SlotCount = counts[4];
   TemplateSlotCount = counts[5];
   SlotNameMapCount = counts[6];
   HandlerCount = counts[7];
   MaxClassID = (unsigned short) counts[8];
   if (ModuleCount != 0L)
     {
      space = (UNLN) (sizeof(DEFCLASS_MODULE) * ModuleCount);
      ModuleArray = (DEFCLASS_MODULE *) genlongalloc(space);
     }
   if (ClassCount != 0L)
     {
      space = (UNLN) (sizeof(DEFCLASS) * ClassCount);
      defclassArray = (DEFCLASS *) genlongalloc(space);
      ClassIDMap = (DEFCLASS **) gm2((int) (sizeof(DEFCLASS *) * MaxClassID));
     }
   if (LinkCount != 0L)
     {
      space = (UNLN) (sizeof(DEFCLASS *) * LinkCount);
      linkArray = (DEFCLASS * *) genlongalloc(space);
     }
   if (SlotCount != 0L)
     {
      space = (UNLN) (sizeof(SLOT_DESC) * SlotCount);
      slotArray = (SLOT_DESC *) genlongalloc(space);
     }
   if (SlotNameCount != 0L)
     {
      space = (UNLN) (sizeof(SLOT_NAME) * SlotNameCount);
      slotNameArray = (SLOT_NAME *) genlongalloc(space);
     }
   if (TemplateSlotCount != 0L)
     {
      space = (UNLN) (sizeof(SLOT_DESC *) * TemplateSlotCount);
      tmpslotArray = (SLOT_DESC * *) genlongalloc(space);
     }
   if (SlotNameMapCount != 0L)
     {
      space = (UNLN) (sizeof(unsigned) * SlotNameMapCount);
      mapslotArray = (unsigned *) genlongalloc(space);
     }
   if (HandlerCount != 0L)
     {
      space = (UNLN) (sizeof(HANDLER) * HandlerCount);
      handlerArray = (HANDLER *) genlongalloc(space);
      space = (UNLN) (sizeof(unsigned) * HandlerCount);
      maphandlerArray = (unsigned *) genlongalloc(space);
     }
  }
예제 #15
0
static void EmptyDrive(
  struct joinNode *join,
  struct partialMatch *rhsBinds)
  {
   struct partialMatch *linker;
   struct joinNode *listOfJoins;
   int joinExpr;

   /*======================================================*/
   /* Determine if the alpha memory partial match satifies */
   /* the join expression. If it doesn't then no further   */
   /* action is taken.                                     */
   /*======================================================*/

   if (join->networkTest != NULL)
     {
      joinExpr = EvaluateJoinExpression(join->networkTest,NULL,rhsBinds,join);
      EvaluationError = FALSE;
      if (joinExpr == FALSE) return;
     }

   /*===========================================================*/
   /* The first join of a rule cannot be connected to a NOT CE. */
   /*===========================================================*/

   if (join->patternIsNegated == TRUE)
     {
      SystemError("DRIVE",2);
      ExitRouter(EXIT_FAILURE);
     }

   /*=========================================================*/
   /* If the join's RHS entry is associated with a pattern CE */
   /* (positive entry), then copy the alpha memory partial    */
   /* match and send it to all child joins.                   */
   /*=========================================================*/

   linker = CopyPartialMatch(rhsBinds,
                             (join->ruleToActivate == NULL) ? 0 : 1,
                             (int) join->logicalJoin);

   /*=======================================================*/
   /* Add the partial match to the beta memory of the join. */
   /*=======================================================*/

   linker->next = join->beta;
   join->beta = linker;

   /*====================================================*/
   /* Activate the rule satisfied by this partial match. */
   /*====================================================*/

   if (join->ruleToActivate != NULL) AddActivation(join->ruleToActivate,linker);

   /*============================================*/
   /* Send the partial match to all child joins. */
   /*============================================*/

   listOfJoins = join->nextLevel;
   while (listOfJoins != NULL)
     {
      NetworkAssert(linker,listOfJoins,LHS);
      listOfJoins = listOfJoins->rightDriveNode;
     }
  }
예제 #16
0
globle void GetNextPatternEntity(
  struct patternParser **theParser,
  struct patternEntity **theEntity)
  {
   /*=============================================================*/
   /* If the current parser is NULL, then we want to retrieve the */
   /* very first data entity. The traversal of entities is done   */
   /* by entity type (e.g. all facts are traversed followed by    */
   /* all instances). To get the first entity type to traverse,   */
   /* the current parser is set to the first parser on the list   */
   /* of pattern parsers.                                         */
   /*=============================================================*/

   if (*theParser == NULL)
     {
      *theParser = ListOfPatternParsers;
      *theEntity = NULL;
     }

   /*================================================================*/
   /* Otherwise try to retrieve the next entity following the entity */
   /* returned by the last call to GetNextEntity. If that entity was */
   /* the last of its data type, then move on to the next pattern    */
   /* parser, otherwise return that entity as the next one.          */
   /*================================================================*/

   else if (theEntity != NULL)
     {
      *theEntity = (struct patternEntity *)
                   (*(*theParser)->entityType->base.getNextFunction)(*theEntity);

      if ((*theEntity) != NULL) return;

      *theParser = (*theParser)->next;
     }

   /*===============================================================*/
   /* Otherwise, we encountered a situation which should not occur. */
   /* Once a NULL entity is returned from GetNextEntity, it should  */
   /* not be passed back to GetNextEntity.                          */
   /*===============================================================*/

   else
     {
      SystemError("PATTERN",1);
      ExitRouter(EXIT_FAILURE);
     }

   /*================================================*/
   /* Keep looping through the lists of entities and */
   /* pattern parsers until an entity is found.      */
   /*================================================*/

   while ((*theEntity == NULL) && (*theParser != NULL))
     {
      *theEntity = (struct patternEntity *)
                   (*(*theParser)->entityType->base.getNextFunction)(*theEntity);

      if (*theEntity != NULL) return;

      *theParser = (*theParser)->next;
     }

   return;
  }
예제 #17
0
globle struct CodeGeneratorItem *AddCodeGeneratorItem(
  char *name,
  int priority,
  void (*beforeFunction)(void),
  void (*initFunction)(FILE *,int,int),
  int (*generateFunction)(char *,int,FILE *,int,int),
  int arrayCount)
  {
   struct CodeGeneratorItem *newPtr, *currentPtr, *lastPtr = NULL;
   static int theCount = 0;
   register int i;
   char theBuffer[3];

   /*======================================*/
   /* Create the code generator item data  */
   /* structure and initialize its values. */
   /*======================================*/

   newPtr = get_struct(CodeGeneratorItem);

   newPtr->name = name;
   newPtr->beforeFunction = beforeFunction;
   newPtr->initFunction = initFunction;
   newPtr->generateFunction = generateFunction;
   newPtr->priority = priority;

   /*================================================*/
   /* Create the primary and secondary codes used to */
   /* provide names for the C data structure arrays. */
   /* (The maximum number of arrays is currently     */
   /* limited to 47.                                 */
   /*================================================*/

   if (arrayCount != 0)
     {
      if ((arrayCount + theCount) > (PRIMARY_LEN + SECONDARY_LEN))
        {
         SystemError("CONSCOMP",2);
         ExitRouter(EXIT_FAILURE);
        }

      newPtr->arrayNames = (char **) gm2((int) (sizeof(char *) * arrayCount));

      for (i = 0 ; i < arrayCount ; i++)
        {
         if (theCount < PRIMARY_LEN)
           { sprintf(theBuffer,"%c",PRIMARY_CODES[theCount]); }
         else
           { sprintf(theBuffer,"%c_",SECONDARY_CODES[theCount - PRIMARY_LEN]); }
         theCount++;
         newPtr->arrayNames[i] = (char *) gm2((int) (strlen(theBuffer) + 1));
         strcpy(newPtr->arrayNames[i],theBuffer);
        }
     }
   else
     { newPtr->arrayNames = NULL; }

   /*===========================================*/
   /* Add the new item in the appropriate place */
   /* in the code generator item list.          */
   /*===========================================*/

   if (ListOfCodeGeneratorItems == NULL)
     {
      newPtr->next = NULL;
      ListOfCodeGeneratorItems = newPtr;
      return(newPtr);
     }

   currentPtr = ListOfCodeGeneratorItems;
   while ((currentPtr != NULL) ? (priority < currentPtr->priority) : FALSE)
     {
      lastPtr = currentPtr;
      currentPtr = currentPtr->next;
     }

   if (lastPtr == NULL)
     {
      newPtr->next = ListOfCodeGeneratorItems;
      ListOfCodeGeneratorItems = newPtr;
     }
   else
     {
      newPtr->next = currentPtr;
      lastPtr->next = newPtr;
     }

   /*=========================*/
   /* Return a pointer to the */
   /* code generator item.    */
   /*=========================*/

   return(newPtr);
  }
예제 #18
0
globle void NetworkRetract(
  struct patternMatch *listOfMatchedPatterns)
  {
   struct patternMatch *tempMatch;
   struct partialMatch *deletedMatches, *theLast;
   struct joinNode *joinPtr;

   /*===============================*/
   /* Remember the beginning of the */
   /* list of matched patterns.     */
   /*===============================*/

   tempMatch = listOfMatchedPatterns;

   /*============================================*/
   /* Remove the data entity from all joins that */
   /* aren't directly enclosed by a not CE.      */
   /*============================================*/

   for (;
        listOfMatchedPatterns != NULL;
        listOfMatchedPatterns = listOfMatchedPatterns->next)
     {
      /*====================================*/
      /* Loop through the list of all joins */
      /* attached to this pattern.          */
      /*====================================*/

      for (joinPtr = listOfMatchedPatterns->matchingPattern->entryJoin;
           joinPtr != NULL;
           joinPtr = joinPtr->rightMatchNode)
        {
         if (joinPtr->patternIsNegated == FALSE)
           { PosEntryRetract(joinPtr,
                             listOfMatchedPatterns->theMatch->binds[0].gm.theMatch,
                             listOfMatchedPatterns->theMatch,
                             (int) joinPtr->depth - 1,TRUE); }
        }
     }

   /*============================================*/
   /* Remove the data entity from all joins that */
   /* are directly enclosed by a not CE.         */
   /*============================================*/

   listOfMatchedPatterns = tempMatch;
   while (listOfMatchedPatterns != NULL)
     {
      /*====================================*/
      /* Loop through the list of all joins */
      /* attached to this pattern.          */
      /*====================================*/

      for (joinPtr = listOfMatchedPatterns->matchingPattern->entryJoin;
           joinPtr != NULL;
           joinPtr = joinPtr->rightMatchNode)
        {
         if (joinPtr->patternIsNegated == TRUE)
           {
            if (joinPtr->firstJoin == TRUE)
              {
               SystemError("RETRACT",3);
               ExitRouter(EXIT_FAILURE);
              }
            else
              { NegEntryRetract(joinPtr,listOfMatchedPatterns->theMatch,TRUE); }
           }
        }

      /*===================================================*/
      /* Remove from the alpha memory of the pattern node. */
      /*===================================================*/

      theLast = NULL;
      listOfMatchedPatterns->matchingPattern->alphaMemory =
      RemovePartialMatches(listOfMatchedPatterns->theMatch->binds[0].gm.theMatch,
                                listOfMatchedPatterns->matchingPattern->alphaMemory,
                                &deletedMatches,0,&theLast);
      listOfMatchedPatterns->matchingPattern->endOfQueue = theLast;

      DeletePartialMatches(deletedMatches,0);

      tempMatch = listOfMatchedPatterns->next;
      rtn_struct(patternMatch,listOfMatchedPatterns);
      listOfMatchedPatterns = tempMatch;
     }

   /*=========================================*/
   /* Filter new partial matches generated by */
   /* retraction through the join network.    */
   /*=========================================*/

   DriveRetractions();
  }
예제 #19
0
/*****************************************************
  NAME         : PerformMessage
  DESCRIPTION  : Calls core framework for a message
  INPUTS       : 1) Caller's result buffer
                 2) Message argument expressions
                    (including implicit object)
                 3) Message name
  RETURNS      : Nothing useful
  SIDE EFFECTS : Any side-effects of message execution
                    and caller's result buffer set
  NOTES        : None
 *****************************************************/
static void PerformMessage(
  DATA_OBJECT *result,
  EXPRESSION *args,
  SYMBOL_HN *mname)
  {
   int oldce;
   HANDLER_LINK *oldCore;
   DEFCLASS *cls = NULL;
   INSTANCE_TYPE *ins = NULL;
   SYMBOL_HN *oldName;
#if PROFILING_FUNCTIONS
   struct profileFrameInfo profileFrame;
#endif

   result->type = SYMBOL;
   result->value = FalseSymbol;
   EvaluationError = FALSE;
   if (HaltExecution)
     return;
   oldce = ExecutingConstruct();
   SetExecutingConstruct(TRUE);
   oldName = CurrentMessageName;
   CurrentMessageName = mname;
   CurrentEvaluationDepth++;
   PushProcParameters(args,CountArguments(args),
                        ValueToString(CurrentMessageName),"message",
                        UnboundHandlerErr);

   if (EvaluationError)
     {
      CurrentEvaluationDepth--;
      CurrentMessageName = oldName;
      PeriodicCleanup(FALSE,TRUE);
      SetExecutingConstruct(oldce);
      return;
     }

   if (ProcParamArray->type == INSTANCE_ADDRESS)
     {
      ins = (INSTANCE_TYPE *) ProcParamArray->value;
      if (ins->garbage == 1)
        {
         StaleInstanceAddress("send",0);
         SetEvaluationError(TRUE);
        }
      else if (DefclassInScope(ins->cls,(struct defmodule *) GetCurrentModule()) == FALSE)
        NoInstanceError(ValueToString(ins->name),"send");
      else
        {
         cls = ins->cls;
         ins->busy++;
        }
     }
   else if (ProcParamArray->type == INSTANCE_NAME)
     {
      ins = FindInstanceBySymbol((SYMBOL_HN *) ProcParamArray->value);
      if (ins == NULL)
        {
         PrintErrorID("MSGPASS",2,FALSE);
         PrintRouter(WERROR,"No such instance ");
         PrintRouter(WERROR,ValueToString((SYMBOL_HN *) ProcParamArray->value));
         PrintRouter(WERROR," in function send.\n");
         SetEvaluationError(TRUE);
        }
      else
        {
         ProcParamArray->value = (void *) ins;
         ProcParamArray->type = INSTANCE_ADDRESS;
         cls = ins->cls;
         ins->busy++;
        }
     }
   else if ((cls = PrimitiveClassMap[ProcParamArray->type]) == NULL)
     {
      SystemError("MSGPASS",1);
      ExitRouter(EXIT_FAILURE);
     }
   if (EvaluationError)
     {
      PopProcParameters();
      CurrentEvaluationDepth--;
      CurrentMessageName = oldName;
      PeriodicCleanup(FALSE,TRUE);
      SetExecutingConstruct(oldce);
      return;
     }

   oldCore = TopOfCore;
   TopOfCore = FindApplicableHandlers(cls,mname);

   if (TopOfCore != NULL)
     {
      HANDLER_LINK *oldCurrent,*oldNext;

      oldCurrent = CurrentCore;
      oldNext = NextInCore;

#if IMPERATIVE_MESSAGE_HANDLERS

      if (TopOfCore->hnd->type == MAROUND)
        {
         CurrentCore = TopOfCore;
         NextInCore = TopOfCore->nxt;
#if DEBUGGING_FUNCTIONS
         if (WatchMessages)
           WatchMessage(WTRACE,BEGIN_TRACE);
         if (CurrentCore->hnd->trace)
           WatchHandler(WTRACE,CurrentCore,BEGIN_TRACE);
#endif
         if (CheckHandlerArgCount())
           {
#if PROFILING_FUNCTIONS
            StartProfile(&profileFrame,
                         &CurrentCore->hnd->usrData,
                         ProfileConstructs);
#endif


           EvaluateProcActions(CurrentCore->hnd->cls->header.whichModule->theModule,
                               CurrentCore->hnd->actions,
                               CurrentCore->hnd->localVarCount,
                               result,UnboundHandlerErr);


#if PROFILING_FUNCTIONS
            EndProfile(&profileFrame);
#endif
           }

#if DEBUGGING_FUNCTIONS
         if (CurrentCore->hnd->trace)
           WatchHandler(WTRACE,CurrentCore,END_TRACE);
         if (WatchMessages)
           WatchMessage(WTRACE,END_TRACE);
#endif
        }
      else

#endif  /* IMPERATIVE_MESSAGE_HANDLERS */

        {
         CurrentCore = NULL;
         NextInCore = TopOfCore;
#if DEBUGGING_FUNCTIONS
         if (WatchMessages)
           WatchMessage(WTRACE,BEGIN_TRACE);
#endif
         CallHandlers(result);
#if DEBUGGING_FUNCTIONS
         if (WatchMessages)
           WatchMessage(WTRACE,END_TRACE);
#endif
        }

      DestroyHandlerLinks(TopOfCore);
      CurrentCore = oldCurrent;
      NextInCore = oldNext;
     }

   TopOfCore = oldCore;
   ReturnFlag = FALSE;

   if (ins != NULL)
     ins->busy--;

   /* ==================================
      Restore the original calling frame
      ================================== */
   PopProcParameters();
   CurrentEvaluationDepth--;
   CurrentMessageName = oldName;
   PropagateReturnValue(result);
   PeriodicCleanup(FALSE,TRUE);
   SetExecutingConstruct(oldce);
   if (EvaluationError)
     {
      result->type = SYMBOL;
      result->value = FalseSymbol;
     }
  }