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

📄 analysis.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
        { theNode = theNode->bottom; }     }        /*========================================================*/   /* Return FALSE to indicate that no errors were detected. */   /*========================================================*/      return(CLIPS_FALSE);  }/*************************************************************//* UnboundVariablesInPattern: Verifies that variables within *//*   a slot/field have been referenced properly (i.e. that   *//*   variables have been previously bound if they are not a  *//*   binding occurrence).                                    *//*************************************************************/static BOOLEAN UnboundVariablesInPattern(theSlot,pattern)  struct lhsParseNode *theSlot;  int pattern;  {   struct lhsParseNode *andField;   struct lhsParseNode *rv;   int result;   struct lhsParseNode *orField;   struct symbolHashNode *slotName;   CONSTRAINT_RECORD *theConstraints;   int theField;   /*===================================================*/   /* If a multifield slot is being checked, then check */   /* each of the fields grouped with the multifield.   */   /*===================================================*/      if (theSlot->multifieldSlot)     {      theSlot = theSlot->bottom;      while (theSlot != NULL)        {         if (UnboundVariablesInPattern(theSlot,pattern))           { return(CLIPS_TRUE); }         theSlot = theSlot->right;        }              return(CLIPS_FALSE);     }       /*=======================*/   /* Check a single field. */   /*=======================*/      slotName = theSlot->slot;   theField = theSlot->index;   theConstraints = theSlot->constraints;      /*===========================================*/   /* Loop through each of the '|' constraints. */   /*===========================================*/      for (orField = theSlot->bottom;        orField != NULL;        orField = orField->bottom)     {         /*===========================================*/      /* Loop through each of the fields connected */      /* by the '&' within the '|' constraint.     */      /*===========================================*/      for (andField = orField;           andField != NULL;           andField = andField->right)        {         /*=======================================================*/         /* If this is not a binding occurence of a variable and  */         /* there is no previous binding occurence of a variable, */         /* then generate an error message for a variable that is */         /* referred to but not bound.                            */         /*=======================================================*/                  if (((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) &&             (andField->referringNode == NULL))           {            VariableReferenceErrorMessage((SYMBOL_HN *) andField->value,NULL,pattern,                                          slotName,theField);            return(CLIPS_TRUE);           }                    /*==============================================*/         /* Check predicate and return value constraints */         /* to insure that all variables used within the */         /* constraint have been previously bound.       */         /*==============================================*/                      else if ((andField->type == PREDICATE_CONSTRAINT) ||                  (andField->type == RETURN_VALUE_CONSTRAINT))           {            rv = CheckExpression(andField->expression,NULL,pattern,slotName,theField);             if (rv != NULL) return(CLIPS_TRUE);           }                    /*========================================================*/         /* If static constraint checking is being performed, then */         /* determine if constant values have violated the set of  */         /* derived constraints for the slot/field (based on the   */         /* deftemplate definition and propagated constraints).    */         /*========================================================*/                  else if (((andField->type == INTEGER) || (andField->type == FLOAT) ||                   (andField->type == SYMBOL) || (andField->type == STRING) ||                   (andField->type == INSTANCE_NAME)) &&                  GetStaticConstraintChecking())           {            result = ConstraintCheckValue(andField->type,andField->value,theConstraints);            if (result != NO_VIOLATION)              {               ConstraintViolationErrorMessage("A literal restriction value",                                               NULL,CLIPS_FALSE,pattern,                                               slotName,theField,result,                                               theConstraints,CLIPS_TRUE);               return(CLIPS_TRUE);              }           }        }     }   /*===============================*/   /* Return FALSE to indicate that */   /* no errors were detected.      */   /*===============================*/      return(CLIPS_FALSE);  }/******************************************************************//* CheckExpression: Verifies that variables within an expression  *//*   have been referenced properly. All variables within an       *//*   expression must have been previously bound.                  *//******************************************************************/static struct lhsParseNode *CheckExpression(exprPtr,lastOne,whichCE,slotName,theField)  struct lhsParseNode *exprPtr, *lastOne;  int whichCE;  struct symbolHashNode *slotName;  int theField;  {   struct lhsParseNode *rv;   int i = 1;   while (exprPtr != NULL)     {      /*===============================================================*/      /* Check that single field variables contained in the expression */      /* were previously defined in the LHS. Also check to see if the  */      /* variable has unmatchable constraints.                         */      /*===============================================================*/            if (exprPtr->type == SF_VARIABLE)         {          if (exprPtr->referringNode == NULL)           {            VariableReferenceErrorMessage((SYMBOL_HN *) exprPtr->value,lastOne,                                          whichCE,slotName,theField);            return(exprPtr);           }         else if ((UnmatchableConstraint(exprPtr->constraints)) &&                  GetStaticConstraintChecking())           {            ConstraintReferenceErrorMessage((SYMBOL_HN *) exprPtr->value,lastOne,i,                                            whichCE,slotName,theField);            return(exprPtr);            }        }                  /*==================================================*/      /* Check that multifield variables contained in the */      /* expression were previously defined in the LHS.   */      /*==================================================*/      else if ((exprPtr->type == MF_VARIABLE) && (exprPtr->referringNode == NULL))        {          VariableReferenceErrorMessage((SYMBOL_HN *) exprPtr->value,lastOne,                                       whichCE,slotName,theField);         return(exprPtr);         }            /*=====================================================*/      /* Check that global variables are referenced properly */      /* (i.e. if you reference a global variable, it must   */      /* already be defined by a defglobal construct).       */      /*=====================================================*/#if DEFGLOBAL_CONSTRUCT      else if (exprPtr->type == GBL_VARIABLE)        {         int count;                  if (FindImportedConstruct("defglobal",NULL,ValueToString(exprPtr->value),                                   &count,CLIPS_TRUE,NULL) == NULL)           {            VariableReferenceErrorMessage((SYMBOL_HN *) exprPtr->value,lastOne,                                          whichCE,slotName,theField);            return(exprPtr);           }        }#endif      /*============================================*/      /* Recursively check other function calls to  */      /* insure variables are referenced correctly. */      /*============================================*/            else if (((exprPtr->type == FCALL)#if DEFGENERIC_CONSTRUCT             || (exprPtr->type == GCALL)#endif#if DEFFUNCTION_CONSTRUCT             || (exprPtr->type == PCALL)#endif         ) && (exprPtr->bottom != NULL))        {         if ((rv = CheckExpression(exprPtr->bottom,exprPtr,whichCE,slotName,theField)) != NULL)           { return(rv); }        }            /*=============================================*/      /* Move on to the next part of the expression. */      /*=============================================*/            i++;      exprPtr = exprPtr->right;     }   /*================================================*/   /* Return NULL to indicate no error was detected. */   /*================================================*/      return(NULL);  } /********************************************************//* VariableReferenceErrorMessage: Generic error message *//*   for referencing a variable before it is defined.   *//********************************************************/static VOID VariableReferenceErrorMessage(theVariable,theExpression,whichCE,slotName,theField)  struct symbolHashNode *theVariable;  struct lhsParseNode *theExpression;  int whichCE;  struct symbolHashNode *slotName;  int theField;  {   struct expr *temprv;      /*=============================*/   /* Print the error message ID. */   /*=============================*/      PrintErrorID("ANALYSIS",4,CLIPS_TRUE);   /*=================================*/   /* Print the name of the variable. */   /*=================================*/      PrintCLIPS(WERROR,"Variable ?");   PrintCLIPS(WERROR,ValueToString(theVariable));   PrintCLIPS(WERROR," ");      /*=================================================*/   /* If the variable was found inside an expression, */   /* then print the expression.                      */   /*=================================================*/      if (theExpression != NULL)     {      temprv = LHSParseNodesToExpression(theExpression);      ReturnExpression(temprv->nextArg);      temprv->nextArg = NULL;      PrintCLIPS(WERROR,"found in the expression ");      PrintExpression(WERROR,temprv);      PrintCLIPS(WERROR,"\n");      ReturnExpression(temprv);     }      /*====================================================*/   /* Print the CE in which the variable was referenced. */   /*====================================================*/      PrintCLIPS(WERROR,"was referenced in CE #");   PrintLongInteger(WERROR,(long int) whichCE);      /*=====================================*/   /* Identify the slot or field in which */   /* the variable was found.             */   /*=====================================*/      if (slotName == NULL)     {      if (theField > 0)        {         PrintCLIPS(WERROR," field #");         PrintLongInteger(WERROR,(long int) theField);        }     }   else     {      PrintCLIPS(WERROR," slot ");      PrintCLIPS(WERROR,ValueToString(slotName));     }              PrintCLIPS(WERROR," before being defined.\n");  }  /************************************************************//* VariableMixingErrorMessage: Prints the error message for *//*   the illegal mixing of single and multifield variables  *//*   on the LHS of a rule.                                  *//************************************************************/static VOID VariableMixingErrorMessage(theVariable)  struct symbolHashNode *theVariable;  {   PrintErrorID("ANALYSIS",3,CLIPS_TRUE);   PrintCLIPS(WERROR,"Variable ?");   PrintCLIPS(WERROR,ValueToString(theVariable));   PrintCLIPS(WERROR," is used as both a single and multifield variable in the LHS\n");  }#endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */

⌨️ 快捷键说明

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