📄 cstrnchk.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 07/01/05 */
/* */
/* CONSTRAINT CHECKING MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides functions for constraint checking of */
/* data types. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian Donnell */
/* */
/* Revision History: */
/* 6.23: Changed name of variable exp to theExp */
/* because of Unix compiler warnings of shadowed */
/* definitions. */
/* */
/* 6.24: Added allowed-classes slot facet. */
/* */
/* Renamed BOOLEAN macro type to intBool. */
/* */
/*************************************************************/
#define _CSTRNCHK_SOURCE_
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <stdlib.h>
#include "setup.h"
#include "router.h"
#include "multifld.h"
#include "envrnmnt.h"
#include "extnfunc.h"
#include "cstrnutl.h"
#if OBJECT_SYSTEM
#include "inscom.h"
#include "insfun.h"
#include "classcom.h"
#include "classexm.h"
#endif
#include "cstrnchk.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static intBool CheckRangeAgainstCardinalityConstraint(void *,int,int,CONSTRAINT_RECORD *);
static int CheckFunctionReturnType(int,CONSTRAINT_RECORD *);
static intBool CheckTypeConstraint(int,CONSTRAINT_RECORD *);
static intBool CheckRangeConstraint(void *,int,void *,CONSTRAINT_RECORD *);
static void PrintRange(void *,char *,CONSTRAINT_RECORD *);
/******************************************************/
/* CheckFunctionReturnType: Checks a functions return */
/* type against a set of permissable return values. */
/* Returns TRUE if the return type is included */
/* among the permissible values, otherwise FALSE. */
/******************************************************/
static int CheckFunctionReturnType(
int functionReturnType,
CONSTRAINT_RECORD *constraints)
{
if (constraints == NULL) return(TRUE);
if (constraints->anyAllowed) return(TRUE);
switch(functionReturnType)
{
case 'c':
case 'w':
case 'b':
if (constraints->symbolsAllowed) return(TRUE);
else return(FALSE);
case 's':
if (constraints->stringsAllowed) return(TRUE);
else return(FALSE);
case 'j':
if ((constraints->symbolsAllowed) ||
(constraints->stringsAllowed) ||
(constraints->instanceNamesAllowed)) return(TRUE);
else return(FALSE);
case 'k':
if ((constraints->symbolsAllowed) || (constraints->stringsAllowed)) return(TRUE);
else return(FALSE);
case 'd':
case 'f':
if (constraints->floatsAllowed) return(TRUE);
else return(FALSE);
case 'i':
case 'l':
if (constraints->integersAllowed) return(TRUE);
else return(FALSE);
case 'n':
if ((constraints->integersAllowed) || (constraints->floatsAllowed)) return(TRUE);
else return(FALSE);
case 'm':
if (constraints->multifieldsAllowed) return(TRUE);
else return(FALSE);
case 'a':
if (constraints->externalAddressesAllowed) return(TRUE);
else return(FALSE);
case 'x':
if (constraints->instanceAddressesAllowed) return(TRUE);
else return(FALSE);
case 'o':
if (constraints->instanceNamesAllowed) return(TRUE);
else return(FALSE);
case 'u':
return(TRUE);
case 'v':
if (constraints->voidAllowed) return(TRUE);
}
return(TRUE);
}
/****************************************************/
/* CheckTypeConstraint: Determines if a primitive */
/* data type satisfies the type constraint fields */
/* of aconstraint record. */
/****************************************************/
static intBool CheckTypeConstraint(
int type,
CONSTRAINT_RECORD *constraints)
{
if (type == RVOID) return(FALSE);
if (constraints == NULL) return(TRUE);
if (constraints->anyAllowed == TRUE) return(TRUE);
if ((type == SYMBOL) && (constraints->symbolsAllowed != TRUE))
{ return(FALSE); }
if ((type == STRING) && (constraints->stringsAllowed != TRUE))
{ return(FALSE); }
if ((type == FLOAT) && (constraints->floatsAllowed != TRUE))
{ return(FALSE); }
if ((type == INTEGER) && (constraints->integersAllowed != TRUE))
{ return(FALSE); }
#if OBJECT_SYSTEM
if ((type == INSTANCE_NAME) && (constraints->instanceNamesAllowed != TRUE))
{ return(FALSE); }
if ((type == INSTANCE_ADDRESS) && (constraints->instanceAddressesAllowed != TRUE))
{ return(FALSE); }
#endif
if ((type == EXTERNAL_ADDRESS) && (constraints->externalAddressesAllowed != TRUE))
{ return(FALSE); }
if ((type == RVOID) && (constraints->voidAllowed != TRUE))
{ return(FALSE); }
if ((type == FACT_ADDRESS) && (constraints->factAddressesAllowed != TRUE))
{ return(FALSE); }
return(TRUE);
}
/********************************************************/
/* CheckCardinalityConstraint: Determines if an integer */
/* falls within the range of allowed cardinalities */
/* for a constraint record. */
/********************************************************/
globle intBool CheckCardinalityConstraint(
void *theEnv,
long number,
CONSTRAINT_RECORD *constraints)
{
/*=========================================*/
/* If the constraint record is NULL, there */
/* are no cardinality restrictions. */
/*=========================================*/
if (constraints == NULL) return(TRUE);
/*==================================*/
/* Determine if the integer is less */
/* than the minimum cardinality. */
/*==================================*/
if (constraints->minFields != NULL)
{
if (constraints->minFields->value != SymbolData(theEnv)->NegativeInfinity)
{
if (number < ValueToLong(constraints->minFields->value))
{ return(FALSE); }
}
}
/*=====================================*/
/* Determine if the integer is greater */
/* than the maximum cardinality. */
/*=====================================*/
if (constraints->maxFields != NULL)
{
if (constraints->maxFields->value != SymbolData(theEnv)->PositiveInfinity)
{
if (number > ValueToLong(constraints->maxFields->value))
{ return(FALSE); }
}
}
/*=========================================================*/
/* The integer falls within the allowed cardinality range. */
/*=========================================================*/
return(TRUE);
}
/*****************************************************************/
/* CheckRangeAgainstCardinalityConstraint: Determines if a range */
/* of numbers could possibly fall within the range of allowed */
/* cardinalities for a constraint record. Returns TRUE if at */
/* least one of the numbers in the range is within the allowed */
/* cardinality, otherwise FALSE is returned. */
/*****************************************************************/
static intBool CheckRangeAgainstCardinalityConstraint(
void *theEnv,
int min,
int max,
CONSTRAINT_RECORD *constraints)
{
/*=========================================*/
/* If the constraint record is NULL, there */
/* are no cardinality restrictions. */
/*=========================================*/
if (constraints == NULL) return(TRUE);
/*===============================================================*/
/* If the minimum value of the range is greater than the maximum */
/* value of the cardinality, then there are no numbers in the */
/* range which could fall within the cardinality range, and so */
/* FALSE is returned. */
/*===============================================================*/
if (constraints->maxFields != NULL)
{
if (constraints->maxFields->value != SymbolData(theEnv)->PositiveInfinity)
{
if (min > ValueToLong(constraints->maxFields->value))
{ return(FALSE); }
}
}
/*===============================================================*/
/* If the maximum value of the range is less than the minimum */
/* value of the cardinality, then there are no numbers in the */
/* range which could fall within the cardinality range, and so */
/* FALSE is returned. A maximum range value of -1 indicates that */
/* the maximum possible value of the range is positive infinity. */
/*===============================================================*/
if ((constraints->minFields != NULL) && (max != -1))
{
if (constraints->minFields->value != SymbolData(theEnv)->NegativeInfinity)
{
if (max < ValueToLong(constraints->minFields->value))
{ return(FALSE); }
}
}
/*=============================================*/
/* At least one number in the specified range */
/* falls within the allowed cardinality range. */
/*=============================================*/
return(TRUE);
}
/**********************************************************************/
/* CheckAllowedValuesConstraint: Determines if a primitive data type */
/* satisfies the allowed-... constraint fields of a constraint */
/* record. Returns TRUE if the constraints are satisfied, otherwise */
/* FALSE is returned. */
/**********************************************************************/
globle intBool CheckAllowedValuesConstraint(
int type,
void *vPtr,
CONSTRAINT_RECORD *constraints)
{
struct expr *tmpPtr;
/*=========================================*/
/* If the constraint record is NULL, there */
/* are no allowed-... restrictions. */
/*=========================================*/
if (constraints == NULL) return(TRUE);
/*=====================================================*/
/* Determine if there are any allowed-... restrictions */
/* for the type of the value being checked. */
/*=====================================================*/
switch (type)
{
case SYMBOL:
if ((constraints->symbolRestriction == FALSE) &&
(constraints->anyRestriction == FALSE))
{ return(TRUE); }
break;
#if OBJECT_SYSTEM
case INSTANCE_NAME:
if ((constraints->instanceNameRestriction == FALSE) &&
(constraints->anyRestriction == FALSE))
{ return(TRUE); }
break;
#endif
case STRING:
if ((constraints->stringRestriction == FALSE) &&
(constraints->anyRestriction == FALSE))
{ return(TRUE); }
break;
case INTEGER:
if ((constraints->integerRestriction == FALSE) &&
(constraints->anyRestriction == FALSE))
{ return(TRUE); }
break;
case FLOAT:
if ((constraints->floatRestriction == FALSE) &&
(constraints->anyRestriction == FALSE))
{ return(TRUE); }
break;
default:
return(TRUE);
}
/*=========================================================*/
/* Search through the restriction list to see if the value */
/* matches one of the allowed values in the list. */
/*=========================================================*/
for (tmpPtr = constraints->restrictionList;
tmpPtr != NULL;
tmpPtr = tmpPtr->nextArg)
{
if ((tmpPtr->type == type) && (tmpPtr->value == vPtr)) return(TRUE);
}
/*====================================================*/
/* If the value wasn't found in the list, then return */
/* FALSE because the constraint has been violated. */
/*====================================================*/
return(FALSE);
}
/**********************************************************************/
/* CheckAllowedClassesConstraint: Determines if a primitive data type */
/* satisfies the allowed-classes constraint fields of a constraint */
/* record. Returns TRUE if the constraints are satisfied, otherwise */
/* FALSE is returned. */
/**********************************************************************/
globle intBool CheckAllowedClassesConstraint(
void *theEnv,
int type,
void *vPtr,
CONSTRAINT_RECORD *constraints)
{
#if OBJECT_SYSTEM
struct expr *tmpPtr;
INSTANCE_TYPE *ins;
DEFCLASS *insClass, *cmpClass;
/*=========================================*/
/* If the constraint record is NULL, there */
/* is no allowed-classes restriction. */
/*=========================================*/
if (constraints == NULL) return(TRUE);
/*======================================*/
/* The constraint is satisfied if there */
/* aren't any class restrictions. */
/*======================================*/
if (constraints->classList == NULL)
{ return(TRUE); }
/*==================================*/
/* Class restrictions only apply to */
/* instances and instance names. */
/*==================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -