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

📄 drive.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.30  10/19/06            */   /*                                                     */   /*                    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:                                         *//*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  *//*                                                           *//*      6.24: Removed INCREMENTAL_RESET and                  *//*            LOGICAL_DEPENDENCIES compilation flags.        *//*                                                           *//*            Renamed BOOLEAN macro type to intBool.         *//*                                                           *//*            Rule with exists CE has incorrect activation.  *//*            DR0867                                         *//*                                                           *//*      6.30: Added support for hashed alpha memories.       *//*                                                           *//*            Added additional developer statistics to help  *//*            analyze join network performance.              *//*                                                           *//*            Removed pseudo-facts used in not CE.           *//*                                                           *//*************************************************************/#define _DRIVE_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include <stdlib.h>#include "setup.h"#if DEFRULE_CONSTRUCT#include "agenda.h"#include "constant.h"#include "engine.h"#include "envrnmnt.h"#include "memalloc.h"#include "prntutil.h"#include "reteutil.h"#include "retract.h"#include "router.h"#include "lgcldpnd.h"#include "incrrset.h"#include "drive.h"    /***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static void                    EmptyDrive(void *,struct joinNode *,struct partialMatch *);   static void                    JoinNetErrorMessage(void *,struct joinNode *);   /************************************************//* NetworkAssert: Primary routine for filtering *//*   a partial match through the join network.  *//************************************************/globle void NetworkAssert(  void *theEnv,  struct partialMatch *binds,  struct joinNode *join)  {   /*=========================================================*/   /* If an incremental reset is being performed and the join */   /* is not part of the network to be reset, then return.    */   /*=========================================================*/#if (! BLOAD_ONLY) && (! RUN_TIME)   if (EngineData(theEnv)->IncrementalResetInProgress && (join->initialize == FALSE)) return;#endif   /*==================================================*/   /* Use a special routine if this is the first join. */   /*==================================================*/   if (join->firstJoin)     {      EmptyDrive(theEnv,join,binds);      return;     }   /*================================*/   /* Enter the join from the right. */   /*================================*/   NetworkAssertRight(theEnv,binds,join);   return;  }/*****************************************************//* NetworkAssertRight: Primary routine for filtering *//*   a partial match through the join network from   *//*   the RHS of a join.                              *//*****************************************************/globle void NetworkAssertRight(  void *theEnv,  struct partialMatch *rhsBinds,  struct joinNode *join)  {   struct partialMatch *lhsBinds, *nextBind;   int exprResult, restore = FALSE;   struct partialMatch *oldLHSBinds = NULL;   struct partialMatch *oldRHSBinds = NULL;   struct joinNode *oldJoin = NULL;   /*=========================================================*/   /* If an incremental reset is being performed and the join */   /* is not part of the network to be reset, then return.    */   /*=========================================================*/#if (! BLOAD_ONLY) && (! RUN_TIME)   if (EngineData(theEnv)->IncrementalResetInProgress && (join->initialize == FALSE)) return;#endif   if (join->firstJoin)     {      EmptyDrive(theEnv,join,rhsBinds);      return;     }     /*=====================================================*/   /* The partial matches entering from the LHS of a join */   /* are stored in the left beta memory of the join.     */   /*=====================================================*/   lhsBinds = GetLeftBetaMemory(join,rhsBinds->hashValue);#if DEVELOPER   if (lhsBinds != NULL)     { EngineData(theEnv)->rightToLeftLoops++; }#endif   /*====================================*/   /* Set up the evaluation environment. */   /*====================================*/      if (lhsBinds != NULL)     {      oldLHSBinds = EngineData(theEnv)->GlobalLHSBinds;      oldRHSBinds = EngineData(theEnv)->GlobalRHSBinds;      oldJoin = EngineData(theEnv)->GlobalJoin;      EngineData(theEnv)->GlobalRHSBinds = rhsBinds;      EngineData(theEnv)->GlobalJoin = join;      restore = TRUE;     }       /*===================================================*/   /* 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 (lhsBinds != NULL)     {      nextBind = lhsBinds->nextInMemory;      join->memoryCompares++;            /*===========================================================*/      /* Initialize some variables pointing to the partial matches */      /* in the LHS and RHS of the join.                           */      /*===========================================================*/      if (lhsBinds->hashValue != rhsBinds->hashValue)        {#if DEVELOPER         if (join->leftMemory->size == 1)           { EngineData(theEnv)->betaHashListSkips++; }         else           { EngineData(theEnv)->betaHashHTSkips++; }                    if (lhsBinds->marker != NULL)           { EngineData(theEnv)->unneededMarkerCompare++; }#endif         lhsBinds = nextBind;         continue;        }              /*===============================================================*/      /* If there already is an associated RHS partial match stored in */      /* the LHS partial match from the beta memory of this join, then */      /* the exists/nand CE has already been satisfied and we can move */      /* on to the next partial match found in the beta memory.        */      /*===============================================================*/              if (lhsBinds->marker != NULL)        { #if DEVELOPER         EngineData(theEnv)->unneededMarkerCompare++;#endif         lhsBinds = nextBind;         continue;        }      /*===================================================*/      /* If the join has no expression associated with it, */      /* then the new partial match derived from the LHS   */      /* and RHS partial matches is valid.                 */      /*===================================================*/      if (join->networkTest == NULL)        { exprResult = TRUE; }      /*=========================================================*/      /* 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        {#if DEVELOPER         EngineData(theEnv)->rightToLeftComparisons++;#endif         EngineData(theEnv)->GlobalLHSBinds = lhsBinds;         exprResult = EvaluateJoinExpression(theEnv,join->networkTest,join);         if (EvaluationData(theEnv)->EvaluationError)           {            if (join->patternIsNegated) exprResult = TRUE;            SetEvaluationError(theEnv,FALSE);           }#if DEVELOPER         if (exprResult)           { EngineData(theEnv)->rightToLeftSucceeds++; }#endif        }      if ((join->secondaryNetworkTest != NULL) && exprResult)        {         /* EngineData(theEnv)->GlobalRHSBinds = NULL; */                  exprResult = EvaluateJoinExpression(theEnv,join->secondaryNetworkTest,join);         if (EvaluationData(theEnv)->EvaluationError)           { SetEvaluationError(theEnv,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 != FALSE)        {         if (join->patternIsExists)           {            AddBlockedLink(lhsBinds,rhsBinds);            PPDrive(theEnv,lhsBinds,NULL,join);           }         else if (join->patternIsNegated || join->joinFromTheRight)           {            AddBlockedLink(lhsBinds,rhsBinds);            if (lhsBinds->children != NULL)              { PosEntryRetractBeta(theEnv,lhsBinds,lhsBinds->children); }            if (lhsBinds->dependents != NULL)               { RemoveLogicalSupport(theEnv,lhsBinds); }           }          else           { PPDrive(theEnv,lhsBinds,rhsBinds,join); }        }      /*====================================*/      /* Move on to the next partial match. */      /*====================================*/      lhsBinds = nextBind;     }   /*=========================================*/   /* Restore the old evaluation environment. */   /*=========================================*/   if (restore)     {      EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;      EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;      EngineData(theEnv)->GlobalJoin = oldJoin;     }        return;  }/****************************************************//* NetworkAssertLeft: Primary routine for filtering *//*   a partial match through the join network when  *//*   entering through the left side of a join.      *//****************************************************/globle void NetworkAssertLeft(  void *theEnv,  struct partialMatch *lhsBinds,  struct joinNode *join)  {   struct partialMatch *rhsBinds;   int exprResult, restore = FALSE;   unsigned long entryHashValue;   struct partialMatch *oldLHSBinds = NULL;   struct partialMatch *oldRHSBinds = NULL;   struct joinNode *oldJoin = NULL;   /*=========================================================*/   /* If an incremental reset is being performed and the join */   /* is not part of the network to be reset, then return.    */   /*=========================================================*/#if (! BLOAD_ONLY) && (! RUN_TIME)   if (EngineData(theEnv)->IncrementalResetInProgress && (join->initialize == FALSE)) return;#endif   /*===================================*/   /* The only action for the last join */   /* of a rule is to activate it.      */   /*===================================*/      if (join->ruleToActivate != NULL)     {      AddActivation(theEnv,join->ruleToActivate,lhsBinds);      return;     }   /*==================================================*/   /* Initialize some variables used to indicate which */   /* side is being compared to the new partial match. */   /*==================================================*/   entryHashValue = lhsBinds->hashValue;   if (join->joinFromTheRight)     { rhsBinds = GetRightBetaMemory(join,entryHashValue); }   else     { rhsBinds = GetAlphaMemory(theEnv,(struct patternNodeHeader *) join->rightSideEntryStructure,entryHashValue); }       #if DEVELOPER   if (rhsBinds != NULL)     { EngineData(theEnv)->leftToRightLoops++; }#endif      /*====================================*/   /* Set up the evaluation environment. */   /*====================================*/      if ((rhsBinds != NULL) || (join->secondaryNetworkTest != NULL))     {      oldLHSBinds = EngineData(theEnv)->GlobalLHSBinds;      oldRHSBinds = EngineData(theEnv)->GlobalRHSBinds;

⌨️ 快捷键说明

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