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

📄 analysis.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
      theVariable = (struct symbolHashNode *) thePattern->value;      if (thePattern->derivedConstraints) RemoveConstraint(thePattern->constraints);      theConstraints = GetConstraintRecord();      thePattern->constraints = theConstraints;      thePattern->constraints->anyAllowed = CLIPS_FALSE;      thePattern->constraints->instanceAddressesAllowed = CLIPS_TRUE;      thePattern->constraints->factAddressesAllowed = CLIPS_TRUE;      thePattern->derivedConstraints = CLIPS_TRUE;     }      /*===================================================*/   /* Otherwise a pattern variable is being propagated. */   /*===================================================*/   else      {      theType = thePattern->type;      theVariable = (struct symbolHashNode *) thePattern->value;     }          /*===================================================*/   /* Propagate the variable location to any additional */   /* fields associated with the binding variable.      */   /*===================================================*/      if (thePattern->type != PATTERN_CE)     {      PropagateVariableToNodes(thePattern->bottom,theType,theVariable,                               thePattern,patternHead->beginNandDepth,                               CLIPS_TRUE,CLIPS_FALSE);                                       if (ProcessField(thePattern,multifieldHeader,patternHead))        { return(CLIPS_TRUE); }     }      /*=================================================================*/   /* Propagate the constraints to other fields, slots, and patterns. */   /*=================================================================*/      return(PropagateVariableDriver(patternHead,thePattern,multifieldHeader,theType,                                  theVariable,thePattern,CLIPS_TRUE));  }  /*******************************************//* PropagateVariableDriver: Driver routine *//*   for propagating variable references.  *//*******************************************/static int PropagateVariableDriver(patternHead,theNode,multifieldHeader,                                   theType,variableName,theReference,assignReference)  struct lhsParseNode *patternHead, *theNode, *multifieldHeader;  int theType;  struct symbolHashNode *variableName;  struct lhsParseNode *theReference;  int assignReference;  {   /*===================================================*/   /* Propagate the variable location to any additional */   /* constraints associated with the binding variable. */   /*===================================================*/      if (multifieldHeader != NULL)     {      if (PropagateVariableToNodes(multifieldHeader->right,theType,variableName,                                   theReference,patternHead->beginNandDepth,assignReference,CLIPS_FALSE))        {         VariableMixingErrorMessage(variableName);         return(CLIPS_TRUE);        }     }                /*========================================================*/   /* Propagate the variable location to fields/slots in the */   /* same pattern which appear after the binding variable.  */   /*========================================================*/      if (PropagateVariableToNodes(theNode->right,theType,variableName,theReference,                                patternHead->beginNandDepth,assignReference,CLIPS_FALSE))     {      VariableMixingErrorMessage(variableName);      return(CLIPS_TRUE);     }      /*======================================================*/   /* Propagate values to other patterns if the pattern in */   /* which the variable is found is not a "not" CE or the */   /* last pattern within a nand CE.                       */   /*======================================================*/      if (((patternHead->type == PATTERN_CE) || (patternHead->type == TEST_CE)) &&        (patternHead->negated == CLIPS_FALSE) &&       (patternHead->beginNandDepth <= patternHead->endNandDepth))     {      int ignoreVariableMixing;            /*============================================================*/      /* If the variables are propagated from a test CE, then don't */      /* check for mixing of single and multifield variables (since */      /* previously bound multifield variables typically have the $ */      /* removed when passed as an argument to a function unless    */      /* sequence expansion is desired).                            */      /*============================================================*/            if (patternHead->type == TEST_CE) ignoreVariableMixing = CLIPS_TRUE;      else ignoreVariableMixing = CLIPS_FALSE;            /*==========================*/      /* Propagate the reference. */      /*==========================*/            if (PropagateVariableToNodes(patternHead->bottom,theType,variableName,theReference,                                   patternHead->beginNandDepth,assignReference,                                   ignoreVariableMixing))       {         VariableMixingErrorMessage(variableName);         return(CLIPS_TRUE);        }     }        /*==============================================*/   /* Return FALSE to indicate that no errors were */   /* generated by the variable propagation.       */   /*==============================================*/      return(CLIPS_FALSE);  }   /********************************************************//* ProcessField: Processes a field or slot of a pattern *//*   which does not contain a binding variable.         *//********************************************************/static int ProcessField(thePattern,multifieldHeader,patternHead)  struct lhsParseNode *thePattern, *multifieldHeader, *patternHead;  {   struct lhsParseNode *theList, *tempList;      /*====================================================*/   /* Nothing needs to be done for the node representing */   /* the entire pattern. Return FALSE to indicate that  */   /* no errors were generated.                          */   /*====================================================*/         if (thePattern->type == PATTERN_CE) return(CLIPS_FALSE);   /*====================================================================*/   /* Derive a set of constraints based on values found in the slot or   */   /* field. For example, if a slot can only contain the values 1, 2, or */   /* 3, the field constraint ~2 would generate a constraint record that */   /* only allows the value 1 or 3. Once generated, the constraints are  */   /* propagated to other slots and fields.                              */   /*====================================================================*/      theList = DeriveVariableConstraints(thePattern);   for (tempList = theList; tempList != NULL; tempList = tempList->right)     {      if (PropagateVariableDriver(patternHead,thePattern,multifieldHeader,tempList->type,                                  tempList->value,tempList,CLIPS_FALSE))        {          ReturnLHSParseNodes(theList);         return(CLIPS_TRUE);        }     }   ReturnLHSParseNodes(theList);   /*===========================================================*/   /* Check for "variable referenced, but not previously bound" */   /* errors. Return TRUE if this type of error is detected.    */   /*===========================================================*/             if (UnboundVariablesInPattern(thePattern,(int) patternHead->whichCE))     { return(CLIPS_TRUE); }            /*==================================================*/   /* Check for constraint errors for this slot/field. */   /* If the slot/field has unmatchable constraints    */   /* then return TRUE to indicate a semantic error.   */   /*==================================================*/       if (ProcessConnectedConstraints(thePattern,multifieldHeader,patternHead))     { return(CLIPS_TRUE); }   /*==============================================================*/   /* Convert the slot/field constraint to a series of expressions */   /* that will be used in the pattern and join networks.          */   /*==============================================================*/      FieldConversion(thePattern,patternHead);       /*=========================================================*/   /* Return FALSE to indicate that no errors were generated. */   /*=========================================================*/      return(CLIPS_FALSE);  }  /*************************************************************//* PropagateVariableToNodes: Propagates variable references  *//*  to all other variables within the semantic scope of the  *//*  bound variable. That is, a variable reference cannot be  *//*  beyond an enclosing not/and CE combination. The          *//*  restriction of propagating variables beyond an enclosing *//*  not CE is handled within the GetVariables function.      *//*************************************************************/static int PropagateVariableToNodes(theNode,theType,variableName,                                    theReference,startDepth,                                    assignReference,ignoreVariableTypes)  struct lhsParseNode *theNode;  int theType;  struct symbolHashNode *variableName;  struct lhsParseNode *theReference;  int startDepth;  int assignReference;  int ignoreVariableTypes;  {   struct constraintRecord *tempConstraints;      /*===========================================*/   /* Traverse the nodes using the bottom link. */   /*===========================================*/      while (theNode != NULL)     {      /*==================================================*/      /* If the field/slot contains a predicate or return */      /* value constraint, then propagate the variable to */      /* the expression associated with that constraint.  */      /*==================================================*/            if (theNode->expression != NULL)        {          PropagateVariableToNodes(theNode->expression,theType,variableName,                                  theReference,startDepth,assignReference,CLIPS_TRUE);        }              /*======================================================*/      /* If the field/slot is a single or multifield variable */      /* with the same name as the propagated variable,       */      /* then propagate the variable location to this node.   */      /*======================================================*/            else if (((theNode->type == SF_VARIABLE) || (theNode->type == MF_VARIABLE)) &&               (theNode->value == (VOID *) variableName))        {         /*======================================================*/         /* Check for mixing of single and multifield variables. */         /*======================================================*/                  if (ignoreVariableTypes == CLIPS_FALSE)           {            if (((theType == SF_VARIABLE) && (theNode->type == MF_VARIABLE)) ||                ((theType == MF_VARIABLE) && (theNode->type == SF_VARIABLE)))              { return(CLIPS_TRUE); }           }                           /*======================================================*/         /* Intersect the propagated variable's constraints with */         /* the current constraints for this field/slot.         */         /*======================================================*/                  if ((theReference->constraints != NULL) && (! theNode->negated))           {            tempConstraints = theNode->constraints;            theNode->constraints = IntersectConstraints(theReference->constraints,                                                        tempConstraints);            if (theNode->derivedConstraints)              { RemoveConstraint(tempConstraints); }                         theNode->derivedConstraints = CLIPS_TRUE;           }                              /*=====================================================*/         /* Don't propagate the variable if it originates from  */         /* a different type of pattern object and the variable */         /* reference has already been resolved.                */         /*=====================================================*/                  if (assignReference)           {            if (theNode->referringNode == NULL)               { theNode->referringNode = theReference; }            else if (theReference->pattern == theNode->pattern)              { theNode->referringNode = theReference; }            else if (theReference->patternType == theNode->patternType)              { theNode->referringNode = theReference; }           }        }              /*========================================================*/      /* If the field/slot is the node representing the entire  */      /* pattern, then propagate the variable location to the   */      /* fact address associated with the pattern (if it is the */      /* same variable name).                                   */      /*========================================================*/            else if ((theNode->type == PATTERN_CE) &&                (theNode->value == (VOID *) variableName) &&               (assignReference == CLIPS_TRUE))        {         if (theType == MF_VARIABLE) return(CLIPS_TRUE);                  theNode->referringNode = theReference;        }              /*=====================================================*/      /* Propagate the variable to other fields contained    */      /* within the same & field constraint or same pattern. */      /*=====================================================*/             if (theNode->right != NULL)         {         if (PropagateVariableToNodes(theNode->right,theType,variableName,                                      theReference,startDepth,assignReference,ignoreVariableTypes))           { return(CLIPS_TRUE); }        }                                        /*============================================================*/      /* Propagate the variable to other patterns within the same   */      /* semantic scope (if dealing with the node for an entire     */      /* pattern) or to the next | field constraint within a field. */      /*============================================================*/            if ((theNode->type == PATTERN_CE) || (theNode->type == TEST_CE))        {          if (theNode->endNandDepth < startDepth) theNode = NULL;         else theNode = theNode->bottom;        }      else

⌨️ 快捷键说明

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