00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define _INCRRSET_SOURCE_
00031
00032 #include "setup.h"
00033
00034 #include <stdio.h>
00035 #define _STDIO_INCLUDED_
00036
00037 #if DEFRULE_CONSTRUCT
00038
00039 #include "agenda.h"
00040 #include "argacces.h"
00041 #include "constant.h"
00042 #include "drive.h"
00043 #include "engine.h"
00044 #include "envrnmnt.h"
00045 #include "evaluatn.h"
00046 #include "pattern.h"
00047 #include "router.h"
00048 #include "reteutil.h"
00049
00050 #include "incrrset.h"
00051
00052
00053
00054
00055
00056 #if (! RUN_TIME) && (! BLOAD_ONLY)
00057 static void MarkNetworkForIncrementalReset(void *,struct defrule *,int);
00058 static void MarkJoinsForIncrementalReset(void *,struct joinNode *,int);
00059 static void CheckForPrimableJoins(void *,struct defrule *,struct joinNode *);
00060 static void PrimeJoinFromLeftMemory(void *,struct joinNode *);
00061 static void PrimeJoinFromRightMemory(void *,struct joinNode *);
00062 static void MarkPatternForIncrementalReset(void *,int,struct patternNodeHeader *,int);
00063 #endif
00064
00065
00066
00067
00068 globle void IncrementalReset(
00069 void *theEnv,
00070 struct defrule *tempRule)
00071 {
00072 #if (MAC_MCW || WIN_MCW) && (RUN_TIME || BLOAD_ONLY)
00073 #pragma unused(theEnv,tempRule)
00074 #endif
00075
00076 #if (! RUN_TIME) && (! BLOAD_ONLY)
00077 struct defrule *tempPtr;
00078 struct patternParser *theParser;
00079
00080
00081
00082
00083
00084 if (! EnvGetIncrementalReset(theEnv)) return;
00085
00086
00087
00088
00089
00090
00091 MarkNetworkForIncrementalReset(theEnv,tempRule,TRUE);
00092
00093
00094
00095
00096
00097 EngineData(theEnv)->IncrementalResetInProgress = TRUE;
00098
00099
00100
00101
00102
00103
00104
00105 for (tempPtr = tempRule;
00106 tempPtr != NULL;
00107 tempPtr = tempPtr->disjunct)
00108 { CheckForPrimableJoins(theEnv,tempPtr,tempPtr->lastJoin); }
00109
00110
00111
00112
00113
00114
00115 for (theParser = PatternData(theEnv)->ListOfPatternParsers;
00116 theParser != NULL;
00117 theParser = theParser->next)
00118 {
00119 if (theParser->incrementalResetFunction != NULL)
00120 { (*theParser->incrementalResetFunction)(theEnv); }
00121 }
00122
00123
00124
00125
00126
00127 EngineData(theEnv)->IncrementalResetInProgress = FALSE;
00128
00129
00130
00131
00132
00133 MarkNetworkForIncrementalReset(theEnv,tempRule,FALSE);
00134 #endif
00135 }
00136
00137 #if (! RUN_TIME) && (! BLOAD_ONLY)
00138
00139
00140
00141
00142
00143
00144 static void MarkNetworkForIncrementalReset(
00145 void *theEnv,
00146 struct defrule *tempRule,
00147 int value)
00148 {
00149
00150
00151
00152
00153 for (;
00154 tempRule != NULL;
00155 tempRule = tempRule->disjunct)
00156 { MarkJoinsForIncrementalReset(theEnv,tempRule->lastJoin,value); }
00157 }
00158
00159
00160
00161
00162
00163
00164 static void MarkJoinsForIncrementalReset(
00165 void *theEnv,
00166 struct joinNode *joinPtr,
00167 int value)
00168 {
00169 struct patternNodeHeader *patternPtr;
00170
00171 for (;
00172 joinPtr != NULL;
00173 joinPtr = joinPtr->lastLevel)
00174 {
00175 if (joinPtr->ruleToActivate != NULL)
00176 {
00177 joinPtr->marked = FALSE;
00178 joinPtr->initialize = value;
00179 continue;
00180 }
00181
00182 if (joinPtr->joinFromTheRight)
00183 { MarkJoinsForIncrementalReset(theEnv,(struct joinNode *) joinPtr->rightSideEntryStructure,value); }
00184
00185
00186
00187
00188
00189 joinPtr->marked = FALSE;
00190
00191 if (joinPtr->initialize)
00192 {
00193 joinPtr->initialize = value;
00194 if (joinPtr->joinFromTheRight == FALSE)
00195 {
00196 patternPtr = (struct patternNodeHeader *) GetPatternForJoin(joinPtr);
00197 if (patternPtr != NULL)
00198 { MarkPatternForIncrementalReset(theEnv,(int) joinPtr->rhsType,patternPtr,value); }
00199 }
00200 }
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 static void CheckForPrimableJoins(
00213 void *theEnv,
00214 struct defrule *tempRule,
00215 struct joinNode *joinPtr)
00216 {
00217
00218
00219
00220
00221 for (;
00222 joinPtr != NULL;
00223 joinPtr = joinPtr->lastLevel)
00224 {
00225
00226
00227
00228
00229 if ((joinPtr->initialize) && (! joinPtr->marked))
00230 {
00231 if (joinPtr->firstJoin == TRUE)
00232 {
00233 if (joinPtr->joinFromTheRight == FALSE)
00234 {
00235 if ((joinPtr->rightSideEntryStructure == NULL) ||
00236 (joinPtr->patternIsNegated) ||
00237 (((struct patternNodeHeader *) joinPtr->rightSideEntryStructure)->initialize == FALSE))
00238 {
00239 PrimeJoinFromLeftMemory(theEnv,joinPtr);
00240 joinPtr->marked = TRUE;
00241 }
00242 }
00243 else
00244 {
00245 PrimeJoinFromRightMemory(theEnv,joinPtr);
00246 joinPtr->marked = TRUE;
00247 }
00248 }
00249 else if (joinPtr->lastLevel->initialize == FALSE)
00250 {
00251 PrimeJoinFromLeftMemory(theEnv,joinPtr);
00252 joinPtr->marked = TRUE;
00253 }
00254 else if ((joinPtr->joinFromTheRight) &&
00255 (((struct joinNode *) joinPtr->rightSideEntryStructure)->initialize == FALSE))
00256 {
00257 PrimeJoinFromRightMemory(theEnv,joinPtr);
00258 joinPtr->marked = TRUE;
00259 }
00260 }
00261
00262 if (joinPtr->joinFromTheRight)
00263 { CheckForPrimableJoins(theEnv,tempRule,(struct joinNode *) joinPtr->rightSideEntryStructure); }
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 static void PrimeJoinFromLeftMemory(
00276 void *theEnv,
00277 struct joinNode *joinPtr)
00278 {
00279 struct partialMatch *theList, *linker;
00280 struct alphaMemoryHash *listOfHashNodes;
00281 unsigned long b;
00282 unsigned long hashValue;
00283 struct betaMemory *theMemory;
00284 struct partialMatch *notParent;
00285 struct joinLink *tempLink;
00286
00287
00288
00289
00290
00291
00292
00293
00294 if (joinPtr->firstJoin == TRUE)
00295 {
00296 if (joinPtr->rightSideEntryStructure == NULL)
00297 { NetworkAssert(theEnv,joinPtr->rightMemory->beta[0],joinPtr); }
00298 else if (joinPtr->patternIsNegated)
00299 {
00300 notParent = joinPtr->leftMemory->beta[0];
00301
00302 if (joinPtr->secondaryNetworkTest != NULL)
00303 {
00304 if (EvaluateSecondaryNetworkTest(theEnv,notParent,joinPtr) == FALSE)
00305 { return; }
00306 }
00307
00308 for (listOfHashNodes = ((struct patternNodeHeader *) joinPtr->rightSideEntryStructure)->firstHash;
00309 listOfHashNodes != NULL;
00310 listOfHashNodes = listOfHashNodes->nextHash)
00311 {
00312 if (listOfHashNodes->alphaMemory != NULL)
00313 {
00314 AddBlockedLink(notParent,listOfHashNodes->alphaMemory);
00315 return;
00316 }
00317 }
00318
00319 EPMDrive(theEnv,notParent,joinPtr);
00320 }
00321 else
00322 {
00323 for (listOfHashNodes = ((struct patternNodeHeader *) joinPtr->rightSideEntryStructure)->firstHash;
00324 listOfHashNodes != NULL;
00325 listOfHashNodes = listOfHashNodes->nextHash)
00326 {
00327 for (theList = listOfHashNodes->alphaMemory;
00328 theList != NULL;
00329 theList = theList->nextInMemory)
00330 { NetworkAssert(theEnv,theList,joinPtr); }
00331 }
00332 }
00333 return;
00334 }
00335
00336
00337
00338
00339
00340
00341 tempLink = joinPtr->lastLevel->nextLinks;
00342
00343 while (tempLink != NULL)
00344 {
00345 if ((tempLink->join != joinPtr) &&
00346 (tempLink->join->initialize == FALSE))
00347 { break; }
00348
00349 tempLink = tempLink->next;
00350 }
00351
00352 if (tempLink == NULL) return;
00353
00354 if (tempLink->enterDirection == LHS)
00355 { theMemory = tempLink->join->leftMemory; }
00356 else
00357 { theMemory = tempLink->join->rightMemory; }
00358
00359
00360
00361
00362
00363
00364 for (b = 0; b < theMemory->size; b++)
00365 {
00366 for (theList = theMemory->beta[b];
00367 theList != NULL;
00368 theList = theList->nextInMemory)
00369 {
00370 linker = CopyPartialMatch(theEnv,theList);
00371
00372 if (joinPtr->leftHash != NULL)
00373 { hashValue = BetaMemoryHashValue(theEnv,joinPtr->leftHash,linker,NULL,joinPtr); }
00374 else
00375 { hashValue = 0; }
00376
00377 UpdateBetaPMLinks(theEnv,linker,theList->leftParent,theList->rightParent,joinPtr,hashValue,LHS);
00378
00379 NetworkAssertLeft(theEnv,linker,joinPtr);
00380 }
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 static void PrimeJoinFromRightMemory(
00393 void *theEnv,
00394 struct joinNode *joinPtr)
00395 {
00396 struct partialMatch *theList, *linker;
00397 unsigned long b;
00398 struct betaMemory *theMemory;
00399 unsigned long hashValue;
00400 struct joinLink *tempLink;
00401 struct partialMatch *notParent;
00402
00403
00404
00405
00406
00407 if (joinPtr->joinFromTheRight == FALSE)
00408 { return; }
00409
00410
00411
00412
00413
00414
00415 tempLink = ((struct joinNode *) joinPtr->rightSideEntryStructure)->nextLinks;
00416 while (tempLink != NULL)
00417 {
00418 if ((tempLink->join != joinPtr) &&
00419 (tempLink->join->initialize == FALSE))
00420 { break; }
00421
00422 tempLink = tempLink->next;
00423 }
00424
00425 if (tempLink == NULL)
00426 {
00427 if (joinPtr->firstJoin &&
00428 (joinPtr->rightMemory->beta[0] == NULL) &&
00429 (! joinPtr->patternIsExists))
00430 {
00431 notParent = joinPtr->leftMemory->beta[0];
00432
00433 if (joinPtr->secondaryNetworkTest != NULL)
00434 {
00435 if (EvaluateSecondaryNetworkTest(theEnv,notParent,joinPtr) == FALSE)
00436 { return; }
00437 }
00438
00439 EPMDrive(theEnv,notParent,joinPtr);
00440 }
00441
00442 return;
00443 }
00444
00445 if (tempLink->enterDirection == LHS)
00446 { theMemory = tempLink->join->leftMemory; }
00447 else
00448 { theMemory = tempLink->join->rightMemory; }
00449
00450
00451
00452
00453
00454
00455 for (b = 0; b < theMemory->size; b++)
00456 {
00457 for (theList = theMemory->beta[b];
00458 theList != NULL;
00459 theList = theList->nextInMemory)
00460 {
00461 linker = CopyPartialMatch(theEnv,theList);
00462
00463 if (joinPtr->rightHash != NULL)
00464 { hashValue = BetaMemoryHashValue(theEnv,joinPtr->rightHash,linker,NULL,joinPtr); }
00465 else
00466 { hashValue = 0; }
00467
00468 UpdateBetaPMLinks(theEnv,linker,theList->leftParent,theList->rightParent,joinPtr,hashValue,RHS);
00469 NetworkAssert(theEnv,linker,joinPtr);
00470 }
00471 }
00472
00473 if (joinPtr->firstJoin &&
00474 (joinPtr->rightMemory->beta[0] == NULL) &&
00475 (! joinPtr->patternIsExists))
00476 {
00477 notParent = joinPtr->leftMemory->beta[0];
00478
00479 if (joinPtr->secondaryNetworkTest != NULL)
00480 {
00481 if (EvaluateSecondaryNetworkTest(theEnv,notParent,joinPtr) == FALSE)
00482 { return; }
00483 }
00484
00485 EPMDrive(theEnv,notParent,joinPtr);
00486 }
00487 }
00488
00489
00490
00491
00492
00493
00494
00495 static void MarkPatternForIncrementalReset(
00496 void *theEnv,
00497 int rhsType,
00498 struct patternNodeHeader *theHeader,
00499 int value)
00500 {
00501 struct patternParser *tempParser;
00502
00503 tempParser = GetPatternParser(theEnv,rhsType);
00504
00505 if (tempParser != NULL)
00506 {
00507 if (tempParser->markIRPatternFunction != NULL)
00508 { (*tempParser->markIRPatternFunction)(theEnv,theHeader,value); }
00509 }
00510 }
00511
00512 #endif
00513
00514
00515
00516
00517
00518 globle intBool EnvGetIncrementalReset(
00519 void *theEnv)
00520 {
00521 return(EngineData(theEnv)->IncrementalResetFlag);
00522 }
00523
00524
00525
00526
00527
00528 globle intBool EnvSetIncrementalReset(
00529 void *theEnv,
00530 int value)
00531 {
00532 int ov;
00533 struct defmodule *theModule;
00534
00535 SaveCurrentModule(theEnv);
00536
00537 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
00538 theModule != NULL;
00539 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
00540 {
00541 EnvSetCurrentModule(theEnv,(void *) theModule);
00542 if (EnvGetNextDefrule(theEnv,NULL) != NULL)
00543 {
00544 RestoreCurrentModule(theEnv);
00545 return(-1);
00546 }
00547 }
00548
00549 RestoreCurrentModule(theEnv);
00550
00551 ov = EngineData(theEnv)->IncrementalResetFlag;
00552 EngineData(theEnv)->IncrementalResetFlag = value;
00553 return(ov);
00554 }
00555
00556
00557
00558
00559
00560 globle int SetIncrementalResetCommand(
00561 void *theEnv)
00562 {
00563 int oldValue;
00564 DATA_OBJECT argPtr;
00565 struct defmodule *theModule;
00566
00567 oldValue = EnvGetIncrementalReset(theEnv);
00568
00569
00570
00571
00572
00573 if (EnvArgCountCheck(theEnv,"set-incremental-reset",EXACTLY,1) == -1)
00574 { return(oldValue); }
00575
00576
00577
00578
00579
00580
00581 SaveCurrentModule(theEnv);
00582
00583 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
00584 theModule != NULL;
00585 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
00586 {
00587 EnvSetCurrentModule(theEnv,(void *) theModule);
00588 if (EnvGetNextDefrule(theEnv,NULL) != NULL)
00589 {
00590 RestoreCurrentModule(theEnv);
00591 PrintErrorID(theEnv,"INCRRSET",1,FALSE);
00592 EnvPrintRouter(theEnv,WERROR,"The incremental reset behavior cannot be changed with rules loaded.\n");
00593 SetEvaluationError(theEnv,TRUE);
00594 return(oldValue);
00595 }
00596 }
00597
00598 RestoreCurrentModule(theEnv);
00599
00600
00601
00602
00603
00604
00605 EnvRtnUnknown(theEnv,1,&argPtr);
00606
00607 if ((argPtr.value == EnvFalseSymbol(theEnv)) && (argPtr.type == SYMBOL))
00608 { EnvSetIncrementalReset(theEnv,FALSE); }
00609 else
00610 { EnvSetIncrementalReset(theEnv,TRUE); }
00611
00612
00613
00614
00615
00616 return(oldValue);
00617 }
00618
00619
00620
00621
00622
00623 globle int GetIncrementalResetCommand(
00624 void *theEnv)
00625 {
00626 int oldValue;
00627
00628 oldValue = EnvGetIncrementalReset(theEnv);
00629
00630 if (EnvArgCountCheck(theEnv,"get-incremental-reset",EXACTLY,0) == -1)
00631 { return(oldValue); }
00632
00633 return(oldValue);
00634 }
00635
00636 #endif