📄 constrnt.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 07/01/05 */
/* */
/* CONSTRAINT MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides functions for creating and removing */
/* constraint records, adding them to the contraint hash */
/* table, and enabling and disabling static and dynamic */
/* constraint checking. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian Donnell */
/* */
/* Revision History: */
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
/* */
/* 6.24: Added allowed-classes slot facet. */
/* */
/* Renamed BOOLEAN macro type to intBool. */
/* */
/*************************************************************/
#define _CONSTRNT_SOURCE_
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <stdlib.h>
#include "setup.h"
#include "argacces.h"
#include "constant.h"
#include "envrnmnt.h"
#include "extnfunc.h"
#include "memalloc.h"
#include "multifld.h"
#include "router.h"
#include "scanner.h"
#include "constrnt.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if (! RUN_TIME) && (! BLOAD_ONLY)
static void InstallConstraintRecord(void *,CONSTRAINT_RECORD *);
static int ConstraintCompare(struct constraintRecord *,struct constraintRecord *);
#endif
#if (! RUN_TIME)
static void ReturnConstraintRecord(void *,CONSTRAINT_RECORD *);
static void DeinstallConstraintRecord(void *,CONSTRAINT_RECORD *);
#endif
static void DeallocateConstraintData(void *);
/*****************************************************/
/* InitializeConstraints: Initializes the constraint */
/* hash table to NULL and defines the static and */
/* dynamic constraint access functions. */
/*****************************************************/
globle void InitializeConstraints(
void *theEnv)
{
#if (! RUN_TIME) && (! BLOAD_ONLY)
int i;
#endif
AllocateEnvironmentData(theEnv,CONSTRAINT_DATA,sizeof(struct constraintData),DeallocateConstraintData);
ConstraintData(theEnv)->StaticConstraintChecking = TRUE;
#if (! RUN_TIME) && (! BLOAD_ONLY)
ConstraintData(theEnv)->ConstraintHashtable = (struct constraintRecord **)
gm2(theEnv,(int) sizeof (struct constraintRecord *) *
SIZE_CONSTRAINT_HASH);
if (ConstraintData(theEnv)->ConstraintHashtable == NULL) EnvExitRouter(theEnv,EXIT_FAILURE);
for (i = 0; i < SIZE_CONSTRAINT_HASH; i++) ConstraintData(theEnv)->ConstraintHashtable[i] = NULL;
#endif
#if (! RUN_TIME)
EnvDefineFunction2(theEnv,"get-dynamic-constraint-checking",'b',GDCCommand,"GDCCommand", "00");
EnvDefineFunction2(theEnv,"set-dynamic-constraint-checking",'b',SDCCommand,"SDCCommand", "11");
EnvDefineFunction2(theEnv,"get-static-constraint-checking",'b',GSCCommand,"GSCCommand", "00");
EnvDefineFunction2(theEnv,"set-static-constraint-checking",'b',SSCCommand,"SSCCommand", "11");
#endif
}
/*****************************************************/
/* DeallocateConstraintData: Deallocates environment */
/* data for constraints. */
/*****************************************************/
static void DeallocateConstraintData(
void *theEnv)
{
#if ! RUN_TIME
struct constraintRecord *tmpPtr, *nextPtr;
int i;
for (i = 0; i < SIZE_CONSTRAINT_HASH; i++)
{
tmpPtr = ConstraintData(theEnv)->ConstraintHashtable[i];
while (tmpPtr != NULL)
{
nextPtr = tmpPtr->next;
ReturnConstraintRecord(theEnv,tmpPtr);
tmpPtr = nextPtr;
}
}
rm(theEnv,ConstraintData(theEnv)->ConstraintHashtable,
(int) sizeof (struct constraintRecord *) * SIZE_CONSTRAINT_HASH);
#else
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
#endif
#if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME)
if (ConstraintData(theEnv)->NumberOfConstraints != 0)
{
genlongfree(theEnv,(void *) ConstraintData(theEnv)->ConstraintArray,
(unsigned long) (sizeof(CONSTRAINT_RECORD) *
ConstraintData(theEnv)->NumberOfConstraints));
}
#endif
}
#if (! RUN_TIME)
/*************************************************************/
/* ReturnConstraintRecord: Frees the data structures used by */
/* a constraint record. If the returnOnlyFields argument */
/* is FALSE, then the constraint record is also freed. */
/*************************************************************/
static void ReturnConstraintRecord(
void *theEnv,
CONSTRAINT_RECORD *constraints)
{
if (constraints == NULL) return;
if (constraints->bucket < 0)
{
ReturnExpression(theEnv,constraints->classList);
ReturnExpression(theEnv,constraints->restrictionList);
ReturnExpression(theEnv,constraints->maxValue);
ReturnExpression(theEnv,constraints->minValue);
ReturnExpression(theEnv,constraints->minFields);
ReturnExpression(theEnv,constraints->maxFields);
}
ReturnConstraintRecord(theEnv,constraints->multifield);
rtn_struct(theEnv,constraintRecord,constraints);
}
/***************************************************/
/* DeinstallConstraintRecord: Decrements the count */
/* values of all occurrences of primitive data */
/* types found in a constraint record. */
/***************************************************/
static void DeinstallConstraintRecord(
void *theEnv,
CONSTRAINT_RECORD *constraints)
{
if (constraints->bucket >= 0)
{
RemoveHashedExpression(theEnv,constraints->classList);
RemoveHashedExpression(theEnv,constraints->restrictionList);
RemoveHashedExpression(theEnv,constraints->maxValue);
RemoveHashedExpression(theEnv,constraints->minValue);
RemoveHashedExpression(theEnv,constraints->minFields);
RemoveHashedExpression(theEnv,constraints->maxFields);
}
else
{
ExpressionDeinstall(theEnv,constraints->classList);
ExpressionDeinstall(theEnv,constraints->restrictionList);
ExpressionDeinstall(theEnv,constraints->maxValue);
ExpressionDeinstall(theEnv,constraints->minValue);
ExpressionDeinstall(theEnv,constraints->minFields);
ExpressionDeinstall(theEnv,constraints->maxFields);
}
if (constraints->multifield != NULL)
{ DeinstallConstraintRecord(theEnv,constraints->multifield); }
}
/******************************************/
/* RemoveConstraint: Removes a constraint */
/* from the constraint hash table. */
/******************************************/
globle void RemoveConstraint(
void *theEnv,
struct constraintRecord *theConstraint)
{
struct constraintRecord *tmpPtr, *prevPtr = NULL;
if (theConstraint == NULL) return;
/*========================================*/
/* If the bucket value is less than zero, */
/* then the constraint wasn't stored in */
/* the hash table. */
/*========================================*/
if (theConstraint->bucket < 0)
{
ReturnConstraintRecord(theEnv,theConstraint);
return;
}
/*================================*/
/* Find and remove the constraint */
/* from the contraint hash table. */
/*================================*/
tmpPtr = ConstraintData(theEnv)->ConstraintHashtable[theConstraint->bucket];
while (tmpPtr != NULL)
{
if (tmpPtr == theConstraint)
{
theConstraint->count--;
if (theConstraint->count == 0)
{
if (prevPtr == NULL)
{ ConstraintData(theEnv)->ConstraintHashtable[theConstraint->bucket] = theConstraint->next; }
else
{ prevPtr->next = theConstraint->next; }
DeinstallConstraintRecord(theEnv,theConstraint);
ReturnConstraintRecord(theEnv,theConstraint);
}
return;
}
prevPtr = tmpPtr;
tmpPtr = tmpPtr->next;
}
return;
}
#endif /* (! RUN_TIME) */
#if (! RUN_TIME) && (! BLOAD_ONLY)
/***********************************/
/* HashConstraint: Returns a hash */
/* value for a given constraint. */
/***********************************/
globle int HashConstraint(
struct constraintRecord *theConstraint)
{
int i = 0;
unsigned int count = 0;
int hashValue;
struct expr *tmpPtr;
count += (unsigned)
(theConstraint->anyAllowed * 17) +
(theConstraint->symbolsAllowed * 5) +
(theConstraint->stringsAllowed * 23) +
(theConstraint->floatsAllowed * 19) +
(theConstraint->integersAllowed * 29) +
(theConstraint->instanceNamesAllowed * 31) +
(theConstraint->instanceAddressesAllowed * 17);
count += (unsigned)
(theConstraint->externalAddressesAllowed * 29) +
(theConstraint->voidAllowed * 29) +
(theConstraint->multifieldsAllowed * 29) +
(theConstraint->factAddressesAllowed * 79) +
(theConstraint->anyRestriction * 59) +
(theConstraint->symbolRestriction * 61);
count += (unsigned)
(theConstraint->stringRestriction * 3) +
(theConstraint->floatRestriction * 37) +
(theConstraint->integerRestriction * 9) +
(theConstraint->classRestriction * 11) +
(theConstraint->instanceNameRestriction * 7);
for (tmpPtr = theConstraint->classList; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
{ count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
for (tmpPtr = theConstraint->restrictionList; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
{ count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
for (tmpPtr = theConstraint->minValue; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
{ count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
for (tmpPtr = theConstraint->maxValue; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
{ count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
for (tmpPtr = theConstraint->minFields; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
{ count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
for (tmpPtr = theConstraint->maxFields; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
{ count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
if (theConstraint->multifield != NULL)
{ count += (unsigned) HashConstraint(theConstraint->multifield); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -