?? rulecmp.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 05/17/06 */ /* */ /* DEFRULE CONSTRUCTS-TO-C MODULE */ /*******************************************************//*************************************************************//* Purpose: Implements the constructs-to-c feature for the *//* defrule construct. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* Brian L. Donnell *//* *//* Revision History: *//* *//* 6.24: Removed DYNAMIC_SALIENCE and *//* LOGICAL_DEPENDENCIES compilation flags. *//* *//*************************************************************/#define _RULECMP_SOURCE_#include "setup.h"#if DEFRULE_CONSTRUCT && (! RUN_TIME) && CONSTRUCT_COMPILER#include <stdio.h>#define _STDIO_INCLUDED_#include <string.h>#include "envrnmnt.h"#include "factbld.h"#include "reteutil.h"#include "rulecmp.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static int ConstructToCode(void *,char *,int,FILE *,int,int); static void JoinToCode(void *,FILE *,struct joinNode *,int,int); static void LinkToCode(void *,FILE *,struct joinLink *,int,int); static void DefruleModuleToCode(void *,FILE *,struct defmodule *,int,int,int); static void DefruleToCode(void *,FILE *,struct defrule *,int,int,int); static void CloseDefruleFiles(void *,FILE *,FILE *,FILE *,FILE*,int); static void BeforeDefrulesCode(void *); static void InitDefruleCode(void *,FILE *,int,int); static int RuleCompilerTraverseJoins(void *,struct joinNode *,char *,int, FILE *,int,int,FILE **,FILE **, int *,int *,int *,int *,int *); static int TraverseJoinLinks(void *,struct joinLink *,char *,int,FILE *, int,int,FILE **,int *,int *, int *); /***********************************************************//* DefruleCompilerSetup: Initializes the defrule construct *//* for use with the constructs-to-c command. *//***********************************************************/globle void DefruleCompilerSetup( void *theEnv) { DefruleData(theEnv)->DefruleCodeItem = AddCodeGeneratorItem(theEnv,"defrules",0,BeforeDefrulesCode, InitDefruleCode,ConstructToCode,4); }/**************************************************************//* BeforeDefrulesCode: Assigns each defrule and join with a *//* unique ID which will be used for pointer references when *//* the data structures are written to a file as C code *//**************************************************************/static void BeforeDefrulesCode( void *theEnv) { long int moduleCount, ruleCount, joinCount, linkCount; TagRuleNetwork(theEnv,&moduleCount,&ruleCount,&joinCount, &linkCount); }/*********************************************************//* ConstructToCode: Produces defrule code for a run-time *//* module created using the constructs-to-c function. *//*********************************************************/static int ConstructToCode( void *theEnv, char *fileName, int fileID, FILE *headerFP, int imageID, int maxIndices) { int fileCount = 1; struct defmodule *theModule; struct defrule *theDefrule; int joinArrayCount = 0, joinArrayVersion = 1; int linkArrayCount = 0, linkArrayVersion = 1; int moduleCount = 0, moduleArrayCount = 0, moduleArrayVersion = 1; int defruleArrayCount = 0, defruleArrayVersion = 1; FILE *joinFile = NULL, *moduleFile = NULL, *defruleFile = NULL, *linkFile = NULL; /*==============================================*/ /* Include the appropriate defrule header file. */ /*==============================================*/ fprintf(headerFP,"#include \"ruledef.h\"\n"); /*======================================*/ /* Save the left and right prime links. */ /*======================================*/ if (! TraverseJoinLinks(theEnv,DefruleData(theEnv)->LeftPrimeJoins,fileName,fileID,headerFP,imageID, maxIndices,&linkFile,&fileCount,&linkArrayVersion,&linkArrayCount)) { CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices); return(0); } if (! TraverseJoinLinks(theEnv,DefruleData(theEnv)->RightPrimeJoins,fileName,fileID,headerFP,imageID, maxIndices,&linkFile,&fileCount,&linkArrayVersion,&linkArrayCount)) { CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices); return(0); } /*=========================================================*/ /* Loop through all the modules, all the defrules, and all */ /* the join nodes writing their C code representation to */ /* the file as they are traversed. */ /*=========================================================*/ for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL); theModule != NULL; theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule)) { /*=========================*/ /* Set the current module. */ /*=========================*/ EnvSetCurrentModule(theEnv,(void *) theModule); /*==========================*/ /* Save the defrule module. */ /*==========================*/ moduleFile = OpenFileIfNeeded(theEnv,moduleFile,fileName,fileID,imageID,&fileCount, moduleArrayVersion,headerFP, "struct defruleModule",ModulePrefix(DefruleData(theEnv)->DefruleCodeItem), FALSE,NULL); if (moduleFile == NULL) { CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices); return(0); } DefruleModuleToCode(theEnv,moduleFile,theModule,imageID,maxIndices,moduleCount); moduleFile = CloseFileIfNeeded(theEnv,moduleFile,&moduleArrayCount,&moduleArrayVersion, maxIndices,NULL,NULL); /*=========================================*/ /* Loop through all of the defrules (and */ /* their disjuncts) in the current module. */ /*=========================================*/ theDefrule = (struct defrule *) EnvGetNextDefrule(theEnv,NULL); while (theDefrule != NULL) { /*===================================*/ /* Save the defrule data structures. */ /*===================================*/ defruleFile = OpenFileIfNeeded(theEnv,defruleFile,fileName,fileID,imageID,&fileCount, defruleArrayVersion,headerFP, "struct defrule",ConstructPrefix(DefruleData(theEnv)->DefruleCodeItem), FALSE,NULL); if (defruleFile == NULL) { CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices); return(0); } DefruleToCode(theEnv,defruleFile,theDefrule,imageID,maxIndices, moduleCount); defruleArrayCount++; defruleFile = CloseFileIfNeeded(theEnv,defruleFile,&defruleArrayCount,&defruleArrayVersion, maxIndices,NULL,NULL); /*================================*/ /* Save the join data structures. */ /*================================*/ if (! RuleCompilerTraverseJoins(theEnv,theDefrule->lastJoin,fileName,fileID,headerFP,imageID, maxIndices,&joinFile,&linkFile,&fileCount,&joinArrayVersion,&joinArrayCount, &linkArrayVersion,&linkArrayCount)) { CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices); return(0); } /*==========================================*/ /* Move on to the next disjunct or defrule. */ /*==========================================*/ if (theDefrule->disjunct != NULL) theDefrule = theDefrule->disjunct; else theDefrule = (struct defrule *) EnvGetNextDefrule(theEnv,theDefrule); } moduleCount++; moduleArrayCount++; } CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices); return(1); }/*********************************************************************//* RuleCompilerTraverseJoins: Traverses the join network for a rule. *//*********************************************************************/static int RuleCompilerTraverseJoins( void *theEnv, struct joinNode *joinPtr, char *fileName, int fileID, FILE *headerFP, int imageID, int maxIndices, FILE **joinFile, FILE **linkFile, int *fileCount, int *joinArrayVersion, int *joinArrayCount, int *linkArrayVersion, int *linkArrayCount) { for (; joinPtr != NULL; joinPtr = joinPtr->lastLevel) { if (joinPtr->marked) { *joinFile = OpenFileIfNeeded(theEnv,*joinFile,fileName,fileID,imageID,fileCount, *joinArrayVersion,headerFP, "struct joinNode",JoinPrefix(),FALSE,NULL); if (*joinFile == NULL) { return(FALSE); } JoinToCode(theEnv,*joinFile,joinPtr,imageID,maxIndices); (*joinArrayCount)++; *joinFile = CloseFileIfNeeded(theEnv,*joinFile,joinArrayCount,joinArrayVersion, maxIndices,NULL,NULL); if (! TraverseJoinLinks(theEnv,joinPtr->nextLinks,fileName,fileID,headerFP,imageID, maxIndices,linkFile,fileCount,linkArrayVersion,linkArrayCount)) { return(FALSE); } } if (joinPtr->joinFromTheRight) { if (RuleCompilerTraverseJoins(theEnv,joinPtr->rightSideEntryStructure,fileName, fileID,headerFP,imageID,maxIndices,joinFile,linkFile,fileCount, joinArrayVersion,joinArrayCount, linkArrayVersion,linkArrayCount) == FALSE) { return(FALSE); } } } return(TRUE); }/*******************************************************//* TraverseJoinLinks: Writes out a list of join links. *//*******************************************************/static int TraverseJoinLinks( void *theEnv, struct joinLink *linkPtr, char *fileName, int fileID, FILE *headerFP, int imageID, int maxIndices, FILE **linkFile, int *fileCount, int *linkArrayVersion, int *linkArrayCount) { for (; linkPtr != NULL; linkPtr = linkPtr->next) { *linkFile = OpenFileIfNeeded(theEnv,*linkFile,fileName,fileID,imageID,fileCount, *linkArrayVersion,headerFP, "struct joinLink",LinkPrefix(),FALSE,NULL); if (*linkFile == NULL) { return(FALSE); } LinkToCode(theEnv,*linkFile,linkPtr,imageID,maxIndices); (*linkArrayCount)++; *linkFile = CloseFileIfNeeded(theEnv,*linkFile,linkArrayCount,linkArrayVersion, maxIndices,NULL,NULL); } return(TRUE); }/********************************************************//* CloseDefruleFiles: Closes all of the C files created *//* for defrule. Called when an error occurs or when *//* the defrules have all been written to the files. *//********************************************************/static void CloseDefruleFiles( void *theEnv, FILE *moduleFile, FILE *defruleFile, FILE *joinFile, FILE *linkFile, int maxIndices) { int count = maxIndices; int arrayVersion = 0; if (linkFile != NULL) { count = maxIndices; CloseFileIfNeeded(theEnv,linkFile,&count,&arrayVersion,maxIndices,NULL,NULL); } if (joinFile != NULL) { count = maxIndices; CloseFileIfNeeded(theEnv,joinFile,&count,&arrayVersion,maxIndices,NULL,NULL); } if (defruleFile != NULL) { count = maxIndices; CloseFileIfNeeded(theEnv,defruleFile,&count,&arrayVersion,maxIndices,NULL,NULL); } if (moduleFile != NULL) { count = maxIndices; CloseFileIfNeeded(theEnv,moduleFile,&count,&arrayVersion,maxIndices,NULL,NULL); } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -