📄 rulecstr.c
字号:
andConstraints = NULL;
for (andNode = orNode; andNode != NULL; andNode = andNode->right)
{
if (! andNode->negated)
{
if (andNode->type == RETURN_VALUE_CONSTRAINT)
{
if (andNode->expression->type == FCALL)
{
rvConstraints = FunctionCallToConstraintRecord(theEnv,andNode->expression->value);
tmpConstraints = andConstraints;
andConstraints = IntersectConstraints(theEnv,andConstraints,rvConstraints);
RemoveConstraint(theEnv,tmpConstraints);
RemoveConstraint(theEnv,rvConstraints);
}
}
else if (ConstantType(andNode->type))
{
tmpExpr = GenConstant(theEnv,andNode->type,andNode->value);
rvConstraints = ExpressionToConstraintRecord(theEnv,tmpExpr);
tmpConstraints = andConstraints;
andConstraints = IntersectConstraints(theEnv,andConstraints,rvConstraints);
RemoveConstraint(theEnv,tmpConstraints);
RemoveConstraint(theEnv,rvConstraints);
ReturnExpression(theEnv,tmpExpr);
}
else if (andNode->constraints != NULL)
{
tmpConstraints = andConstraints;
andConstraints = IntersectConstraints(theEnv,andConstraints,andNode->constraints);
RemoveConstraint(theEnv,tmpConstraints);
}
}
}
/*===========================================================*/
/* Intersect the &'ed constraints with the slot constraints. */
/*===========================================================*/
tmpConstraints = andConstraints;
andConstraints = IntersectConstraints(theEnv,andConstraints,theNode->constraints);
RemoveConstraint(theEnv,tmpConstraints);
/*===============================================================*/
/* Remove any negated constants from the list of allowed values. */
/*===============================================================*/
for (andNode = orNode; andNode != NULL; andNode = andNode->right)
{
if ((andNode->negated) && ConstantType(andNode->type))
{ RemoveConstantFromConstraint(theEnv,andNode->type,andNode->value,andConstraints); }
}
/*=======================================================*/
/* Union the &'ed constraints with the |'ed constraints. */
/*=======================================================*/
tmpConstraints = orConstraints;
orConstraints = UnionConstraints(theEnv,orConstraints,andConstraints);
RemoveConstraint(theEnv,tmpConstraints);
RemoveConstraint(theEnv,andConstraints);
}
/*===============================================*/
/* Replace the constraints for the slot with the */
/* constraints derived from the connected */
/* constraints (which should be a subset. */
/*===============================================*/
if (orConstraints != NULL)
{
if (theNode->derivedConstraints) RemoveConstraint(theEnv,theNode->constraints);
theNode->constraints = orConstraints;
theNode->derivedConstraints = TRUE;
}
/*==================================*/
/* Check for constraint violations. */
/*==================================*/
if (CheckForUnmatchableConstraints(theEnv,theNode,(int) patternHead->whichCE))
{ return(TRUE); }
/*=========================================*/
/* If the constraints are for a multifield */
/* slot, check for cardinality violations. */
/*=========================================*/
if ((multifieldHeader != NULL) && (theNode->right == NULL))
{
if (MultifieldCardinalityViolation(theEnv,multifieldHeader))
{
ConstraintViolationErrorMessage(theEnv,"The group of restrictions",
NULL,FALSE,
(int) patternHead->whichCE,
multifieldHeader->slot,
multifieldHeader->index,
CARDINALITY_VIOLATION,
multifieldHeader->constraints,TRUE);
return(TRUE);
}
}
/*=======================================*/
/* Return FALSE indicating no constraint */
/* violations were detected. */
/*=======================================*/
return(FALSE);
}
/**************************************************/
/* ConstraintReferenceErrorMessage: Generic error */
/* message for LHS constraint violation errors */
/* that occur within an expression. */
/**************************************************/
globle void ConstraintReferenceErrorMessage(
void *theEnv,
struct symbolHashNode *theVariable,
struct lhsParseNode *theExpression,
int whichArgument,
int whichCE,
struct symbolHashNode *slotName,
int theField)
{
struct expr *temprv;
PrintErrorID(theEnv,"RULECSTR",2,TRUE);
/*==========================*/
/* Print the variable name. */
/*==========================*/
EnvPrintRouter(theEnv,WERROR,"Previous variable bindings of ?");
EnvPrintRouter(theEnv,WERROR,ValueToString(theVariable));
EnvPrintRouter(theEnv,WERROR," caused the type restrictions");
/*============================*/
/* Print the argument number. */
/*============================*/
EnvPrintRouter(theEnv,WERROR,"\nfor argument #");
PrintLongInteger(theEnv,WERROR,(long int) whichArgument);
/*=======================*/
/* Print the expression. */
/*=======================*/
EnvPrintRouter(theEnv,WERROR," of the expression ");
temprv = LHSParseNodesToExpression(theEnv,theExpression);
ReturnExpression(theEnv,temprv->nextArg);
temprv->nextArg = NULL;
PrintExpression(theEnv,WERROR,temprv);
EnvPrintRouter(theEnv,WERROR,"\n");
ReturnExpression(theEnv,temprv);
/*========================================*/
/* Print out the index of the conditional */
/* element and the slot name or field */
/* index where the violation occured. */
/*========================================*/
EnvPrintRouter(theEnv,WERROR,"found in CE #");
PrintLongInteger(theEnv,WERROR,(long int) whichCE);
if (slotName == NULL)
{
if (theField > 0)
{
EnvPrintRouter(theEnv,WERROR," field #");
PrintLongInteger(theEnv,WERROR,(long int) theField);
}
}
else
{
EnvPrintRouter(theEnv,WERROR," slot ");
EnvPrintRouter(theEnv,WERROR,ValueToString(slotName));
}
EnvPrintRouter(theEnv,WERROR," to be violated.\n");
}
/********************************************************/
/* AddToVariableConstraints: Adds the constraints for a */
/* variable to a list of constraints. If the variable */
/* is already in the list, the constraints for the */
/* variable are intersected with the new constraints. */
/********************************************************/
static struct lhsParseNode *AddToVariableConstraints(
void *theEnv,
struct lhsParseNode *oldList,
struct lhsParseNode *newItems)
{
CONSTRAINT_RECORD *newConstraints;
struct lhsParseNode *temp, *trace;
/*=================================================*/
/* Loop through each of the new constraints adding */
/* it to the list if it's not already present or */
/* modifying the constraint if it is. */
/*=================================================*/
while (newItems != NULL)
{
/*==========================================*/
/* Get the next item since the next pointer */
/* value (right) needs to be set to NULL. */
/*==========================================*/
temp = newItems->right;
newItems->right = NULL;
/*===================================*/
/* Search the list for the variable. */
/*===================================*/
for (trace = oldList; trace != NULL; trace = trace->right)
{
/*=========================================*/
/* If the variable is already in the list, */
/* modify the constraint already there to */
/* include the new constraint. */
/*=========================================*/
if (trace->value == newItems->value)
{
newConstraints = IntersectConstraints(theEnv,trace->constraints,
newItems->constraints);
RemoveConstraint(theEnv,trace->constraints);
trace->constraints = newConstraints;
ReturnLHSParseNodes(theEnv,newItems);
break;
}
}
/*=================================*/
/* Add the variable constraints to */
/* the list if it wasn't found. */
/*=================================*/
if (trace == NULL)
{
newItems->right = oldList;
oldList = newItems;
}
/*===========================*/
/* Move on to the next item. */
/*===========================*/
newItems = temp;
}
return(oldList);
}
/***********************************************************/
/* UnionVariableConstraints: Unions two lists of variable */
/* constraints. If a variable appears in one list but */
/* not the other, then the variable is unconstrained and */
/* thus not included in the unioned list. */
/***********************************************************/
static struct lhsParseNode *UnionVariableConstraints(
void *theEnv,
struct lhsParseNode *list1,
struct lhsParseNode *list2)
{
struct lhsParseNode *list3 = NULL, *trace, *temp;
/*===================================*/
/* Loop through all of the variables */
/* in the first list. */
/*===================================*/
while (list1 != NULL)
{
/*=============================================*/
/* Search for the variable in the second list. */
/*=============================================*/
for (trace = list2; trace != NULL; trace = trace->right)
{
/*============================================*/
/* If the variable is found in both lists, */
/* union the constraints and add the variable */
/* to the new list being constructed. */
/*============================================*/
if (list1->value == trace->value)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -