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

📄 factmch.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.30  10/19/06            */   /*                                                     */   /*                 FACT MATCH MODULE                   */   /*******************************************************//*************************************************************//* Purpose: Implements the algorithm for pattern matching in *//*   the fact pattern network.                               *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  *//*                                                           *//*      6.24: Removed INCREMENTAL_RESET compilation flag.    *//*                                                           *//*            Renamed BOOLEAN macro type to intBool.         *//*                                                           *//*      6.30: Added support for hashed alpha memories.       *//*                                                           *//*************************************************************/#define _FACTMCH_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include "setup.h"#if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT#include "drive.h"#include "engine.h"#include "envrnmnt.h"#include "extnfunc.h"#include "factgen.h"#include "factrete.h"#include "incrrset.h"#include "memalloc.h"#include "reteutil.h"#include "router.h"#include "sysdep.h"#include "tmpltdef.h"#include "factmch.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static intBool                  EvaluatePatternExpression(void *,struct factPatternNode *,struct expr *);   static void                     TraceErrorToJoin(void *,struct factPatternNode *,int);   static void                     ProcessFactAlphaMatch(void *,struct fact *,struct multifieldMarker *,struct factPatternNode *);   static struct factPatternNode  *GetNextFactPatternNode(void *,int,struct factPatternNode *);   static int                      SkipFactPatternNode(void *,struct factPatternNode *);   static void                     ProcessMultifieldNode(void *,                                                         struct factPatternNode *,                                                         struct multifieldMarker *,                                                         struct multifieldMarker *,int);   static void                     PatternNetErrorMessage(void *,struct factPatternNode *);/*************************************************************************//* FactPatternMatch: Implements the core loop for fact pattern matching. *//*************************************************************************/globle void FactPatternMatch(  void *theEnv,  struct fact *theFact,  struct factPatternNode *patternPtr,  int offset,  struct multifieldMarker *markers,  struct multifieldMarker *endMark)  {   int theSlotField;   int offsetSlot;   DATA_OBJECT theResult;   struct factPatternNode *tempPtr;      /*=========================================================*/   /* If there's nothing left in the pattern network to match */   /* against, then the current traversal of the pattern      */   /* network needs to back up.                               */   /*=========================================================*/   if (patternPtr == NULL) return;   /*=======================================================*/   /* The offsetSlot variable indicates the current offset  */   /* within the multifield slot being pattern matched.     */   /* (Recall that a multifield wildcard or variable        */   /* recursively iterates through all possible  bindings.) */   /* Once a new slot starts being pattern matched, the     */   /* offset is reset to zero.                              */   /*=======================================================*/   offsetSlot = patternPtr->whichSlot;   /*================================================*/   /* Set up some global parameters for use by the   */   /* Rete access functions and general convenience. */   /*================================================*/   FactData(theEnv)->CurrentPatternFact = theFact;   FactData(theEnv)->CurrentPatternMarks = markers;   /*============================================*/   /* Loop through each node in pattern network. */   /*============================================*/   while (patternPtr != NULL)     {      /*=============================================================*/      /* Determine the position of the field we're going to pattern  */      /* match. If this routine has been entered recursively because */      /* of multifield wildcards or variables, then add in the       */      /* additional offset caused by the values which match these    */      /* multifields. This offset may be negative (if for example a  */      /* a multifield matched a zero length value).                  */      /*=============================================================*/      theSlotField = patternPtr->whichField;      if (offsetSlot == patternPtr->whichSlot)        { theSlotField += offset; }      /*===================================*/      /* Determine if we want to skip this */      /* node during an incremental reset. */      /*===================================*/      if (SkipFactPatternNode(theEnv,patternPtr))        { patternPtr = GetNextFactPatternNode(theEnv,TRUE,patternPtr); }      /*=========================================================*/      /* If this is a single field pattern node, then determine  */      /* if the constraints for the node have been satisfied for */      /* the current field in the slot being examined.           */      /*=========================================================*/      else if (patternPtr->header.singlefieldNode)        {         /*==================================================*/         /* If we're at the last slot in the pattern, make   */         /* sure the number of fields in the fact correspond */         /* to the number of fields required by the pattern  */         /* based on the binding of multifield variables.    */         /*==================================================*/         int skipit = FALSE;         if (patternPtr->header.endSlot &&             ((FactData(theEnv)->CurrentPatternMarks == NULL) ?              FALSE :              (FactData(theEnv)->CurrentPatternMarks->where.whichSlotNumber == patternPtr->whichSlot)) &&             (FactData(theEnv)->CurrentPatternFact->theProposition.theFields                  [patternPtr->whichSlot].type == MULTIFIELD))           {            if ((patternPtr->leaveFields + theSlotField) != (int)               ((struct multifield *) FactData(theEnv)->CurrentPatternFact->theProposition.theFields                                      [patternPtr->whichSlot].value)->multifieldLength)              { skipit = TRUE; }           }         if (skipit)           { patternPtr = GetNextFactPatternNode(theEnv,TRUE,patternPtr); }         else         if (patternPtr->header.selector)           {            if (EvaluatePatternExpression(theEnv,patternPtr,patternPtr->networkTest->nextArg))              {               EvaluateExpression(theEnv,patternPtr->networkTest,&theResult);                           tempPtr = FindHashedPatternNode(theEnv,patternPtr,theResult.type,theResult.value);              }            else              { tempPtr = NULL; }                          if (tempPtr != NULL)              {               if (tempPtr->header.stopNode)                 { ProcessFactAlphaMatch(theEnv,theFact,markers,tempPtr); }                              patternPtr = GetNextFactPatternNode(theEnv,FALSE,tempPtr);              }            else              { patternPtr = GetNextFactPatternNode(theEnv,TRUE,patternPtr); }           }                  /*=============================================*/         /* If the constraints are satisified, then ... */         /*=============================================*/         else if (EvaluatePatternExpression(theEnv,patternPtr,patternPtr->networkTest))           {            /*=======================================================*/            /* If a leaf pattern node has been successfully reached, */            /* then the pattern has been satisified. Generate an     */            /* alpha match to store in the pattern node.             */            /*=======================================================*/            if (patternPtr->header.stopNode)              { ProcessFactAlphaMatch(theEnv,theFact,markers,patternPtr); }            /*===================================*/            /* Move on to the next pattern node. */            /*===================================*/            patternPtr = GetNextFactPatternNode(theEnv,FALSE,patternPtr);           }         /*==============================================*/         /* Otherwise, move on to the next pattern node. */         /*==============================================*/         else           { patternPtr = GetNextFactPatternNode(theEnv,TRUE,patternPtr); }        }      /*======================================================*/      /* If this is a multifield pattern node, then determine */      /* if the constraints for the node have been satisfied  */      /* for the current field in the slot being examined.    */      /*======================================================*/      else if (patternPtr->header.multifieldNode)        {         /*========================================================*/         /* Determine if the multifield pattern node's constraints */         /* are satisfied. If we've traversed to a different slot  */         /* than the one we started this routine with, then the    */         /* offset into the slot is reset to zero.                 */         /*========================================================*/         if (offsetSlot == patternPtr->whichSlot)           { ProcessMultifieldNode(theEnv,patternPtr,markers,endMark,offset); }         else           { ProcessMultifieldNode(theEnv,patternPtr,markers,endMark,0); }         /*===================================================*/         /* Move on to the next pattern node. Since the lower */         /* branches of the pattern network have already been */         /* recursively processed by ProcessMultifieldNode,   */         /* we get the next pattern node by treating this     */         /* multifield pattern node as if it were a single    */         /* field pattern node that failed its constraint.    */         /*===================================================*/         patternPtr = GetNextFactPatternNode(theEnv,TRUE,patternPtr);        }     }  }/**************************************************************//* ProcessMultifieldNode: Handles recursive pattern matching  *//*  when a multifield wildcard or variable is encountered as  *//*  a slot constraint. The pattern matching routine is called *//*  iteratively for each possible binding of the multifield   *//*  wildcard or variable.                                     *//**************************************************************/static void ProcessMultifieldNode(  void *theEnv,  struct factPatternNode *thePattern,  struct multifieldMarker *markers,  struct multifieldMarker *endMark,  int offset)  {   struct multifieldMarker *newMark, *oldMark;   int repeatCount;   struct multifield *theSlotValue;   DATA_OBJECT theResult;   struct factPatternNode *tempPtr;   intBool success;   /*========================================*/   /* Get a pointer to the slot value of the */   /* multifield slot being pattern matched. */   /*========================================*/   theSlotValue = (struct multifield *)     FactData(theEnv)->CurrentPatternFact->theProposition.theFields[thePattern->whichSlot].value;   /*===============================================*/   /* Save the value of the markers already stored. */   /*===============================================*/

⌨️ 快捷键说明

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