📄 reorder.c
字号:
while (change) { change = CLIPS_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(theLHS,argPtr->right,count); change = CLIPS_TRUE; *newChange = CLIPS_TRUE; break; } /*==============================================================*/ /* Convert not/or CE combinations into and/not CE combinations. */ /*==============================================================*/ else if ((theLHS->type == NOT_CE) && (argPtr->type == OR_CE)) { change = CLIPS_TRUE; *newChange = CLIPS_TRUE; tempArg = argPtr->right; argPtr->right = NULL; argPtr->bottom = NULL; ReturnLHSParseNodes(argPtr); theLHS->type = AND_CE; theLHS->right = tempArg; while (tempArg != NULL) { newNode = GetLHSParseNode(); CopyLHSParseNode(newNode,tempArg,CLIPS_FALSE); newNode->right = tempArg->right; newNode->bottom = NULL; tempArg->type = NOT_CE; tempArg->negated = CLIPS_FALSE; tempArg->logical = CLIPS_FALSE; tempArg->value = NULL; tempArg->expression = NULL; tempArg->right = newNode; tempArg = tempArg->bottom; } break; } /*=====================================*/ /* Remove duplication of or CEs within */ /* or CEs and and CEs within and CEs. */ /*=====================================*/ else if (((theLHS->type == OR_CE) && (argPtr->type == OR_CE)) || ((theLHS->type == AND_CE) && (argPtr->type == AND_CE))) { if (argPtr->logical) theLHS->logical = CLIPS_TRUE; change = CLIPS_TRUE; *newChange = CLIPS_TRUE; tempArg = argPtr->right; nextArg = argPtr->bottom; argPtr->right = NULL; argPtr->bottom = NULL; ReturnLHSParseNodes(argPtr); if (lastArg == NULL) { theLHS->right = tempArg; } else { lastArg->bottom = tempArg; } argPtr = tempArg; while (tempArg->bottom != NULL) tempArg = tempArg->bottom; tempArg->bottom = nextArg; } /*===================================================*/ /* If no changes are needed, move on to the next CE. */ /*===================================================*/ else { count++; lastArg = argPtr; argPtr = argPtr->bottom; } } } /*===========================*/ /* Return the reordered LHS. */ /*===========================*/ return(theLHS); }/***********************************************************//* PerformReorder2: Reorders a group of CEs to accommodate *//* CLIPS Rete topology. The second pass performs all *//* other transformations not associated with the or CE. *//***********************************************************/static struct lhsParseNode *PerformReorder2(theLHS,newChange) struct lhsParseNode *theLHS; int *newChange; { struct lhsParseNode *argPtr; int change; /*======================================================*/ /* Loop through the CEs as long as changes can be made. */ /*======================================================*/ change = CLIPS_TRUE; *newChange = CLIPS_FALSE; while (change) { change = CLIPS_FALSE; for (argPtr = theLHS->right; argPtr != NULL;) { /*======================================*/ /* Replace not CEs containing a pattern */ /* CE with a negated pattern CE. */ /*======================================*/ if ((theLHS->type == NOT_CE) && (argPtr->type == PATTERN_CE)) { change = CLIPS_TRUE; *newChange = CLIPS_TRUE; CopyLHSParseNode(theLHS,argPtr,CLIPS_FALSE); theLHS->negated = CLIPS_TRUE; theLHS->right = argPtr->right; argPtr->networkTest = NULL; argPtr->expression = NULL; argPtr->userData = NULL; argPtr->right = NULL; argPtr->bottom = NULL; ReturnLHSParseNodes(argPtr); break; } /*============================================================*/ /* Replace "and" and "not" CEs contained within a not CE with */ /* just the and CE, but increment the nand depths of the */ /* pattern contained within. */ /*============================================================*/ else if ((theLHS->type == NOT_CE) && ((argPtr->type == AND_CE) || (argPtr->type == NOT_CE))) { change = CLIPS_TRUE; *newChange = CLIPS_TRUE; theLHS->type = argPtr->type; theLHS->negated = argPtr->negated; theLHS->value = argPtr->value; theLHS->logical = argPtr->logical; theLHS->right = argPtr->right; argPtr->right = NULL; argPtr->bottom = NULL; ReturnLHSParseNodes(argPtr); IncrementNandDepth(theLHS->right,CLIPS_TRUE); break; } /*===================================================*/ /* If no changes are needed, move on to the next CE. */ /*===================================================*/ else { argPtr = argPtr->bottom; } } } /*===========================*/ /* Return the reordered LHS. */ /*===========================*/ return(theLHS); } /**************************************************//* ReverseAndOr: Switches and/or CEs into *//* equivalent or/and CEs. For example: *//* *//* (and (or a b) (or c d)) *//* *//* would be converted to *//* *//* (or (and a (or c d)) (and b (or c d))), *//* *//* if the "or" CE being expanded was (or a b). *//**************************************************/static struct lhsParseNode *ReverseAndOr(listOfCEs,orCE,orPosition) struct lhsParseNode *listOfCEs; struct lhsParseNode *orCE; int orPosition; { int count; struct lhsParseNode *listOfExpandedOrCEs = NULL; struct lhsParseNode *lastExpandedOrCE = NULL; struct lhsParseNode *copyOfCEs, *replaceCE; /*========================================================*/ /* Loop through each of the CEs contained within the "or" */ /* CE that is being expanded into the enclosing "and" CE. */ /*========================================================*/ while (orCE != NULL) { /*===============================*/ /* Make a copy of the and/or CE. */ /*===============================*/ copyOfCEs = CopyLHSParseNodes(listOfCEs); /*====================================================*/ /* Get a pointer to the "or" CE being expanded in the */ /* copy just made based on the position of the "or" */ /* CE in the original and/or CE (e.g., 1st, 2nd). */ /*====================================================*/ for (count = 1, replaceCE = copyOfCEs->right; count != orPosition; count++, replaceCE = replaceCE->bottom) { /* Do Nothing*/ } /*===================================================*/ /* Delete the contents of the "or" CE being expanded */ /* in the copy of the and/or CE. From the example */ /* above, (and (or a b) (or c d)) would be replaced */ /* with (and (or) (or c d)). Note that the "or" CE */ /* is still left as a placeholder. */ /*===================================================*/ ReturnLHSParseNodes(replaceCE->right); /*======================================================*/ /* Copy the current CE being examined in the "or" CE to */ /* the placeholder left in the and/or CE. From the */ /* example above, (and (or) (or c d)) would be replaced */ /* with (and a (or c d)) if the "a" pattern from the */ /* "or" CE was being examined or (and b (or c d)) if */ /* the "b" pattern from the "or" CE was being examined. */ /*======================================================*/ CopyLHSParseNode(replaceCE,orCE,CLIPS_TRUE); replaceCE->right = CopyLHSParseNodes(orCE->right); /*====================================*/ /* Add the newly expanded "and" CE to */ /* the list of CEs already expanded. */ /*====================================*/ if (lastExpandedOrCE == NULL) { listOfExpandedOrCEs = copyOfCEs; copyOfCEs->bottom = NULL; lastExpandedOrCE = copyOfCEs; } else { lastExpandedOrCE->bottom = copyOfCEs; copyOfCEs->bottom = NULL; lastExpandedOrCE = copyOfCEs; } /*=======================================================*/ /* Move on to the next CE in the "or" CE being expanded. */ /*=======================================================*/ orCE = orCE->bottom; } /*=====================================================*/ /* Release the original and/or CE list to free memory. */ /*=====================================================*/ ReturnLHSParseNodes(listOfCEs); /*================================================*/ /* Wrap an or CE around the list of expanded CEs. */ /*================================================*/ copyOfCEs = GetLHSParseNode(); copyOfCEs->type = OR_CE; copyOfCEs->right = listOfExpandedOrCEs; /*================================*/ /* Return the newly expanded CEs. */ /*================================*/ return(copyOfCEs); }/***********************************************************//* CompressCEs: *//***********************************************************/static struct lhsParseNode *CompressCEs(theLHS,newChange) struct lhsParseNode *theLHS; int *newChange; { struct lhsParseNode *argPtr, *lastArg, *nextArg; struct lhsParseNode *tempArg; int change; struct expr *e1, *e2; /*======================================================*/ /* Loop through the CEs as long as changes can be made. */ /*======================================================*/ change = CLIPS_TRUE; *newChange = CLIPS_FALSE; while (change) { change = CLIPS_FALSE; lastArg = NULL; for (argPtr = theLHS->right; argPtr != NULL;) { /*=====================================*/ /* Remove duplication of or CEs within */ /* or CEs and and CEs within and CEs. */ /*=====================================*/ if (((theLHS->type == OR_CE) && (argPtr->type == OR_CE)) || ((theLHS->type == AND_CE) && (argPtr->type == AND_CE))) { if (argPtr->logical) theLHS->logical = CLIPS_TRUE; change = CLIPS_TRUE; *newChange = CLIPS_TRUE; tempArg = argPtr->right; nextArg = argPtr->bottom; argPtr->right = NULL; argPtr->bottom = NULL; ReturnLHSParseNodes(argPtr); if (lastArg == NULL) { theLHS->right = tempArg; } else { lastArg->bottom = tempArg; } argPtr = tempArg; while (tempArg->bottom != NULL) tempArg = tempArg->bottom; tempArg->bottom = nextArg; } /*=======================================================*/ /* Replace not CEs containing a test CE with just a test */ /* CE with the original test CE condition negated. */ /*=======================================================*/ else if ((theLHS->type == NOT_CE) && (argPtr->type == TEST_CE)) { change = CLIPS_TRUE; *newChange = CLIPS_TRUE; e1 = GenConstant(FCALL,PTR_NOT); e2 = LHSParseNodesToExpression(argPtr->expression); e1->arg_list = e2; CopyLHSParseNode(theLHS,argPtr,CLIPS_TRUE); ReturnLHSParseNodes(argPtr); ReturnLHSParseNodes(theLHS->expression); theLHS->expression = ExpressionToLHSParseNodes(e1); theLHS->right = NULL; ReturnExpression(e1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -