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

📄 factmch.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.05  04/09/97            */   /*                                                     */   /*                 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:                                         *//*                                                           *//*************************************************************/#define _FACTMCH_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT#include "clipsmem.h"#include "extnfunc.h"#include "router.h"#if INCREMENTAL_RESET#include "incrrset.h"#endif#include "reteutil.h"#include "drive.h"#include "factgen.h"#include "factrete.h"#include "tmpltdef.h"#include "factmch.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER   static BOOLEAN                  EvaluatePatternExpression(struct factPatternNode *,struct expr *,int);   static VOID                     TraceErrorToJoin(struct factPatternNode *,int);   static VOID                     ProcessFactAlphaMatch(struct fact *,struct multifieldMarker *,struct factPatternNode *);   static struct factPatternNode  *GetNextFactPatternNode(int,struct factPatternNode *);   static int                      SkipFactPatternNode(struct factPatternNode *);   static VOID                     ProcessMultifieldNode(struct factPatternNode *,                                                         struct multifieldMarker *,                                                         struct multifieldMarker *,int);   static VOID                     PatternNetErrorMessage(struct factPatternNode *);#else   static BOOLEAN                  EvaluatePatternExpression();   static VOID                     TraceErrorToJoin();   static VOID                     ProcessFactAlphaMatch();   static struct factPatternNode  *GetNextFactPatternNode();   static int                      SkipFactPatternNode();   static VOID                     ProcessMultifieldNode();   static VOID                     PatternNetErrorMessage();#endif/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/   globle struct fact             *CurrentPatternFact;   globle struct multifieldMarker *CurrentPatternMarks;/*************************************************************************//* FactPatternMatch: Implements the core loop for fact pattern matching. *//*************************************************************************/globle VOID FactPatternMatch(theFact,patternPtr,offset,markers,endMark)  struct fact *theFact;  struct factPatternNode *patternPtr;  int offset;  struct multifieldMarker *markers, *endMark;  {   int theSlotField;   int offsetSlot;   /*=========================================================*/   /* 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. */   /*================================================*/   CurrentPatternFact = theFact;   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(patternPtr))        { patternPtr = GetNextFactPatternNode(CLIPS_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 = CLIPS_FALSE;         if (patternPtr->header.endSlot &&              ((CurrentPatternMarks == NULL) ?               CLIPS_FALSE :              (CurrentPatternMarks->where.whichSlotNumber == patternPtr->whichSlot)) &&             (CurrentPatternFact->theProposition.theFields                  [patternPtr->whichSlot].type == MULTIFIELD))           {            if ((patternPtr->leaveFields + theSlotField) !=                ((struct multifield *) CurrentPatternFact->theProposition.theFields                                      [patternPtr->whichSlot].value)->multifieldLength)              { skipit = CLIPS_TRUE; }           }                  if (skipit)           { patternPtr = GetNextFactPatternNode(CLIPS_TRUE,patternPtr); }         else                         /*=============================================*/         /* If the constraints are satisified, then ... */         /*=============================================*/                  if (EvaluatePatternExpression(patternPtr,                                       patternPtr->networkTest,                                       theSlotField))           {            /*=======================================================*/            /* 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(theFact,markers,patternPtr); }                          /*===================================*/            /* Move on to the next pattern node. */            /*===================================*/                        patternPtr = GetNextFactPatternNode(CLIPS_FALSE,patternPtr);           }                    /*==============================================*/         /* Otherwise, move on to the next pattern node. */         /*==============================================*/                  else           { patternPtr = GetNextFactPatternNode(CLIPS_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(patternPtr,markers,endMark,offset); }         else           { ProcessMultifieldNode(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(CLIPS_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(thePattern,markers,endMark,offset)  struct factPatternNode *thePattern;  struct multifieldMarker *markers, *endMark;  int offset;  {   struct multifieldMarker *newMark, *oldMark;   int repeatCount;   struct multifield *theSlotValue;        /*========================================*/   /* Get a pointer to the slot value of the */   /* multifield slot being pattern matched. */   /*========================================*/           

⌨️ 快捷键说明

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