/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.40 07/02/18 */ /* */ /* DEFRULE BASIC COMMANDS HEADER FILE */ /*******************************************************/ /*************************************************************/ /* Purpose: Implements core commands for the defrule */ /* construct such as clear, reset, save, undefrule, */ /* ppdefrule, list-defrules, and */ /* get-defrule-list. */ /* */ /* Principal Programmer(s): */ /* Gary D. Riley */ /* */ /* Contributing Programmer(s): */ /* Brian L. Dantes */ /* */ /* Revision History: */ /* */ /* 6.23: Corrected compilation errors for files */ /* generated by constructs-to-c. DR0861 */ /* */ /* Changed name of variable log to logName */ /* because of Unix compiler warnings of shadowed */ /* definitions. */ /* */ /* 6.24: Renamed BOOLEAN macro type to intBool. */ /* */ /* 6.30: Removed conditional code for unsupported */ /* compilers/operating systems (IBM_MCW, */ /* MAC_MCW, and IBM_TBC). */ /* */ /* Support for join network changes. */ /* */ /* Added const qualifiers to remove C++ */ /* deprecation warnings. */ /* */ /* Converted API macros to function calls. */ /* */ /* Added code to prevent a clear command from */ /* being executed during fact assertions via */ /* JoinOperationInProgress mechanism. */ /* */ /* 6.40: Pragma once and other inclusion changes. */ /* */ /* Added support for booleans with . */ /* */ /* Removed use of void pointers for specific */ /* data structures. */ /* */ /* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */ /* */ /* UDF redesign. */ /* */ /* Pretty print functions accept optional logical */ /* name argument. */ /* */ /*************************************************************/ #include "setup.h" #if DEFRULE_CONSTRUCT #include #include "argacces.h" #include "constrct.h" #include "drive.h" #include "engine.h" #include "envrnmnt.h" #include "extnfunc.h" #include "multifld.h" #include "reteutil.h" #include "router.h" #include "ruledef.h" #include "watch.h" #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE #include "rulebin.h" #endif #if CONSTRUCT_COMPILER && (! RUN_TIME) #include "rulecmp.h" #endif #include "rulebsc.h" /***************************************/ /* LOCAL INTERNAL FUNCTION DEFINITIONS */ /***************************************/ static void ResetDefrules(Environment *,void *); static void ResetDefrulesPrime(Environment *,void *); static void SaveDefrules(Environment *,Defmodule *,const char *,void *); #if (! RUN_TIME) static bool ClearDefrulesReady(Environment *,void *); static void ClearDefrules(Environment *,void *); #endif /*************************************************************/ /* DefruleBasicCommands: Initializes basic defrule commands. */ /*************************************************************/ void DefruleBasicCommands( Environment *theEnv) { AddResetFunction(theEnv,"defrule",ResetDefrules,70,NULL); AddResetFunction(theEnv,"defrule",ResetDefrulesPrime,10,NULL); AddSaveFunction(theEnv,"defrule",SaveDefrules,0,NULL); #if (! RUN_TIME) AddClearReadyFunction(theEnv,"defrule",ClearDefrulesReady,0,NULL); AddClearFunction(theEnv,"defrule",ClearDefrules,0,NULL); #endif #if DEBUGGING_FUNCTIONS AddWatchItem(theEnv,"rules",0,&DefruleData(theEnv)->WatchRules,70,DefruleWatchAccess,DefruleWatchPrint); #endif #if ! RUN_TIME AddUDF(theEnv,"get-defrule-list","m",0,1,"y",GetDefruleListFunction,"GetDefruleListFunction",NULL); AddUDF(theEnv,"undefrule","v",1,1,"y",UndefruleCommand,"UndefruleCommand",NULL); AddUDF(theEnv,"defrule-module","y",1,1,"y",DefruleModuleFunction,"DefruleModuleFunction",NULL); #if DEBUGGING_FUNCTIONS AddUDF(theEnv,"rules","v",0,1,"y",ListDefrulesCommand,"ListDefrulesCommand",NULL); AddUDF(theEnv,"list-defrules","v",0,1,"y",ListDefrulesCommand,"ListDefrulesCommand",NULL); AddUDF(theEnv,"ppdefrule","vs",1,2,";y;ldsyn",PPDefruleCommand,"PPDefruleCommand",NULL); #endif #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) DefruleBinarySetup(theEnv); #endif #if CONSTRUCT_COMPILER && (! RUN_TIME) DefruleCompilerSetup(theEnv); #endif #endif } /*****************************************************/ /* ResetDefrules: Defrule reset routine for use with */ /* the reset command. Sets the current entity time */ /* tag (used by the conflict resolution strategies */ /* for recency) to zero. The focus stack is also */ /* cleared. */ /*****************************************************/ static void ResetDefrules( Environment *theEnv, void *context) { Defmodule *theModule; struct joinLink *theLink; struct partialMatch *notParent; DefruleData(theEnv)->CurrentEntityTimeTag = 1L; ClearFocusStack(theEnv); theModule = FindDefmodule(theEnv,"MAIN"); Focus(theModule); for (theLink = DefruleData(theEnv)->RightPrimeJoins; theLink != NULL; theLink = theLink->next) { PosEntryRetractAlpha(theEnv,theLink->join->rightMemory->beta[0],NETWORK_ASSERT); } for (theLink = DefruleData(theEnv)->LeftPrimeJoins; theLink != NULL; theLink = theLink->next) { if ((theLink->join->patternIsNegated || theLink->join->joinFromTheRight) && (! theLink->join->patternIsExists)) { notParent = theLink->join->leftMemory->beta[0]; if (notParent->marker) { RemoveBlockedLink(notParent); } /*==========================================================*/ /* Prevent any retractions from generating partial matches. */ /*==========================================================*/ notParent->marker = notParent; if (notParent->children != NULL) { PosEntryRetractBeta(theEnv,notParent,notParent->children,NETWORK_ASSERT); } /* if (notParent->dependents != NULL) { RemoveLogicalSupport(theEnv,notParent); } */ } } } /***********************/ /* ResetDefrulesPrime: */ /***********************/ static void ResetDefrulesPrime( Environment *theEnv, void *context) { struct joinLink *theLink; struct partialMatch *notParent; for (theLink = DefruleData(theEnv)->RightPrimeJoins; theLink != NULL; theLink = theLink->next) { NetworkAssert(theEnv,theLink->join->rightMemory->beta[0],theLink->join); } for (theLink = DefruleData(theEnv)->LeftPrimeJoins; theLink != NULL; theLink = theLink->next) { if ((theLink->join->patternIsNegated || theLink->join->joinFromTheRight) && (! theLink->join->patternIsExists)) { notParent = theLink->join->leftMemory->beta[0]; if (theLink->join->secondaryNetworkTest != NULL) { if (EvaluateSecondaryNetworkTest(theEnv,notParent,theLink->join) == false) { continue; } } notParent->marker = NULL; EPMDrive(theEnv,notParent,theLink->join,NETWORK_ASSERT); } } } #if (! RUN_TIME) /******************************************************************/ /* ClearDefrulesReady: Indicates whether defrules can be cleared. */ /******************************************************************/ static bool ClearDefrulesReady( Environment *theEnv, void *context) { if (EngineData(theEnv)->ExecutingRule != NULL) return false; if (EngineData(theEnv)->JoinOperationInProgress) return false; ClearFocusStack(theEnv); if (GetCurrentModule(theEnv) == NULL) return false; DefruleData(theEnv)->CurrentEntityTimeTag = 1L; return true; } /***************************************************************/ /* ClearDefrules: Pushes the MAIN module as the current focus. */ /***************************************************************/ static void ClearDefrules( Environment *theEnv, void *context) { Defmodule *theModule; theModule = FindDefmodule(theEnv,"MAIN"); Focus(theModule); } #endif /**************************************/ /* SaveDefrules: Defrule save routine */ /* for use with the save command. */ /**************************************/ static void SaveDefrules( Environment *theEnv, Defmodule *theModule, const char *logicalName, void *context) { SaveConstruct(theEnv,theModule,logicalName,DefruleData(theEnv)->DefruleConstruct); } /******************************************/ /* UndefruleCommand: H/L access routine */ /* for the undefrule command. */ /******************************************/ void UndefruleCommand( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { UndefconstructCommand(context,"undefrule",DefruleData(theEnv)->DefruleConstruct); } /********************************/ /* Undefrule: C access routine */ /* for the undefrule command. */ /********************************/ bool Undefrule( Defrule *theDefrule, Environment *allEnv) { Environment *theEnv; if (theDefrule == NULL) { theEnv = allEnv; return Undefconstruct(theEnv,NULL,DefruleData(theEnv)->DefruleConstruct); } else { theEnv = theDefrule->header.env; return Undefconstruct(theEnv,&theDefrule->header,DefruleData(theEnv)->DefruleConstruct); } } /************************************************/ /* GetDefruleListFunction: H/L access routine */ /* for the get-defrule-list function. */ /************************************************/ void GetDefruleListFunction( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { GetConstructListFunction(context,returnValue,DefruleData(theEnv)->DefruleConstruct); } /****************************************/ /* GetDefruleList: C access routine */ /* for the get-defrule-list function. */ /****************************************/ void GetDefruleList( Environment *theEnv, CLIPSValue *returnValue, Defmodule *theModule) { UDFValue result; GetConstructList(theEnv,&result,DefruleData(theEnv)->DefruleConstruct,theModule); NormalizeMultifield(theEnv,&result); returnValue->value = result.value; } /*********************************************/ /* DefruleModuleFunction: H/L access routine */ /* for the defrule-module function. */ /*********************************************/ void DefruleModuleFunction( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { returnValue->value = GetConstructModuleCommand(context,"defrule-module",DefruleData(theEnv)->DefruleConstruct); } #if DEBUGGING_FUNCTIONS /******************************************/ /* PPDefruleCommand: H/L access routine */ /* for the ppdefrule command. */ /******************************************/ void PPDefruleCommand( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { PPConstructCommand(context,"ppdefrule",DefruleData(theEnv)->DefruleConstruct,returnValue); } /***********************************/ /* PPDefrule: C access routine for */ /* the ppdefrule command. */ /***********************************/ bool PPDefrule( Environment *theEnv, const char *defruleName, const char *logicalName) { return(PPConstruct(theEnv,defruleName,logicalName,DefruleData(theEnv)->DefruleConstruct)); } /*********************************************/ /* ListDefrulesCommand: H/L access routine */ /* for the list-defrules command. */ /*********************************************/ void ListDefrulesCommand( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { ListConstructCommand(context,DefruleData(theEnv)->DefruleConstruct); } /************************************/ /* ListDefrules: C access routine */ /* for the list-defrules command. */ /************************************/ void ListDefrules( Environment *theEnv, const char *logicalName, Defmodule *theModule) { ListConstruct(theEnv,DefruleData(theEnv)->DefruleConstruct,logicalName,theModule); } /*******************************************************/ /* DefruleGetWatchActivations: C access routine for */ /* retrieving the current watch value of a defrule's */ /* activations. */ /*******************************************************/ bool DefruleGetWatchActivations( Defrule *rulePtr) { Defrule *thePtr; for (thePtr = rulePtr; thePtr != NULL; thePtr = thePtr->disjunct) { if (thePtr->watchActivation) return true; } return false; } /********************************************/ /* DefruleGetWatchFirings: C access routine */ /* for retrieving the current watch value */ /* of a defrule's firings. */ /********************************************/ bool DefruleGetWatchFirings( Defrule *rulePtr) { Defrule *thePtr; for (thePtr = rulePtr; thePtr != NULL; thePtr = thePtr->disjunct) { if (thePtr->watchFiring) return true; } return false; } /************************************************/ /* DefruleSetWatchActivations: C access routine */ /* for setting the current watch value of a */ /* defrule's activations. */ /************************************************/ void DefruleSetWatchActivations( Defrule *rulePtr, bool newState) { Defrule *thePtr; for (thePtr = rulePtr; thePtr != NULL; thePtr = thePtr->disjunct) { thePtr->watchActivation = newState; } } /********************************************/ /* DefruleSetWatchFirings: C access routine */ /* for setting the current watch value of */ /* a defrule's firings. */ /********************************************/ void DefruleSetWatchFirings( Defrule *rulePtr, bool newState) { Defrule *thePtr; for (thePtr = rulePtr; thePtr != NULL; thePtr = thePtr->disjunct) { thePtr->watchFiring = newState; } } /*******************************************************************/ /* DefruleWatchAccess: Access function for setting the watch flags */ /* associated with rules (activations and rule firings). */ /*******************************************************************/ bool DefruleWatchAccess( Environment *theEnv, int code, bool newState, struct expr *argExprs) { if (code) return(ConstructSetWatchAccess(theEnv,DefruleData(theEnv)->DefruleConstruct,newState,argExprs, (ConstructGetWatchFunction *) DefruleGetWatchActivations, (ConstructSetWatchFunction *) DefruleSetWatchActivations)); else return(ConstructSetWatchAccess(theEnv,DefruleData(theEnv)->DefruleConstruct,newState,argExprs, (ConstructGetWatchFunction *) DefruleGetWatchFirings, (ConstructSetWatchFunction *) DefruleSetWatchFirings)); } /*****************************************************************/ /* DefruleWatchPrint: Access routine for printing which defrules */ /* have their watch flag set via the list-watch-items command. */ /*****************************************************************/ bool DefruleWatchPrint( Environment *theEnv, const char *logName, int code, struct expr *argExprs) { if (code) return(ConstructPrintWatchAccess(theEnv,DefruleData(theEnv)->DefruleConstruct,logName,argExprs, (ConstructGetWatchFunction *) DefruleGetWatchActivations, (ConstructSetWatchFunction *) DefruleSetWatchActivations)); else return(ConstructPrintWatchAccess(theEnv,DefruleData(theEnv)->DefruleConstruct,logName,argExprs, (ConstructGetWatchFunction *) DefruleGetWatchActivations, (ConstructSetWatchFunction *) DefruleGetWatchActivations)); } #endif /* DEBUGGING_FUNCTIONS */ #endif /* DEFTEMPLATE_CONSTRUCT */