📄 reorder.c
字号:
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;
*newChange = TRUE;
break;
}
/*==============================================================*/
/* Convert not/or CE combinations into and/not CE combinations. */
/*==============================================================*/
else if ((theLHS->type == NOT_CE) && (argPtr->type == OR_CE))
{
change = TRUE;
*newChange = TRUE;
tempArg = argPtr->right;
argPtr->right = NULL;
argPtr->bottom = NULL;
ReturnLHSParseNodes(theEnv,argPtr);
theLHS->type = AND_CE;
theLHS->right = tempArg;
while (tempArg != NULL)
{
newNode = GetLHSParseNode(theEnv);
CopyLHSParseNode(theEnv,newNode,tempArg,FALSE);
newNode->right = tempArg->right;
newNode->bottom = NULL;
tempArg->type = NOT_CE;
tempArg->negated = FALSE;
tempArg->logical = 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 = TRUE;
change = TRUE;
*newChange = TRUE;
tempArg = argPtr->right;
nextArg = argPtr->bottom;
argPtr->right = NULL;
argPtr->bottom = NULL;
ReturnLHSParseNodes(theEnv,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 */
/* KB Rete topology. The second pass performs all other */
/* transformations not associated with the or CE. */
/***********************************************************/
static struct lhsParseNode *PerformReorder2(
void *theEnv,
struct lhsParseNode *theLHS,
int *newChange)
{
struct lhsParseNode *argPtr;
int change;
/*======================================================*/
/* Loop through the CEs as long as changes can be made. */
/*======================================================*/
change = TRUE;
*newChange = FALSE;
while (change)
{
change = 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 = TRUE;
*newChange = TRUE;
CopyLHSParseNode(theEnv,theLHS,argPtr,FALSE);
theLHS->negated = TRUE;
theLHS->right = argPtr->right;
argPtr->networkTest = NULL;
argPtr->expression = NULL;
argPtr->userData = NULL;
argPtr->right = NULL;
argPtr->bottom = NULL;
ReturnLHSParseNodes(theEnv,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 = TRUE;
*newChange = 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(theEnv,argPtr);
IncrementNandDepth(theEnv,theLHS->right,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(
void *theEnv,
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(theEnv,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(theEnv,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(theEnv,replaceCE,orCE,TRUE);
replaceCE->right = CopyLHSParseNodes(theEnv,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(theEnv,listOfCEs);
/*================================================*/
/* Wrap an or CE around the list of expanded CEs. */
/*================================================*/
copyOfCEs = GetLHSParseNode(theEnv);
copyOfCEs->type = OR_CE;
copyOfCEs->right = listOfExpandedOrCEs;
/*================================*/
/* Return the newly expanded CEs. */
/*================================*/
return(copyOfCEs);
}
/***********************************************************/
/* CompressCEs: */
/***********************************************************/
static struct lhsParseNode *CompressCEs(
void *theEnv,
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 = TRUE;
*newChange = FALSE;
while (change)
{
change = 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 = TRUE;
change = TRUE;
*newChange = TRUE;
tempArg = argPtr->right;
nextArg = argPtr->bottom;
argPtr->right = NULL;
argPtr->bottom = NULL;
ReturnLHSParseNodes(theEnv,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 = TRUE;
*newChange = TRUE;
e1 = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NOT);
e2 = LHSParseNodesToExpression(theEnv,argPtr->expression);
e1->arg_list = e2;
CopyLHSParseNode(theEnv,theLHS,argPtr,TRUE);
ReturnLHSParseNodes(theEnv,argPtr);
ReturnLHSParseNodes(theEnv,theLHS->expression);
theLHS->expression = ExpressionToLHSParseNodes(theEnv,e1);
theLHS->right = NULL;
ReturnExpression(theEnv,e1);
break;
}
/*==============================*/
/* Two adjacent test CEs within */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -