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

📄 analysis.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.05  04/09/97            */   /*                                                     */   /*                  ANALYSIS MODULE                    */   /*******************************************************//*************************************************************//* Purpose: Analyzes LHS patterns to check for semantic      *//*   errors and to determine variable comparisons and other  *//*   tests which must be performed either in the pattern or  *//*   join networks.                                          *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*                                                           *//*************************************************************/#define _ANALYSIS_SOURCE_#include "setup.h"#if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT#include <stdio.h>#define _CLIPS_STDIO_#include "constant.h"#include "symbol.h"#include "clipsmem.h"#include "exprnpsr.h"#include "reorder.h"#include "generate.h"#include "pattern.h"#include "router.h"#include "ruledef.h"#include "cstrnchk.h"#include "cstrnutl.h"#include "cstrnops.h"#include "rulecstr.h"#include "modulutl.h"#include "analysis.h"#if DEFGLOBAL_CONSTRUCT#include "globldef.h"#endif/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ #if ANSI_COMPILER   static int                     GetVariables(struct lhsParseNode *);   static BOOLEAN                 UnboundVariablesInPattern(struct lhsParseNode *,int);   static int                     PropagateVariableToNodes(struct lhsParseNode *,                                                           int,                                                           struct symbolHashNode *,                                                           struct lhsParseNode *,                                                           int,int,int);   static struct lhsParseNode    *CheckExpression(struct lhsParseNode *,                                                  struct lhsParseNode *,                                                  int,                                                  struct symbolHashNode *,                                                  int);   static VOID                    VariableReferenceErrorMessage(struct symbolHashNode *,                                                                struct lhsParseNode *,                                                                int,                                                                struct symbolHashNode *,                                                                int);   static int                     ProcessField(struct lhsParseNode *,                                               struct lhsParseNode *,                                               struct lhsParseNode *);   static int                     ProcessVariable(struct lhsParseNode *,                                               struct lhsParseNode *,                                               struct lhsParseNode *);   static VOID                    VariableMixingErrorMessage(struct symbolHashNode *);   static int                     PropagateVariableDriver(struct lhsParseNode *,                                                          struct lhsParseNode *,                                                          struct lhsParseNode *,                                                          int,struct symbolHashNode *,                                                          struct lhsParseNode *,                                                          int);#else   static int                     GetVariables();   static BOOLEAN                 UnboundVariablesInPattern();   static int                     PropagateVariableToNodes();   static struct lhsParseNode    *CheckExpression();   static VOID                    VariableReferenceErrorMessage();   static int                     ProcessField();   static int                     ProcessVariable();   static VOID                    VariableMixingErrorMessage();   static int                     PropagateVariableDriver();#endif  /******************************************************************//* VariableAnalysis: Propagates variables references to other     *//*   variables in the LHS and determines if there are any illegal *//*   variable references (e.g. referring to an unbound variable). *//*   The propagation of variable references simply means all      *//*   subsequent references of a variable are made to "point" back *//*   to the variable being propagated.                            *//******************************************************************/globle int VariableAnalysis(patternPtr)  struct lhsParseNode *patternPtr;  {   struct lhsParseNode *rv, *theList, *tempList;   int errorFlag = CLIPS_FALSE;   /*======================================================*/   /* Loop through all of the CEs in the rule to determine */   /* which variables refer to other variables and whether */   /* any semantic errors exist when refering to variables */   /* (such as referring to a variable that was not        */   /* previously bound).                                   */   /*======================================================*/   while (patternPtr != NULL)     {      /*=========================================================*/      /* If a pattern CE is encountered, propagate any variables */      /* found in the pattern and note any illegal references to */      /* other variables.                                        */      /*=========================================================*/            if (patternPtr->type == PATTERN_CE)        {                  /*====================================================*/         /* Determine if the fact address associated with this */         /* pattern illegally refers to other variables.       */         /*====================================================*/                  if ((patternPtr->value != NULL) &&              (patternPtr->referringNode != NULL))           {            errorFlag = CLIPS_TRUE;            if (patternPtr->referringNode->index == -1)              {               PrintErrorID("ANALYSIS",1,CLIPS_TRUE);               PrintCLIPS(WERROR,"Duplicate pattern-address ?");               PrintCLIPS(WERROR,ValueToString(patternPtr->value));               PrintCLIPS(WERROR," found in CE #");               PrintLongInteger(WERROR,(long) patternPtr->whichCE);               PrintCLIPS(WERROR,".\n");              }            else              {               PrintErrorID("ANALYSIS",2,CLIPS_TRUE);               PrintCLIPS(WERROR,"Pattern-address ?");               PrintCLIPS(WERROR,ValueToString(patternPtr->value));               PrintCLIPS(WERROR," used in CE #");               PrintLongInteger(WERROR,(long) patternPtr->whichCE);               PrintCLIPS(WERROR," was previously bound within a pattern CE.\n");              }           }                  /*====================================================*/         /* Propagate the pattern and field location of bound  */         /* variables found in this pattern to other variables */         /* in the same semantic scope as the bound variable.  */         /*====================================================*/                  if (GetVariables(patternPtr)) return(CLIPS_TRUE);         }              /*==============================================================*/      /* If a test CE is encountered, make sure that all references   */      /* to variables have been previously bound. If they are bound   */      /* then replace the references to variables with function calls */      /* to retrieve the variables.                                   */      /*==============================================================*/             else if (patternPtr->type == TEST_CE)        {          /*=====================================================*/         /* Verify that all variables were referenced properly. */         /*=====================================================*/                  rv = CheckExpression(patternPtr->expression,NULL,(int) patternPtr->whichCE,NULL,0);                   /*=========================================================*/         /* Determine the type and value constraints implied by the */         /* expression and propagate these constraints to other     */         /* variables in the LHS. For example, the expression       */         /* (+ ?x 1) implies that ?x is a number.                   */         /*=========================================================*/                  theList = GetExpressionVarConstraints(patternPtr->expression);         for (tempList = theList; tempList != NULL; tempList = tempList->right)            {             if (PropagateVariableDriver(patternPtr,patternPtr,NULL,SF_VARIABLE,                                         tempList->value,tempList,CLIPS_FALSE))               {                 ReturnLHSParseNodes(theList);                return(CLIPS_TRUE);               }            }         ReturnLHSParseNodes(theList);                  /*========================================================*/         /* If the variables in the expression were all referenced */         /* properly, then create the expression to use in the     */         /* join network.                                          */         /*========================================================*/                  if (rv != NULL)           { errorFlag = CLIPS_TRUE; }         else           { patternPtr->networkTest = GetvarReplace(patternPtr->expression); }        }      /*=====================================================*/      /* Move on to the next pattern in the LHS of the rule. */      /*=====================================================*/            patternPtr = patternPtr->bottom;     }        /*==========================================*/   /* Return the error status of the analysis. */   /*==========================================*/      return(errorFlag);  }  /****************************************************************//* GetVariables: Loops through each field/slot within a pattern *//*   and propagates the pattern and field location of bound     *//*   variables found in the pattern to other variables within   *//*   the same semantic scope as the bound variables.            *//****************************************************************/static int GetVariables(thePattern)  struct lhsParseNode *thePattern;  {   struct lhsParseNode *patternHead = thePattern;   struct lhsParseNode *multifieldHeader = NULL;        /*======================================================*/   /* Loop through all the fields/slots found in a pattern */   /* looking for binding instances of variables.          */   /*======================================================*/      while (thePattern != NULL)     {      /*================================================*/      /* A multifield slot contains a sublist of fields */      /* that must be traversed and checked.            */      /*================================================*/            if (thePattern->multifieldSlot)        {         multifieldHeader = thePattern;         thePattern = thePattern->bottom;        }              /*==================================================*/      /* Propagate the binding occurences of single field */      /* variables, multifield variables, and fact        */      /* addresses to other occurences of the variable.   */      /* If an error is encountered, return TRUE.         */      /*==================================================*/              if (thePattern != NULL)        {         if ((thePattern->type == SF_VARIABLE) ||             (thePattern->type == MF_VARIABLE) ||             ((thePattern->type == PATTERN_CE) && (thePattern->value != NULL)))           {            if (ProcessVariable(thePattern,multifieldHeader,patternHead))              { return(CLIPS_TRUE); }           }         else           {               if (ProcessField(thePattern,multifieldHeader,patternHead))              { return(CLIPS_TRUE); }           }        }              /*===============================================*/      /* Move on to the next field/slot in the pattern */      /* or to the next field in a multifield slot.    */      /*===============================================*/            if (thePattern == NULL)         { thePattern = multifieldHeader; }      else if ((thePattern->right == NULL) && (multifieldHeader != NULL))        {         thePattern = multifieldHeader;         multifieldHeader = NULL;        }              thePattern = thePattern->right;     }        /*===============================*/   /* Return FALSE to indicate that */   /* no errors were detected.      */   /*===============================*/      return(CLIPS_FALSE);  }  /******************************************************//* ProcessVariable: Processes a single occurence of a *//*   variable by propagating references to it.        */                     /******************************************************/static int ProcessVariable(thePattern,multifieldHeader,patternHead)  struct lhsParseNode *thePattern, *multifieldHeader, *patternHead;  {   int theType;   struct symbolHashNode *theVariable;   struct constraintRecord *theConstraints;      /*=============================================================*/   /* If a pattern address is being propagated, then treat it as  */   /* a single field pattern variable and create a constraint     */   /* which indicates that is must be a fact or instance address. */   /* This code will have to be modified for new data types which */   /* can match patterns.                                         */   /*=============================================================*/      if (thePattern->type == PATTERN_CE)      {      theType = SF_VARIABLE;

⌨️ 快捷键说明

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