📄 cstrnutl.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 07/01/05 */
/* */
/* CONSTRAINT UTILITY MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Utility routines for manipulating, initializing, */
/* creating, copying, and comparing constraint records. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian Donnell */
/* */
/* Revision History: */
/* 6.24: Added allowed-classes slot facet. */
/* */
/*************************************************************/
#define _CSTRNUTL_SOURCE_
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <stdlib.h>
#include "setup.h"
#include "constant.h"
#include "envrnmnt.h"
#include "memalloc.h"
#include "router.h"
#include "extnfunc.h"
#include "scanner.h"
#include "multifld.h"
#include "argacces.h"
#include "cstrnutl.h"
/************************************************/
/* GetConstraintRecord: Creates and initializes */
/* the values of a constraint record. */
/************************************************/
globle struct constraintRecord *GetConstraintRecord(
void *theEnv)
{
CONSTRAINT_RECORD *constraints;
unsigned i;
constraints = get_struct(theEnv,constraintRecord);
for (i = 0 ; i < sizeof(CONSTRAINT_RECORD) ; i++)
{ ((char *) constraints)[i] = '\0'; }
SetAnyAllowedFlags(constraints,TRUE);
constraints->multifieldsAllowed = FALSE;
constraints->singlefieldsAllowed = TRUE;
constraints->anyRestriction = FALSE;
constraints->symbolRestriction = FALSE;
constraints->stringRestriction = FALSE;
constraints->floatRestriction = FALSE;
constraints->integerRestriction = FALSE;
constraints->classRestriction = FALSE;
constraints->instanceNameRestriction = FALSE;
constraints->classList = NULL;
constraints->restrictionList = NULL;
constraints->minValue = GenConstant(theEnv,SYMBOL,SymbolData(theEnv)->NegativeInfinity);
constraints->maxValue = GenConstant(theEnv,SYMBOL,SymbolData(theEnv)->PositiveInfinity);
constraints->minFields = GenConstant(theEnv,INTEGER,SymbolData(theEnv)->Zero);
constraints->maxFields = GenConstant(theEnv,SYMBOL,SymbolData(theEnv)->PositiveInfinity);
constraints->bucket = -1;
constraints->count = 0;
constraints->multifield = NULL;
constraints->next = NULL;
return(constraints);
}
/********************************************************/
/* SetAnyAllowedFlags: Sets the allowed type flags of a */
/* constraint record to allow all types. If passed an */
/* argument of TRUE, just the "any allowed" flag is */
/* set to TRUE. If passed an argument of FALSE, then */
/* all of the individual type flags are set to TRUE. */
/********************************************************/
globle void SetAnyAllowedFlags(
CONSTRAINT_RECORD *theConstraint,
int justOne)
{
int flag1, flag2;
if (justOne)
{
flag1 = TRUE;
flag2 = FALSE;
}
else
{
flag1 = FALSE;
flag2 = TRUE;
}
theConstraint->anyAllowed = flag1;
theConstraint->symbolsAllowed = flag2;
theConstraint->stringsAllowed = flag2;
theConstraint->floatsAllowed = flag2;
theConstraint->integersAllowed = flag2;
theConstraint->instanceNamesAllowed = flag2;
theConstraint->instanceAddressesAllowed = flag2;
theConstraint->externalAddressesAllowed = flag2;
theConstraint->voidAllowed = flag2;
theConstraint->factAddressesAllowed = flag2;
}
/*****************************************************/
/* CopyConstraintRecord: Copies a constraint record. */
/*****************************************************/
globle struct constraintRecord *CopyConstraintRecord(
void *theEnv,
CONSTRAINT_RECORD *sourceConstraint)
{
CONSTRAINT_RECORD *theConstraint;
if (sourceConstraint == NULL) return(NULL);
theConstraint = get_struct(theEnv,constraintRecord);
theConstraint->anyAllowed = sourceConstraint->anyAllowed;
theConstraint->symbolsAllowed = sourceConstraint->symbolsAllowed;
theConstraint->stringsAllowed = sourceConstraint->stringsAllowed;
theConstraint->floatsAllowed = sourceConstraint->floatsAllowed;
theConstraint->integersAllowed = sourceConstraint->integersAllowed;
theConstraint->instanceNamesAllowed = sourceConstraint->instanceNamesAllowed;
theConstraint->instanceAddressesAllowed = sourceConstraint->instanceAddressesAllowed;
theConstraint->externalAddressesAllowed = sourceConstraint->externalAddressesAllowed;
theConstraint->voidAllowed = sourceConstraint->voidAllowed;
theConstraint->multifieldsAllowed = sourceConstraint->multifieldsAllowed;
theConstraint->singlefieldsAllowed = sourceConstraint->singlefieldsAllowed;
theConstraint->factAddressesAllowed = sourceConstraint->factAddressesAllowed;
theConstraint->anyRestriction = sourceConstraint->anyRestriction;
theConstraint->symbolRestriction = sourceConstraint->symbolRestriction;
theConstraint->stringRestriction = sourceConstraint->stringRestriction;
theConstraint->floatRestriction = sourceConstraint->floatRestriction;
theConstraint->integerRestriction = sourceConstraint->integerRestriction;
theConstraint->classRestriction = sourceConstraint->classRestriction;
theConstraint->instanceNameRestriction = sourceConstraint->instanceNameRestriction;
theConstraint->classList = CopyExpression(theEnv,sourceConstraint->classList);
theConstraint->restrictionList = CopyExpression(theEnv,sourceConstraint->restrictionList);
theConstraint->minValue = CopyExpression(theEnv,sourceConstraint->minValue);
theConstraint->maxValue = CopyExpression(theEnv,sourceConstraint->maxValue);
theConstraint->minFields = CopyExpression(theEnv,sourceConstraint->minFields);
theConstraint->maxFields = CopyExpression(theEnv,sourceConstraint->maxFields);
theConstraint->bucket = -1;
theConstraint->count = 0;
theConstraint->multifield = CopyConstraintRecord(theEnv,sourceConstraint->multifield);
theConstraint->next = NULL;
return(theConstraint);
}
#if (! RUN_TIME) && (! BLOAD_ONLY)
/**************************************************************/
/* SetAnyRestrictionFlags: Sets the restriction type flags of */
/* a constraint record to indicate there are restriction on */
/* all types. If passed an argument of TRUE, just the */
/* "any restriction" flag is set to TRUE. If passed an */
/* argument of FALSE, then all of the individual type */
/* restriction flags are set to TRUE. */
/**************************************************************/
globle void SetAnyRestrictionFlags(
CONSTRAINT_RECORD *theConstraint,
int justOne)
{
int flag1, flag2;
if (justOne)
{
flag1 = TRUE;
flag2 = FALSE;
}
else
{
flag1 = FALSE;
flag2 = TRUE;
}
theConstraint->anyRestriction = flag1;
theConstraint->symbolRestriction = flag2;
theConstraint->stringRestriction = flag2;
theConstraint->floatRestriction = flag2;
theConstraint->integerRestriction = flag2;
theConstraint->instanceNameRestriction = flag2;
}
/*****************************************************/
/* SetConstraintType: Given a constraint type and a */
/* constraint, sets the allowed type flags for the */
/* specified type in the constraint to TRUE. */
/*****************************************************/
globle int SetConstraintType(
int theType,
CONSTRAINT_RECORD *constraints)
{
int rv = TRUE;
switch(theType)
{
case UNKNOWN_VALUE:
rv = constraints->anyAllowed;
constraints->anyAllowed = TRUE;
break;
case SYMBOL:
rv = constraints->symbolsAllowed;
constraints->symbolsAllowed = TRUE;
break;
case STRING:
rv = constraints->stringsAllowed;
constraints->stringsAllowed = TRUE;
break;
case SYMBOL_OR_STRING:
rv = (constraints->stringsAllowed | constraints->symbolsAllowed);
constraints->symbolsAllowed = TRUE;
constraints->stringsAllowed = TRUE;
break;
case INTEGER:
rv = constraints->integersAllowed;
constraints->integersAllowed = TRUE;
break;
case FLOAT:
rv = constraints->floatsAllowed;
constraints->floatsAllowed = TRUE;
break;
case INTEGER_OR_FLOAT:
rv = (constraints->integersAllowed | constraints->floatsAllowed);
constraints->integersAllowed = TRUE;
constraints->floatsAllowed = TRUE;
break;
case INSTANCE_ADDRESS:
rv = constraints->instanceAddressesAllowed;
constraints->instanceAddressesAllowed = TRUE;
break;
case INSTANCE_NAME:
rv = constraints->instanceNamesAllowed;
constraints->instanceNamesAllowed = TRUE;
break;
case INSTANCE_OR_INSTANCE_NAME:
rv = (constraints->instanceNamesAllowed | constraints->instanceAddressesAllowed);
constraints->instanceNamesAllowed = TRUE;
constraints->instanceAddressesAllowed = TRUE;
break;
case EXTERNAL_ADDRESS:
rv = constraints->externalAddressesAllowed;
constraints->externalAddressesAllowed = TRUE;
break;
case RVOID:
rv = constraints->voidAllowed;
constraints->voidAllowed = TRUE;
break;
case FACT_ADDRESS:
rv = constraints->factAddressesAllowed;
constraints->factAddressesAllowed = TRUE;
break;
case MULTIFIELD:
rv = constraints->multifieldsAllowed;
constraints->multifieldsAllowed = TRUE;
break;
}
if (theType != UNKNOWN_VALUE) constraints->anyAllowed = FALSE;
return(rv);
}
#endif /* (! RUN_TIME) && (! BLOAD_ONLY) */
/*************************************************************/
/* CompareNumbers: Given two numbers (which can be integers, */
/* floats, or the symbols for positive/negative infinity) */
/* returns the relationship between the numbers (greater */
/* than, less than or equal). */
/*************************************************************/
globle int CompareNumbers(
void *theEnv,
int type1,
void *vptr1,
int type2,
void *vptr2)
{
/*============================================*/
/* Handle the situation in which the values */
/* are exactly equal (same type, same value). */
/*============================================*/
if (vptr1 == vptr2) return(EQUAL);
/*=======================================*/
/* Handle the special cases for positive */
/* and negative infinity. */
/*=======================================*/
if (vptr1 == SymbolData(theEnv)->PositiveInfinity) return(GREATER_THAN);
if (vptr1 == SymbolData(theEnv)->NegativeInfinity) return(LESS_THAN);
if (vptr2 == SymbolData(theEnv)->PositiveInfinity) return(LESS_THAN);
if (vptr2 == SymbolData(theEnv)->NegativeInfinity) return(GREATER_THAN);
/*=======================*/
/* Compare two integers. */
/*=======================*/
if ((type1 == INTEGER) && (type2 == INTEGER))
{
if (ValueToLong(vptr1) < ValueToLong(vptr2))
{ return(LESS_THAN); }
else if (ValueToLong(vptr1) > ValueToLong(vptr2))
{ return(GREATER_THAN); }
return(EQUAL);
}
/*=====================*/
/* Compare two floats. */
/*=====================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -