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

📄 analysis.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/
   /*      "C" Language Integrated Production System      */
   /*                                                     */
   /*             CLIPS Version 6.24  06/05/06            */
   /*                                                     */
   /*                  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:                                         */
/*                                                           */
/*      6.24: Renamed BOOLEAN macro type to intBool.         */
/*                                                           */
/*************************************************************/

#define _ANALYSIS_SOURCE_

#include "setup.h"

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

#include <stdio.h>
#define _STDIO_INCLUDED_

#include "constant.h"
#include "symbol.h"
#include "memalloc.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 */
/***************************************/

   static int                     GetVariables(void *,struct lhsParseNode *);
   static intBool                 UnboundVariablesInPattern(void *,struct lhsParseNode *,int);
   static int                     PropagateVariableToNodes(void *,
                                                           struct lhsParseNode *,
                                                           int,
                                                           struct symbolHashNode *,
                                                           struct lhsParseNode *,
                                                           int,int,int);
   static struct lhsParseNode    *CheckExpression(void *,
                                                  struct lhsParseNode *,
                                                  struct lhsParseNode *,
                                                  int,
                                                  struct symbolHashNode *,
                                                  int);
   static void                    VariableReferenceErrorMessage(void *,
                                                                struct symbolHashNode *,
                                                                struct lhsParseNode *,
                                                                int,
                                                                struct symbolHashNode *,
                                                                int);
   static int                     ProcessField(void *theEnv,
                                               struct lhsParseNode *,
                                               struct lhsParseNode *,
                                               struct lhsParseNode *);
   static int                     ProcessVariable(void *,
                                               struct lhsParseNode *,
                                               struct lhsParseNode *,
                                               struct lhsParseNode *);
   static void                    VariableMixingErrorMessage(void *,struct symbolHashNode *);
   static int                     PropagateVariableDriver(void *,
                                                          struct lhsParseNode *,
                                                          struct lhsParseNode *,
                                                          struct lhsParseNode *,
                                                          int,struct symbolHashNode *,
                                                          struct lhsParseNode *,
                                                          int);

/******************************************************************/
/* 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(
  void *theEnv,
  struct lhsParseNode *patternPtr)
  {
   struct lhsParseNode *rv, *theList, *tempList;
   int errorFlag = 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 = TRUE;
            if (patternPtr->referringNode->index == -1)
              {
               PrintErrorID(theEnv,"ANALYSIS",1,TRUE);
               EnvPrintRouter(theEnv,WERROR,"Duplicate pattern-address ?");
               EnvPrintRouter(theEnv,WERROR,ValueToString(patternPtr->value));
               EnvPrintRouter(theEnv,WERROR," found in CE #");
               PrintLongInteger(theEnv,WERROR,(long) patternPtr->whichCE);
               EnvPrintRouter(theEnv,WERROR,".\n");
              }
            else
              {
               PrintErrorID(theEnv,"ANALYSIS",2,TRUE);
               EnvPrintRouter(theEnv,WERROR,"Pattern-address ?");
               EnvPrintRouter(theEnv,WERROR,ValueToString(patternPtr->value));
               EnvPrintRouter(theEnv,WERROR," used in CE #");
               PrintLongInteger(theEnv,WERROR,(long) patternPtr->whichCE);
               EnvPrintRouter(theEnv,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(theEnv,patternPtr)) return(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(theEnv,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(theEnv,patternPtr->expression);
         for (tempList = theList; tempList != NULL; tempList = tempList->right)
            {
             if (PropagateVariableDriver(theEnv,patternPtr,patternPtr,NULL,SF_VARIABLE,
                                         (SYMBOL_HN *) tempList->value,tempList,FALSE))
               {
                ReturnLHSParseNodes(theEnv,theList);
                return(TRUE);
               }
            }
         ReturnLHSParseNodes(theEnv,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 = TRUE; }
         else
           { patternPtr->networkTest = GetvarReplace(theEnv,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(
  void *theEnv,
  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(theEnv,thePattern,multifieldHeader,patternHead))
              { return(TRUE); }
           }
         else
           {
            if (ProcessField(theEnv,thePattern,multifieldHeader,patternHead))
              { return(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(FALSE);
  }

/******************************************************/
/* ProcessVariable: Processes a single occurence of a */
/*   variable by propagating references to it.        */
/******************************************************/
static int ProcessVariable(
  void *theEnv,
  struct lhsParseNode *thePattern,
  struct lhsParseNode *multifieldHeader,
  struct lhsParseNode *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;
      theVariable = (struct symbolHashNode *) thePattern->value;
      if (thePattern->derivedConstraints) RemoveConstraint(theEnv,thePattern->constraints);

⌨️ 快捷键说明

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