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

📄 drive.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.05  04/09/97            */   /*                                                     */   /*                    DRIVE MODULE                     */   /*******************************************************//*************************************************************//* Purpose: Handles join network activity associated with    *//*   with the addition of a data entity such as a fact or    *//*   instance.                                               *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*                                                           *//*************************************************************/#define _DRIVE_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#if DEFRULE_CONSTRUCT#include "constant.h"#include "clipsmem.h"#include "reteutil.h"#include "prntutil.h"#include "router.h"#include "agenda.h"#include "retract.h"#if LOGICAL_DEPENDENCIES#include "lgcldpnd.h"#endif#if INCREMENTAL_RESET#include "incrrset.h"#endif#include "drive.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER   static VOID                    PPDrive(struct partialMatch *,struct partialMatch *,struct joinNode *);   static VOID                    PNRDrive(struct joinNode *,struct partialMatch *,                                           struct partialMatch *);   static VOID                    EmptyDrive(struct joinNode *,struct partialMatch *);   static VOID                    JoinNetErrorMessage(struct joinNode *);#else   static VOID                    PPDrive();   static VOID                    PNRDrive();   static VOID                    EmptyDrive();   static VOID                    JoinNetErrorMessage();#endif/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/   globle BOOLEAN              JoinOperationInProgress = CLIPS_FALSE;   /************************************************//* NetworkAssert: Primary routine for filtering *//*   a partial match through the join network.  *//************************************************/globle VOID NetworkAssert(binds,join,enterDirection)  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 == CLIPS_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 = CLIPS_TRUE;      newBinds->counterf = CLIPS_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     {      CLIPSSystemError("DRIVE",1);      ExitCLIPS(5);     }   /*===================================================*/   /* 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 == CLIPS_FALSE) &&             (join->joinFromTheRight == CLIPS_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 = CLIPS_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 = CLIPS_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 = CLIPS_TRUE;            SetEvaluationError(CLIPS_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 != CLIPS_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 == CLIPS_FALSE) &&             (join->joinFromTheRight == CLIPS_FALSE))

⌨️ 快捷键说明

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