📄 reteutil.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 05/17/06 */
/* */
/* RETE UTILITY MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides a set of utility functions useful to */
/* other modules. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/* 6.24: Removed INCREMENTAL_RESET compilation flag. */
/* */
/* Rule with exists CE has incorrect activation. */
/* DR0867 */
/* */
/*************************************************************/
#define _RETEUTIL_SOURCE_
#include <stdio.h>
#define _STDIO_INCLUDED_
#include "setup.h"
#if DEFRULE_CONSTRUCT
#include "drive.h"
#include "engine.h"
#include "envrnmnt.h"
#include "incrrset.h"
#include "match.h"
#include "memalloc.h"
#include "moduldef.h"
#include "pattern.h"
#include "retract.h"
#include "router.h"
#include "reteutil.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static void TraceErrorToRuleDriver(void *,struct joinNode *,char *);
/***********************************************************/
/* PrintPartialMatch: Prints out the list of fact indices */
/* and/or instance names associated with a partial match */
/* or rule instantiation. */
/***********************************************************/
globle void PrintPartialMatch(
void *theEnv,
char *logicalName,
struct partialMatch *list)
{
struct patternEntity *matchingItem;
short int i;
for (i = 0; i < (int) list->bcount;)
{
if (get_nth_pm_match(list,i)->matchingItem != NULL)
{
matchingItem = get_nth_pm_match(list,i)->matchingItem;
if (matchingItem != NULL) (*matchingItem->theInfo->base.shortPrintFunction)(theEnv,logicalName,matchingItem);
}
i++;
if (i < (int) list->bcount) EnvPrintRouter(theEnv,logicalName,",");
}
}
/**********************************************/
/* CopyPartialMatch: Copies a partial match. */
/**********************************************/
globle struct partialMatch *CopyPartialMatch(
void *theEnv,
struct partialMatch *list,
int addActivationSlot,
int addDependencySlot)
{
struct partialMatch *linker;
short int i;
linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) *
(list->bcount + addActivationSlot + addDependencySlot - 1));
linker->next = NULL;
linker->betaMemory = TRUE;
linker->busy = FALSE;
linker->activationf = addActivationSlot;
linker->dependentsf = addDependencySlot;
linker->notOriginf = FALSE;
linker->counterf = FALSE;
linker->bcount = list->bcount;
for (i = 0; i < (int) linker->bcount; i++) linker->binds[i] = list->binds[i];
if (addActivationSlot) linker->binds[i++].gm.theValue = NULL;
if (addDependencySlot) linker->binds[i].gm.theValue = NULL;
return(linker);
}
/****************************************************/
/* MergePartialMatches: Merges two partial matches. */
/****************************************************/
globle struct partialMatch *MergePartialMatches(
void *theEnv,
struct partialMatch *list1,
struct partialMatch *list2,
int addActivationSlot,
int addDependencySlot)
{
struct partialMatch *linker;
short int i, j;
linker = get_var_struct(theEnv,partialMatch,
sizeof(struct genericMatch) *
(list1->bcount + list2->bcount + addActivationSlot + addDependencySlot - 1));
linker->next = NULL;
linker->betaMemory = TRUE;
linker->busy = FALSE;
linker->activationf = addActivationSlot;
linker->dependentsf = addDependencySlot;
linker->notOriginf = FALSE;
linker->counterf = FALSE;
linker->bcount = list1->bcount + list2->bcount;
for (i = 0; i < (int) list1->bcount; i++)
{ linker->binds[i] = list1->binds[i]; }
for (i = (short) list1->bcount, j = 0; i < (short) linker->bcount; i++, j++)
{ linker->binds[i] = list2->binds[j]; }
if (addActivationSlot) linker->binds[i++].gm.theValue = NULL;
if (addDependencySlot) linker->binds[i].gm.theValue = NULL;
return(linker);
}
/*******************************************************************/
/* InitializePatternHeader: Initializes a pattern header structure */
/* (used by the fact and instance pattern matchers). */
/*******************************************************************/
globle void InitializePatternHeader(
void *theEnv,
struct patternNodeHeader *theHeader)
{
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
theHeader->entryJoin = NULL;
theHeader->alphaMemory = NULL;
theHeader->endOfQueue = NULL;
theHeader->singlefieldNode = FALSE;
theHeader->multifieldNode = FALSE;
theHeader->stopNode = FALSE;
#if (! RUN_TIME)
theHeader->initialize = EnvGetIncrementalReset(theEnv);
#else
theHeader->initialize = FALSE;
#endif
theHeader->marked = FALSE;
theHeader->beginSlot = FALSE;
theHeader->endSlot = FALSE;
}
/******************************************************************/
/* CreateAlphaMatch: Given a pointer to an entity (such as a fact */
/* or instance) which matched a pattern, this function creates */
/* a partial match suitable for storing in the alpha memory of */
/* the pattern network. Note that the multifield markers which */
/* are passed as a calling argument are copied (thus the caller */
/* is still responsible for freeing these data structures). */
/******************************************************************/
globle struct partialMatch *CreateAlphaMatch(
void *theEnv,
void *theEntity,
struct multifieldMarker *markers,
struct patternNodeHeader *theHeader)
{
struct partialMatch *theMatch;
struct alphaMatch *afbtemp;
/*==================================================*/
/* Create the alpha match and intialize its values. */
/*==================================================*/
theMatch = get_struct(theEnv,partialMatch);
theMatch->next = NULL;
theMatch->betaMemory = FALSE;
theMatch->busy = FALSE;
theMatch->activationf = FALSE;
theMatch->dependentsf = FALSE;
theMatch->notOriginf = FALSE;
theMatch->counterf = FALSE;
theMatch->bcount = 1;
afbtemp = get_struct(theEnv,alphaMatch);
afbtemp->next = NULL;
afbtemp->matchingItem = (struct patternEntity *) theEntity;
if (markers != NULL)
{ afbtemp->markers = CopyMultifieldMarkers(theEnv,markers); }
else
{ afbtemp->markers = NULL; }
theMatch->binds[0].gm.theMatch = afbtemp;
/*====================================*/
/* Store the alpha match in the alpha */
/* memory of the pattern node. */
/*====================================*/
if (theHeader->endOfQueue == NULL)
{
theHeader->alphaMemory = theMatch;
theHeader->endOfQueue = theMatch;
}
else
{
theHeader->endOfQueue->next = theMatch;
theHeader->endOfQueue = theMatch;
}
/*===================================================*/
/* Return a pointer to the newly create alpha match. */
/*===================================================*/
return(theMatch);
}
/*********************************************************/
/* AddSingleMatch: Combines an alpha match and a partial */
/* match into a new partial match. */
/*********************************************************/
globle struct partialMatch *AddSingleMatch(
void *theEnv,
struct partialMatch *list,
struct alphaMatch *afb,
int addActivationSlot,
int addDependencySlot)
{
struct partialMatch *linker;
short int i;
linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) *
(list->bcount + addActivationSlot +
addDependencySlot));
linker->next = NULL;
linker->betaMemory = TRUE;
linker->busy = FALSE;
linker->activationf = addActivationSlot;
linker->dependentsf = addDependencySlot;
linker->notOriginf = FALSE;
linker->counterf = FALSE;
linker->bcount = list->bcount + 1;
for (i = 0; i < (int) list->bcount; i++)
{ linker->binds[i] = list->binds[i]; }
set_nth_pm_match(linker,i++,afb);
if (addActivationSlot) linker->binds[i++].gm.theValue = NULL;
if (addDependencySlot) linker->binds[i].gm.theValue = NULL;
return(linker);
}
/*******************************************/
/* CopyMultifieldMarkers: Copies a list of */
/* multifieldMarker data structures. */
/*******************************************/
struct multifieldMarker *CopyMultifieldMarkers(
void *theEnv,
struct multifieldMarker *theMarkers)
{
struct multifieldMarker *head = NULL, *lastMark = NULL, *newMark;
while (theMarkers != NULL)
{
newMark = get_struct(theEnv,multifieldMarker);
newMark->next = NULL;
newMark->whichField = theMarkers->whichField;
newMark->where = theMarkers->where;
newMark->startPosition = theMarkers->startPosition;
newMark->endPosition = theMarkers->endPosition;
if (lastMark == NULL)
{ head = newMark; }
else
{ lastMark->next = newMark; }
lastMark = newMark;
theMarkers = theMarkers->next;
}
return(head);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -