⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pattern.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************/globle struct patternParser *FindPatternParser(name)  char *name;  {   struct patternParser *tempParser;   for (tempParser = ListOfPatternParsers;        tempParser != NULL;        tempParser = tempParser->next)     { if (strcmp(tempParser->name,name) == 0) return(tempParser); }        return(NULL);  }/******************************************************//* GetPatternParser: Returns a pointer to the pattern *//*    parser for the specified data entity.           *//******************************************************/struct patternParser *GetPatternParser(rhsType)  int rhsType;  {   return(PatternParserArray[rhsType]);  }#if CONSTRUCT_COMPILER && (! RUN_TIME)/*************************************************************//* PatternNodeHeaderToCode: Writes the C code representation *//*   of a patternNodeHeader data structure.                  *//*************************************************************/globle VOID PatternNodeHeaderToCode(fp,theHeader,imageID,maxIndices)  FILE *fp;  struct patternNodeHeader *theHeader;  int imageID;  int maxIndices;  {   fprintf(fp,"{NULL,NULL,");      if (theHeader->entryJoin == NULL)     { fprintf(fp,"NULL,"); }   else     {      fprintf(fp,"&%s%d_%d[%d],",                 JoinPrefix(),imageID,                 (((int) theHeader->entryJoin->bsaveID) / maxIndices) + 1,                 ((int) theHeader->entryJoin->bsaveID) % maxIndices);     }      fprintf(fp,"%d,%d,%d,0,0,%d,%d}",theHeader->singlefieldNode,                                     theHeader->multifieldNode,                                     theHeader->stopNode,                                     theHeader->beginSlot,                                     theHeader->endSlot);  }#endif /* CONSTRUCT_COMPILER && (! RUN_TIME) */#if (! RUN_TIME) && (! BLOAD_ONLY)/****************************************************************//* PostPatternAnalysis: Calls the post analysis routines for    *//*   each of the pattern parsers to allow additional processing *//*   by the pattern parser after the variable analysis routines *//*   have analyzed the LHS patterns.                            *//****************************************************************/globle BOOLEAN PostPatternAnalysis(theLHS)  struct lhsParseNode *theLHS;  {   struct lhsParseNode *patternPtr;   struct patternParser *tempParser;      for (patternPtr = theLHS; patternPtr != NULL; patternPtr = patternPtr->bottom)     {      if ((patternPtr->type == PATTERN_CE) && (patternPtr->patternType != NULL))        {         tempParser = patternPtr->patternType;         if (tempParser->postAnalysisFunction != NULL)           { if ((*tempParser->postAnalysisFunction)(patternPtr)) return(CLIPS_TRUE); }        }     }           return(CLIPS_FALSE);  }/******************************************************************//* RestrictionParse: Parses a single field within a pattern. This *//*    field may either be a single field wildcard, a multifield   *//*    wildcard, a single field variable, a multifield variable,   *//*    or a series of connected constraints.                       *//*                                                                *//* <constraint> ::= ? |                                           *//*                  $? |                                          *//*                  <connected-constraint>                        *//******************************************************************/struct lhsParseNode *RestrictionParse(readSource,theToken,multifieldSlot,                                      theSlot,slotNumber,theConstraints,                                      position)  char *readSource;  struct token *theToken;  int multifieldSlot;  struct symbolHashNode *theSlot;  int slotNumber;  CONSTRAINT_RECORD *theConstraints;  int position;  {   struct lhsParseNode *topNode = NULL, *lastNode = NULL, *nextNode;   int numberOfSingleFields = 0;   int numberOfMultifields = 0;   int startPosition = position;   int error = CLIPS_FALSE;   CONSTRAINT_RECORD *tempConstraints;      /*==================================================*/   /* Keep parsing fields until a right parenthesis is */   /* encountered. This will either indicate the end   */   /* of an instance or deftemplate slot or the end of */   /* an ordered fact.                                 */   /*==================================================*/      while (theToken->type != RPAREN)     {      /*========================================*/      /* Look for either a single or multifield */      /* wildcard or a conjuctive restriction.  */      /*========================================*/            if ((theToken->type == SF_WILDCARD) ||          (theToken->type == MF_WILDCARD))        {         nextNode = GetLHSParseNode();         nextNode->type = theToken->type;         nextNode->negated = CLIPS_FALSE;         GetToken(readSource,theToken);        }      else        {          nextNode = ConjuctiveRestrictionParse(readSource,theToken,&error);         if (nextNode == NULL)           {            ReturnLHSParseNodes(topNode);            return(NULL);           }        }                    /*========================================================*/      /* Fix up the pretty print representation of a multifield */      /* slot so that the fields don't run together.            */      /*========================================================*/            if ((theToken->type != RPAREN) && (multifieldSlot == CLIPS_TRUE))        {         PPBackup();         SavePPBuffer(" ");         SavePPBuffer(theToken->printForm);        }            /*========================================*/      /* Keep track of the number of single and */      /* multifield restrictions encountered.   */      /*========================================*/            if ((nextNode->type == SF_WILDCARD) || (nextNode->type == SF_VARIABLE))        { numberOfSingleFields++; }      else        { numberOfMultifields++; }              /*===================================*/      /* Assign the slot name and indices. */      /*===================================*/            nextNode->slot = theSlot;      nextNode->slotNumber = slotNumber;      nextNode->index = position++;            /*==============================================*/      /* If we're not dealing with a multifield slot, */      /* attach the constraints directly to the node  */      /* and return.                                  */      /*==============================================*/            if (! multifieldSlot)        {         if (theConstraints == NULL)            {             if (nextNode->type == SF_VARIABLE)              { nextNode->constraints = GetConstraintRecord(); }            else nextNode->constraints = NULL;           }         else nextNode->constraints = theConstraints;          return(nextNode);        }              /*====================================================*/      /* Attach the restriction to the list of restrictions */      /* already parsed for this slot or ordered fact.      */      /*====================================================*/            if (lastNode == NULL) topNode = nextNode;      else lastNode->right = nextNode;            lastNode = nextNode;     }   /*=====================================================*/   /* Once we're through parsing, check to make sure that */   /* a single field slot was given a restriction. If the */   /* following test fails, then we know we're dealing    */   /* with a multifield slot.                             */   /*=====================================================*/   if ((topNode == NULL) && (! multifieldSlot))     {      SyntaxErrorMessage("defrule");      return(NULL);     }         /*===============================================*/   /* Loop through each of the restrictions in the  */   /* list of restrictions for the multifield slot. */   /*===============================================*/       for (nextNode = topNode; nextNode != NULL; nextNode = nextNode->right)     {      /*===================================================*/      /* Assign a constraint record to each constraint. If */      /* the slot has an explicit constraint, then copy    */      /* this and store it with the constraint. Otherwise, */      /* create a constraint record for a single field     */      /* constraint and skip the constraint modifications  */      /* for a multifield constraint.                      */      /*===================================================*/                if (theConstraints == NULL)        {         if (nextNode->type == SF_VARIABLE)           { nextNode->constraints = GetConstraintRecord(); }         else           { continue; }        }      else        { nextNode->constraints = CopyConstraintRecord(theConstraints); }              /*==========================================*/      /* Remove the min and max field constraints */      /* for the entire slot from the constraint  */      /* record for this single constraint.       */      /*==========================================*/            ReturnExpression(nextNode->constraints->minFields);      ReturnExpression(nextNode->constraints->maxFields);      nextNode->constraints->minFields = GenConstant(SYMBOL,NegativeInfinity);      nextNode->constraints->maxFields = GenConstant(SYMBOL,PositiveInfinity);      nextNode->derivedConstraints = CLIPS_TRUE;                /*====================================================*/      /* If we're not dealing with a multifield constraint, */      /* then no further modifications are needed to the    */      /* min and max constraints for this constraint.       */      /*====================================================*/            if ((nextNode->type != MF_WILDCARD) && (nextNode->type != MF_VARIABLE))        { continue; }            /*==========================================================*/      /* Create a separate constraint record to keep track of the */      /* cardinality information for this multifield constraint.  */      /*==========================================================*/            tempConstraints = GetConstraintRecord();      SetConstraintType(MULTIFIELD,tempConstraints);      tempConstraints->singlefieldsAllowed = CLIPS_FALSE;      tempConstraints->multifield = nextNode->constraints;      nextNode->constraints = tempConstraints;               /*=====================================================*/      /* Adjust the min and max field values for this single */      /* multifield constraint based on the min and max      */      /* fields for the entire slot and the number of single */      /* field values contained in the slot.                 */      /*=====================================================*/            if (theConstraints->maxFields->value != PositiveInfinity)        {         ReturnExpression(tempConstraints->maxFields);         tempConstraints->maxFields = GenConstant(INTEGER,AddLong(ValueToLong(theConstraints->maxFields->value) - numberOfSingleFields));        }                  if ((numberOfMultifields == 1) && (theConstraints->minFields->value != NegativeInfinity))        {         ReturnExpression(tempConstraints->minFields);         tempConstraints->minFields = GenConstant(INTEGER,AddLong(ValueToLong(theConstraints->minFields->value) - numberOfSingleFields));        }     }         /*================================================*/   /* If a multifield slot is being parsed, place a  */   /* node on top of the list of constraints parsed. */   /*================================================*/      if (multifieldSlot)     {      nextNode = GetLHSParseNode();      nextNode->type = MF_WILDCARD;      nextNode->multifieldSlot = CLIPS_TRUE;      nextNode->bottom = topNode;      nextNode->slot = theSlot;      nextNode->slotNumber = slotNumber;      nextNode->index = startPosition;      nextNode->constraints = theConstraints;      topNode = nextNode;      TallyFieldTypes(topNode->bottom);     }        /*=================================*/   /* Return the list of constraints. */   /*=================================*/      return(topNode);  }/***************************************************************//* TallyFieldTypes: Determines the number of single field and  *//*   multifield variables and wildcards that appear before and *//*   after each restriction found in a multifield slot.        *//***************************************************************/static VOID TallyFieldTypes(theRestrictions)  struct lhsParseNode *theRestrictions;  {   struct lhsParseNode *tempNode1, *tempNode2, *tempNode3;   int totalSingleFields = 0, totalMultiFields = 0;   int runningSingleFields = 0, runningMultiFields = 0;      /*========================================*/   /* Compute the total number of single and */   /* multifield variables and wildcards.    */   /*========================================*/      for (tempNode1 = theRestrictions; tempNode1 != NULL; tempNode1 = tempNode1->right)     {      if ((tempNode1->type == SF_VARIABLE) || (tempNode1->type == SF_WILDCARD))        { totalSingleFields++; }      else        { totalMultiFields++; }     }        /*======================================================*/   /* Loop through each constraint tallying the numbers of */   /* the variable types before and after along the way.   */   /*======================================================*/      for (tempNode1 = theRestrictions; tempNode1 != NULL; tempNode1 = tempNode1->right)     {      /*===================================*/      /* Assign the values to the "binding */      /* variable" node of the constraint. */      /*===================================*/            tempNode1->singleFieldsBefore = runningSingleFields;      tempNode1->multiFieldsBefore = runningMultiFields;      tempNode1->withinMultifieldSlot = CLIPS_TRUE;            if ((tempNode1->type == SF_VARIABLE) || (tempNode1->type == SF_WILDCARD))        {          tempNode1->singleFieldsAfter = totalSingleFields - (runningSingleFields + 1);         tempNode1->multiFieldsAfter = totalMultiFields - runningMultiFields;        }      else        {          tempNode1->singleFieldsAfter = totalSingleFields - runningSingleFields;         tempNode1->multiFieldsAfter = totalMultiFields - (runningMultiFields + 1);        }               /*=====================================================*/      /* Assign the values to each of the and (&) and or (|) */      /* connected constraints within the constraint.        */      /*=====================================================*/            for (tempNode2 = tempNode1->bottom; tempNode2 != NULL; tempNode2 = tempNode2->bottom)        {         for (tempNode3 = tempNode2; tempNode3 != NULL; tempNode3 = tempNode3->right)           {            tempNode3->singleFieldsBefore = tempNode1->singleFieldsBefore;            tempNode3->singleFieldsAfter = tempNode1->singleFieldsAfter;            tempNode3->multiFieldsBefore = tempNode1->multiFieldsBefore;            tempNode3->multiFieldsAfter = tempNode1->multiFieldsAfter;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -