📄 reorder.c
字号:
currentDepth = theLHS->endNandDepth; theLHS = theLHS->bottom; } } /*************************************************************//* AddNandPatterns: Adds patterns to the beginning of a nand *//* CE group when a referenced variable falls is detected *//* outside the prior enclosing group. *//*************************************************************/static intBool AddNandPatterns( void *theEnv, int depth, struct lhsParseNode *parent, struct lhsParseNode *firstPattern, struct lhsParseNode *theLHS, struct variableReference *variables, struct groupReference *groups) { struct lhsParseNode *nandStart, *theField, *newParent, *subField; struct variableReference *startVariables, *tmpVar; intBool addPatterns = FALSE, returnAddPatterns = FALSE; struct groupReference *tmpGroup; int vdepth; nandStart = theLHS; startVariables = variables; newParent = parent; while (theLHS != NULL) { if (theLHS->beginNandDepth > depth) { /*==============================*/ /* Process the next nand group. */ /*==============================*/ tmpGroup = get_struct(theEnv,groupReference); tmpGroup->depth = depth; tmpGroup->theGroup = theLHS; tmpGroup->next = groups; groups = tmpGroup; if (AddNandPatterns(theEnv,depth+1,newParent,firstPattern,theLHS,variables,groups)) { addPatterns = TRUE; } groups = tmpGroup->next; rtn_struct(theEnv,variableReference,tmpGroup); /*===================================================*/ /* Skip to the end of the nand group just processed. */ /*===================================================*/ while (theLHS->endNandDepth > depth) { theLHS = theLHS->bottom; } } else { /*===========================================*/ /* Search the pattern for binding variables. */ /*===========================================*/ if (theLHS->type == PATTERN_CE) { for (theField = theLHS->right; theField != NULL; theField = theField->right) { if (theField->multifieldSlot) { subField = theField->bottom; } else { subField = theField; } while (subField != NULL) { if ((subField->type == SF_VARIABLE) || (subField->type == MF_VARIABLE)) { vdepth = VariableDepth(subField->value,variables); if (vdepth != -1) { if (theLHS->negated) { if ((depth - vdepth) > 0) { addPatterns = TRUE; } } else { if ((depth - vdepth) > 1) { returnAddPatterns = TRUE; } } } tmpVar = get_struct(theEnv,variableReference); tmpVar->depth = depth; tmpVar->name = subField->value; tmpVar->next = variables; variables = tmpVar; } if (theField->multifieldSlot) { subField = subField->right; } else { subField = NULL; } } } } else if (theLHS->type == TEST_CE) { if (AddNandPatternsForTestCE(depth,theLHS->expression,variables)) { returnAddPatterns = TRUE; } } /*=====================================================*/ /* Return if the end of a nand group has been reached. */ /*=====================================================*/ if (theLHS->endNandDepth < depth) { /*===================================================*/ /* Deallocate variables detected in this nand group. */ /*===================================================*/ while (variables != startVariables) { tmpVar = variables->next; rtn_struct(theEnv,variableReference,variables); variables = tmpVar; } if (addPatterns) { InsertNandPatterns(theEnv,parent,firstPattern,nandStart,depth); } return(addPatterns || returnAddPatterns); } } /*=============================================*/ /* Move on the next pattern in the nand group. */ /*=============================================*/ newParent = theLHS; theLHS = theLHS->bottom; } if (addPatterns) { InsertNandPatterns(theEnv,parent,firstPattern,nandStart,depth); } /*===================================================*/ /* Deallocate variables detected in this nand group. */ /*===================================================*/ while (variables != startVariables) { tmpVar = variables->next; rtn_struct(theEnv,variableReference,variables); variables = tmpVar; } return(addPatterns || returnAddPatterns); }/******************************//* AddNandPatternsForTestCE: *//******************************/static intBool AddNandPatternsForTestCE( int depth, struct lhsParseNode *testCE, struct variableReference *variables) { int vdepth; while (testCE != NULL) { if ((testCE->type == SF_VARIABLE) || (testCE->type == MF_VARIABLE)) { vdepth = VariableDepth(testCE->value,variables); if (vdepth != -1) { if ((depth - vdepth) > 1) { return(TRUE); } } } if ((testCE->bottom != NULL) && (AddNandPatternsForTestCE(depth,testCE->bottom,variables))) { return(TRUE); } testCE = testCE->right; } return(FALSE); } /*************************************************************//* InsertNandPatterns: *//*************************************************************/static void InsertNandPatterns( void *theEnv, struct lhsParseNode *parent, struct lhsParseNode *firstPattern, struct lhsParseNode *endPattern, int depth) { struct lhsParseNode *theLHS, *newNode, *first = NULL, *last = NULL; struct lhsParseNode *theFinalGroup = NULL; int lastEnd = 1; intBool insideFinalGroup = FALSE; int minDepth, maxDepth; if (parent == NULL) return; /*=========================================================================*/ /* Determine the highest level not/and group to which the pattern belongs. */ /*=========================================================================*/ for (theLHS = firstPattern; theLHS != endPattern; theLHS = theLHS->bottom) { if ((lastEnd == 1) && (theLHS->beginNandDepth > 1)) { theFinalGroup = theLHS; } lastEnd = theLHS->endNandDepth; } if (lastEnd == 1) { theFinalGroup = endPattern; } minDepth = theFinalGroup->endNandDepth; maxDepth = theFinalGroup->beginNandDepth; for (theLHS = theFinalGroup; theLHS != endPattern; theLHS = theLHS->bottom) { if (theLHS->endNandDepth < minDepth) { minDepth = theLHS->endNandDepth; } if (theLHS->beginNandDepth > maxDepth) { maxDepth = theLHS->beginNandDepth; } } /* TBD Add code here to determine the block start. */ for (theLHS = firstPattern; theLHS != endPattern; theLHS = theLHS->bottom) { if (theLHS == theFinalGroup) { insideFinalGroup = TRUE; } newNode = GetLHSParseNode(theEnv); CopyLHSParseNode(theEnv,newNode,theLHS,TRUE); newNode->right = CopyLHSParseNodes(theEnv,theLHS->right); newNode->value = NULL; if (insideFinalGroup) { newNode->beginNandDepth = depth + (theLHS->beginNandDepth - minDepth); newNode->endNandDepth = depth + (theLHS->endNandDepth - minDepth); } else { newNode->beginNandDepth = depth + (theLHS->beginNandDepth - firstPattern->beginNandDepth); newNode->endNandDepth = depth + (theLHS->endNandDepth - firstPattern->beginNandDepth); } if (first == NULL) { first = newNode; } else { last->bottom = newNode; } last = newNode; } first->existsNand = endPattern->existsNand; endPattern->existsNand = FALSE; parent->bottom = first; last->bottom = endPattern; }/**************************************************************//* VariableDepth: Returns the most recent depth of a variable *//* or -1 if the variable has not yet been bound. *//**************************************************************/static int VariableDepth( void *theName, struct variableReference *variables) { while (variables != NULL) { if (variables->name == theName) { return(variables->depth); } variables = variables->next; } return -1; }/****************************************************************//* AddInitialPatterns: Add initial patterns to CEs where needed *//* (such as before a "test" CE or "not" CE which is the first *//* CE within an "and" CE). *//****************************************************************/globle void AddInitialPatterns( void *theEnv, struct lhsParseNode *theLHS) { struct lhsParseNode *thePattern; /*====================================================*/ /* If there are multiple disjuncts for the rule, then */ /* add initial patterns to each disjunct separately. */ /*====================================================*/ if (theLHS->type == OR_CE) { for (thePattern = theLHS->right; thePattern != NULL; thePattern = thePattern->bottom) { AddInitialPatterns(theEnv,thePattern); } return; } /*================================*/ /* Handle the remaining patterns. */ /*================================*/ theLHS->right = AddRemainingInitialPatterns(theEnv,theLHS->right); }/***********************************************************//* PerformReorder1: Reorders a group of CEs to accommodate *//* KB Rete topology. The first pass of this function *//* transforms or CEs into equivalent forms. *//***********************************************************/static struct lhsParseNode *PerformReorder1( void *theEnv, struct lhsParseNode *theLHS, int *newChange) { struct lhsParseNode *argPtr, *lastArg, *nextArg; struct lhsParseNode *tempArg, *newNode; int count; int change; /*======================================================*/ /* Loop through the CEs as long as changes can be made. */ /*======================================================*/ change = TRUE; *newChange = FALSE; while (change) { change = FALSE; count = 1; lastArg = NULL; for (argPtr = theLHS->right; argPtr != NULL;) { /*=============================================================*/ /* Convert and/or CE combinations into or/and CE combinations. */ /*=============================================================*/ if ((theLHS->type == AND_CE) && (argPtr->type == OR_CE)) { theLHS = ReverseAndOr(theEnv,theLHS,argPtr->right,count); change = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -