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
00031 #define _RETEUTIL_SOURCE_
00032
00033 #include <stdio.h>
00034 #define _STDIO_INCLUDED_
00035
00036 #include "setup.h"
00037
00038 #if DEFRULE_CONSTRUCT
00039
00040 #include "drive.h"
00041 #include "engine.h"
00042 #include "envrnmnt.h"
00043 #include "incrrset.h"
00044 #include "match.h"
00045 #include "memalloc.h"
00046 #include "moduldef.h"
00047 #include "pattern.h"
00048 #include "retract.h"
00049 #include "router.h"
00050
00051 #include "reteutil.h"
00052
00053
00054
00055
00056
00057 static void TraceErrorToRuleDriver(void *,struct joinNode *,char *,int,int);
00058 static struct alphaMemoryHash *FindAlphaMemory(void *,struct patternNodeHeader *,unsigned long);
00059 static unsigned long AlphaMemoryHashValue(struct patternNodeHeader *,unsigned long);
00060 static void UnlinkAlphaMemory(void *,struct patternNodeHeader *,struct alphaMemoryHash *);
00061 static void UnlinkAlphaMemoryBucketSiblings(void *,struct alphaMemoryHash *);
00062 static void InitializePMLinks(struct partialMatch *);
00063 static void UnlinkBetaPartialMatchfromAlphaAndBetaLineage(struct partialMatch *);
00064 static int CountPriorPatterns(struct joinNode *);
00065 static void ResizeBetaMemory(void *,struct betaMemory *);
00066 static void ResetBetaMemory(void *,struct betaMemory *);
00067 #if (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME)
00068 static void TagNetworkTraverseJoins(void *,long int *,long int *,struct joinNode *);
00069 #endif
00070
00071
00072
00073
00074
00075
00076 globle void PrintPartialMatch(
00077 void *theEnv,
00078 char *logicalName,
00079 struct partialMatch *list)
00080 {
00081 struct patternEntity *matchingItem;
00082 unsigned short i;
00083
00084 for (i = 0; i < list->bcount;)
00085 {
00086 if ((get_nth_pm_match(list,i) != NULL) &&
00087 (get_nth_pm_match(list,i)->matchingItem != NULL))
00088 {
00089 matchingItem = get_nth_pm_match(list,i)->matchingItem;
00090 (*matchingItem->theInfo->base.shortPrintFunction)(theEnv,logicalName,matchingItem);
00091 }
00092 else
00093 { EnvPrintRouter(theEnv,logicalName,"*"); }
00094 i++;
00095 if (i < list->bcount) EnvPrintRouter(theEnv,logicalName,",");
00096 }
00097 }
00098
00099
00100
00101
00102 globle struct partialMatch *CopyPartialMatch(
00103 void *theEnv,
00104 struct partialMatch *list)
00105 {
00106 struct partialMatch *linker;
00107 unsigned short i;
00108
00109 linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) *
00110 (list->bcount - 1));
00111
00112 InitializePMLinks(linker);
00113 linker->betaMemory = TRUE;
00114 linker->busy = FALSE;
00115 linker->rhsMemory = FALSE;
00116 linker->bcount = list->bcount;
00117 linker->hashValue = 0;
00118
00119 for (i = 0; i < linker->bcount; i++) linker->binds[i] = list->binds[i];
00120
00121 return(linker);
00122 }
00123
00124
00125
00126
00127 globle struct partialMatch *CreateEmptyPartialMatch(
00128 void *theEnv)
00129 {
00130 struct partialMatch *linker;
00131
00132 linker = get_struct(theEnv,partialMatch);
00133
00134 InitializePMLinks(linker);
00135 linker->betaMemory = TRUE;
00136 linker->busy = FALSE;
00137 linker->rhsMemory = FALSE;
00138 linker->bcount = 1;
00139 linker->hashValue = 0;
00140 linker->binds[0].gm.theValue = NULL;
00141
00142 return(linker);
00143 }
00144
00145
00146
00147
00148 static void InitializePMLinks(
00149 struct partialMatch *theMatch)
00150 {
00151 theMatch->nextInMemory = NULL;
00152 theMatch->prevInMemory = NULL;
00153 theMatch->nextRightChild = NULL;
00154 theMatch->prevRightChild = NULL;
00155 theMatch->nextLeftChild = NULL;
00156 theMatch->prevLeftChild = NULL;
00157 theMatch->children = NULL;
00158 theMatch->rightParent = NULL;
00159 theMatch->leftParent = NULL;
00160 theMatch->blockList = NULL;
00161 theMatch->nextBlocked = NULL;
00162 theMatch->prevBlocked = NULL;
00163 theMatch->marker = NULL;
00164 theMatch->dependents = NULL;
00165 }
00166
00167
00168
00169
00170 globle void UpdateBetaPMLinks(
00171 void *theEnv,
00172 struct partialMatch *thePM,
00173 struct partialMatch *lhsBinds,
00174 struct partialMatch *rhsBinds,
00175 struct joinNode *join,
00176 unsigned long hashValue,
00177 int side)
00178 {
00179 unsigned long betaLocation;
00180 struct betaMemory *theMemory;
00181
00182 if (side == LHS)
00183 {
00184 theMemory = join->leftMemory;
00185 thePM->rhsMemory = FALSE;
00186 }
00187 else
00188 {
00189 theMemory = join->rightMemory;
00190 thePM->rhsMemory = TRUE;
00191 }
00192
00193 thePM->hashValue = hashValue;
00194
00195
00196
00197
00198
00199 betaLocation = hashValue % theMemory->size;
00200
00201 if (side == LHS)
00202 {
00203 thePM->nextInMemory = theMemory->beta[betaLocation];
00204 if (theMemory->beta[betaLocation] != NULL)
00205 { theMemory->beta[betaLocation]->prevInMemory = thePM; }
00206 theMemory->beta[betaLocation] = thePM;
00207 }
00208 else
00209 {
00210 if (theMemory->last[betaLocation] != NULL)
00211 {
00212 theMemory->last[betaLocation]->nextInMemory = thePM;
00213 thePM->prevInMemory = theMemory->last[betaLocation];
00214 }
00215 else
00216 { theMemory->beta[betaLocation] = thePM; }
00217
00218 theMemory->last[betaLocation] = thePM;
00219 }
00220
00221 theMemory->count++;
00222 join->memoryAdds++;
00223
00224 thePM->owner = join;
00225
00226
00227
00228
00229
00230 if (rhsBinds != NULL)
00231 {
00232 thePM->nextRightChild = rhsBinds->children;
00233 if (rhsBinds->children != NULL)
00234 { rhsBinds->children->prevRightChild = thePM; }
00235 rhsBinds->children = thePM;
00236 thePM->rightParent = rhsBinds;
00237 }
00238
00239
00240
00241
00242
00243 if (lhsBinds != NULL)
00244 {
00245 thePM->nextLeftChild = lhsBinds->children;
00246 if (lhsBinds->children != NULL)
00247 { lhsBinds->children->prevLeftChild = thePM; }
00248 lhsBinds->children = thePM;
00249 thePM->leftParent = lhsBinds;
00250 }
00251
00252 if (! DefruleData(theEnv)->BetaMemoryResizingFlag)
00253 { return; }
00254
00255 if ((theMemory->size > 1) &&
00256 (theMemory->count > (theMemory->size * 11)))
00257 { ResizeBetaMemory(theEnv,theMemory); }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267 globle void AddBlockedLink(
00268 struct partialMatch *thePM,
00269 struct partialMatch *rhsBinds)
00270 {
00271 thePM->marker = rhsBinds;
00272 thePM->nextBlocked = rhsBinds->blockList;
00273 if (rhsBinds->blockList != NULL)
00274 { rhsBinds->blockList->prevBlocked = thePM; }
00275 rhsBinds->blockList = thePM;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285 globle void RemoveBlockedLink(
00286 struct partialMatch *thePM)
00287 {
00288 struct partialMatch *blocker;
00289
00290 if (thePM->prevBlocked == NULL)
00291 {
00292 blocker = (struct partialMatch *) thePM->marker;
00293 blocker->blockList = thePM->nextBlocked;
00294 }
00295 else
00296 { thePM->prevBlocked->nextBlocked = thePM->nextBlocked; }
00297
00298 if (thePM->nextBlocked != NULL)
00299 { thePM->nextBlocked->prevBlocked = thePM->prevBlocked; }
00300
00301 thePM->nextBlocked = NULL;
00302 thePM->prevBlocked = NULL;
00303 thePM->marker = NULL;
00304 }
00305
00306
00307
00308
00309 globle void UnlinkBetaPMFromNodeAndLineage(
00310 void *theEnv,
00311 struct joinNode *join,
00312 struct partialMatch *thePM,
00313 int side)
00314 {
00315 unsigned long betaLocation;
00316 struct betaMemory *theMemory;
00317
00318 if (side == LHS)
00319 { theMemory = join->leftMemory; }
00320 else
00321 { theMemory = join->rightMemory; }
00322
00323
00324
00325
00326
00327 theMemory->count--;
00328 join->memoryDeletes++;
00329
00330 betaLocation = thePM->hashValue % theMemory->size;
00331
00332 if ((side == RHS) &&
00333 (theMemory->last[betaLocation] == thePM))
00334 { theMemory->last[betaLocation] = thePM->prevInMemory; }
00335
00336 if (thePM->prevInMemory == NULL)
00337 {
00338 betaLocation = thePM->hashValue % theMemory->size;
00339 theMemory->beta[betaLocation] = thePM->nextInMemory;
00340 }
00341 else
00342 { thePM->prevInMemory->nextInMemory = thePM->nextInMemory; }
00343
00344 if (thePM->nextInMemory != NULL)
00345 { thePM->nextInMemory->prevInMemory = thePM->prevInMemory; }
00346
00347 thePM->nextInMemory = NULL;
00348 thePM->prevInMemory = NULL;
00349
00350 UnlinkBetaPartialMatchfromAlphaAndBetaLineage(thePM);
00351
00352 if (! DefruleData(theEnv)->BetaMemoryResizingFlag)
00353 { return; }
00354
00355 if ((theMemory->count == 0) && (theMemory->size > 1))
00356 { ResetBetaMemory(theEnv,theMemory); }
00357 }
00358
00359
00360
00361
00362 globle void UnlinkNonLeftLineage(
00363 void *theEnv,
00364 struct joinNode *join,
00365 struct partialMatch *thePM,
00366 int side)
00367 {
00368 unsigned long betaLocation;
00369 struct betaMemory *theMemory;
00370 struct partialMatch *tempPM;
00371
00372 if (side == LHS)
00373 { theMemory = join->leftMemory; }
00374 else
00375 { theMemory = join->rightMemory; }
00376
00377
00378
00379
00380
00381 theMemory->count--;
00382 join->memoryDeletes++;
00383
00384 betaLocation = thePM->hashValue % theMemory->size;
00385
00386 if ((side == RHS) &&
00387 (theMemory->last[betaLocation] == thePM))
00388 { theMemory->last[betaLocation] = thePM->prevInMemory; }
00389
00390 if (thePM->prevInMemory == NULL)
00391 {
00392 betaLocation = thePM->hashValue % theMemory->size;
00393 theMemory->beta[betaLocation] = thePM->nextInMemory;
00394 }
00395 else
00396 { thePM->prevInMemory->nextInMemory = thePM->nextInMemory; }
00397
00398 if (thePM->nextInMemory != NULL)
00399 { thePM->nextInMemory->prevInMemory = thePM->prevInMemory; }
00400
00401
00402
00403
00404
00405 if (thePM->prevRightChild == NULL)
00406 {
00407 if (thePM->rightParent != NULL)
00408 {
00409 thePM->rightParent->children = thePM->nextRightChild;
00410 if (thePM->nextRightChild != NULL)
00411 {
00412 thePM->rightParent->children = thePM->nextRightChild;
00413 thePM->nextRightChild->rightParent = thePM->rightParent;
00414 }
00415 }
00416 }
00417 else
00418 { thePM->prevRightChild->nextRightChild = thePM->nextRightChild; }
00419
00420 if (thePM->nextRightChild != NULL)
00421 { thePM->nextRightChild->prevRightChild = thePM->prevRightChild; }
00422
00423
00424
00425
00426
00427 if (thePM->prevBlocked == NULL)
00428 {
00429 tempPM = (struct partialMatch *) thePM->marker;
00430
00431 if (tempPM != NULL)
00432 { tempPM->blockList = thePM->nextBlocked; }
00433 }
00434 else
00435 { thePM->prevBlocked->nextBlocked = thePM->nextBlocked; }
00436
00437 if (thePM->nextBlocked != NULL)
00438 { thePM->nextBlocked->prevBlocked = thePM->prevBlocked; }
00439
00440 if (! DefruleData(theEnv)->BetaMemoryResizingFlag)
00441 { return; }
00442
00443 if ((theMemory->count == 0) && (theMemory->size > 1))
00444 { ResetBetaMemory(theEnv,theMemory); }
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454 static void UnlinkBetaPartialMatchfromAlphaAndBetaLineage(
00455 struct partialMatch *thePM)
00456 {
00457 struct partialMatch *tempPM;
00458
00459
00460
00461
00462
00463 if (thePM->prevRightChild == NULL)
00464 {
00465 if (thePM->rightParent != NULL)
00466 { thePM->rightParent->children = thePM->nextRightChild; }
00467 }
00468 else
00469 { thePM->prevRightChild->nextRightChild = thePM->nextRightChild; }
00470
00471 if (thePM->nextRightChild != NULL)
00472 { thePM->nextRightChild->prevRightChild = thePM->prevRightChild; }
00473
00474 thePM->rightParent = NULL;
00475 thePM->nextRightChild = NULL;
00476 thePM->prevRightChild = NULL;
00477
00478
00479
00480
00481
00482 if (thePM->prevLeftChild == NULL)
00483 {
00484 if (thePM->leftParent != NULL)
00485 { thePM->leftParent->children = thePM->nextLeftChild; }
00486 }
00487 else
00488 { thePM->prevLeftChild->nextLeftChild = thePM->nextLeftChild; }
00489
00490 if (thePM->nextLeftChild != NULL)
00491 { thePM->nextLeftChild->prevLeftChild = thePM->prevLeftChild; }
00492
00493 thePM->leftParent = NULL;
00494 thePM->nextLeftChild = NULL;
00495 thePM->prevLeftChild = NULL;
00496
00497
00498
00499
00500
00501 if (thePM->prevBlocked == NULL)
00502 {
00503 tempPM = (struct partialMatch *) thePM->marker;
00504
00505 if (tempPM != NULL)
00506 { tempPM->blockList = thePM->nextBlocked; }
00507 }
00508 else
00509 { thePM->prevBlocked->nextBlocked = thePM->nextBlocked; }
00510
00511 if (thePM->nextBlocked != NULL)
00512 { thePM->nextBlocked->prevBlocked = thePM->prevBlocked; }
00513
00514 thePM->marker = NULL;
00515 thePM->nextBlocked = NULL;
00516 thePM->prevBlocked = NULL;
00517
00518
00519
00520
00521
00522 if (thePM->children != NULL)
00523 {
00524 if (thePM->betaMemory)
00525 {
00526 for (tempPM = thePM->children; tempPM != NULL; tempPM = tempPM->nextLeftChild)
00527 { tempPM->leftParent = NULL; }
00528 }
00529 else
00530 {
00531 for (tempPM = thePM->children; tempPM != NULL; tempPM = tempPM->nextRightChild)
00532 { tempPM->rightParent = NULL; }
00533 }
00534
00535 thePM->children = NULL;
00536 }
00537 }
00538
00539
00540
00541
00542
00543
00544 globle struct partialMatch *MergePartialMatches(
00545 void *theEnv,
00546 struct partialMatch *lhsBind,
00547 struct partialMatch *rhsBind)
00548 {
00549 struct partialMatch *linker;
00550 static struct partialMatch mergeTemplate = { 1 };
00551
00552
00553
00554
00555
00556 linker = get_var_struct(theEnv,partialMatch,sizeof(struct genericMatch) * lhsBind->bcount);
00557
00558
00559
00560
00561
00562 memcpy(linker,&mergeTemplate,sizeof(struct partialMatch) - sizeof(struct genericMatch));
00563
00564 linker->bcount = (unsigned short) (lhsBind->bcount + 1);
00565
00566
00567
00568
00569
00570 memcpy(linker->binds,lhsBind->binds,sizeof(struct genericMatch) * lhsBind->bcount);
00571
00572
00573
00574
00575
00576 if (rhsBind == NULL)
00577 { linker->binds[lhsBind->bcount].gm.theValue = NULL; }
00578 else
00579 { linker->binds[lhsBind->bcount].gm.theValue = rhsBind->binds[0].gm.theValue; }
00580
00581 return(linker);
00582 }
00583
00584
00585
00586
00587
00588 globle void InitializePatternHeader(
00589 void *theEnv,
00590 struct patternNodeHeader *theHeader)
00591 {
00592 #if MAC_MCW || WIN_MCW || MAC_XCD
00593 #pragma unused(theEnv)
00594 #endif
00595 theHeader->firstHash = NULL;
00596 theHeader->lastHash = NULL;
00597 theHeader->entryJoin = NULL;
00598 theHeader->rightHash = NULL;
00599 theHeader->singlefieldNode = FALSE;
00600 theHeader->multifieldNode = FALSE;
00601 theHeader->stopNode = FALSE;
00602 #if (! RUN_TIME)
00603 theHeader->initialize = EnvGetIncrementalReset(theEnv);
00604 #else
00605 theHeader->initialize = FALSE;
00606 #endif
00607 theHeader->marked = FALSE;
00608 theHeader->beginSlot = FALSE;
00609 theHeader->endSlot = FALSE;
00610 theHeader->selector = FALSE;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 globle struct partialMatch *CreateAlphaMatch(
00622 void *theEnv,
00623 void *theEntity,
00624 struct multifieldMarker *markers,
00625 struct patternNodeHeader *theHeader,
00626 unsigned long hashOffset)
00627 {
00628 struct partialMatch *theMatch;
00629 struct alphaMatch *afbtemp;
00630 unsigned long hashValue;
00631 struct alphaMemoryHash *theAlphaMemory;
00632
00633
00634
00635
00636
00637 theMatch = get_struct(theEnv,partialMatch);
00638 InitializePMLinks(theMatch);
00639 theMatch->betaMemory = FALSE;
00640 theMatch->busy = FALSE;
00641 theMatch->bcount = 1;
00642 theMatch->hashValue = hashOffset;
00643
00644 afbtemp = get_struct(theEnv,alphaMatch);
00645 afbtemp->next = NULL;
00646 afbtemp->matchingItem = (struct patternEntity *) theEntity;
00647
00648 if (markers != NULL)
00649 { afbtemp->markers = CopyMultifieldMarkers(theEnv,markers); }
00650 else
00651 { afbtemp->markers = NULL; }
00652
00653 theMatch->binds[0].gm.theMatch = afbtemp;
00654
00655
00656
00657
00658
00659 hashValue = AlphaMemoryHashValue(theHeader,hashOffset);
00660 theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue);
00661 afbtemp->bucket = hashValue;
00662
00663
00664
00665
00666
00667 if (theAlphaMemory == NULL)
00668 {
00669 theAlphaMemory = get_struct(theEnv,alphaMemoryHash);
00670 theAlphaMemory->bucket = hashValue;
00671 theAlphaMemory->owner = theHeader;
00672 theAlphaMemory->alphaMemory = NULL;
00673 theAlphaMemory->endOfQueue = NULL;
00674 theAlphaMemory->nextHash = NULL;
00675
00676 theAlphaMemory->next = DefruleData(theEnv)->AlphaMemoryTable[hashValue];
00677 if (theAlphaMemory->next != NULL)
00678 { theAlphaMemory->next->prev = theAlphaMemory; }
00679
00680 theAlphaMemory->prev = NULL;
00681 DefruleData(theEnv)->AlphaMemoryTable[hashValue] = theAlphaMemory;
00682
00683 if (theHeader->firstHash == NULL)
00684 {
00685 theHeader->firstHash = theAlphaMemory;
00686 theHeader->lastHash = theAlphaMemory;
00687 theAlphaMemory->prevHash = NULL;
00688 }
00689 else
00690 {
00691 theHeader->lastHash->nextHash = theAlphaMemory;
00692 theAlphaMemory->prevHash = theHeader->lastHash;
00693 theHeader->lastHash = theAlphaMemory;
00694 }
00695 }
00696
00697
00698
00699
00700
00701
00702 theMatch->prevInMemory = theAlphaMemory->endOfQueue;
00703 if (theAlphaMemory->endOfQueue == NULL)
00704 {
00705 theAlphaMemory->alphaMemory = theMatch;
00706 theAlphaMemory->endOfQueue = theMatch;
00707 }
00708 else
00709 {
00710 theAlphaMemory->endOfQueue->nextInMemory = theMatch;
00711 theAlphaMemory->endOfQueue = theMatch;
00712 }
00713
00714
00715
00716
00717
00718 return(theMatch);
00719 }
00720
00721
00722
00723
00724
00725 struct multifieldMarker *CopyMultifieldMarkers(
00726 void *theEnv,
00727 struct multifieldMarker *theMarkers)
00728 {
00729 struct multifieldMarker *head = NULL, *lastMark = NULL, *newMark;
00730
00731 while (theMarkers != NULL)
00732 {
00733 newMark = get_struct(theEnv,multifieldMarker);
00734 newMark->next = NULL;
00735 newMark->whichField = theMarkers->whichField;
00736 newMark->where = theMarkers->where;
00737 newMark->startPosition = theMarkers->startPosition;
00738 newMark->endPosition = theMarkers->endPosition;
00739
00740 if (lastMark == NULL)
00741 { head = newMark; }
00742 else
00743 { lastMark->next = newMark; }
00744 lastMark = newMark;
00745
00746 theMarkers = theMarkers->next;
00747 }
00748
00749 return(head);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758
00759 globle void FlushAlphaBetaMemory(
00760 void *theEnv,
00761 struct partialMatch *pfl)
00762 {
00763 struct partialMatch *pfltemp;
00764
00765 while (pfl != NULL)
00766 {
00767 pfltemp = pfl->nextInMemory;
00768
00769 UnlinkBetaPartialMatchfromAlphaAndBetaLineage(pfl);
00770 ReturnPartialMatch(theEnv,pfl);
00771
00772 pfl = pfltemp;
00773 }
00774 }
00775
00776
00777
00778
00779
00780 globle void DestroyAlphaBetaMemory(
00781 void *theEnv,
00782 struct partialMatch *pfl)
00783 {
00784 struct partialMatch *pfltemp;
00785
00786 while (pfl != NULL)
00787 {
00788 pfltemp = pfl->nextInMemory;
00789 DestroyPartialMatch(theEnv,pfl);
00790 pfl = pfltemp;
00791 }
00792 }
00793
00794
00795
00796
00797
00798 globle int FindEntityInPartialMatch(
00799 struct patternEntity *theEntity,
00800 struct partialMatch *thePartialMatch)
00801 {
00802 unsigned short i;
00803
00804 for (i = 0 ; i < thePartialMatch->bcount; i++)
00805 {
00806 if (thePartialMatch->binds[i].gm.theMatch == NULL) continue;
00807 if (thePartialMatch->binds[i].gm.theMatch->matchingItem == theEntity)
00808 { return(TRUE); }
00809 }
00810
00811 return(FALSE);
00812 }
00813
00814
00815
00816
00817
00818
00819 globle int GetPatternNumberFromJoin(
00820 struct joinNode *joinPtr)
00821 {
00822 int whichOne = 0;
00823
00824 while (joinPtr != NULL)
00825 {
00826 if (joinPtr->joinFromTheRight)
00827 { joinPtr = (struct joinNode *) joinPtr->rightSideEntryStructure; }
00828 else
00829 {
00830 whichOne++;
00831 joinPtr = joinPtr->lastLevel;
00832 }
00833 }
00834
00835 return(whichOne);
00836 }
00837
00838
00839
00840
00841
00842
00843 globle void TraceErrorToRule(
00844 void *theEnv,
00845 struct joinNode *joinPtr,
00846 char *indentSpaces)
00847 {
00848 int patternCount;
00849
00850 MarkRuleNetwork(theEnv,0);
00851
00852 patternCount = CountPriorPatterns(joinPtr->lastLevel) + 1;
00853
00854 TraceErrorToRuleDriver(theEnv,joinPtr,indentSpaces,patternCount,FALSE);
00855
00856 MarkRuleNetwork(theEnv,0);
00857 }
00858
00859
00860
00861
00862
00863 static void TraceErrorToRuleDriver(
00864 void *theEnv,
00865 struct joinNode *joinPtr,
00866 char *indentSpaces,
00867 int priorRightJoinPatterns,
00868 int enteredJoinFromRight)
00869 {
00870 char *name;
00871 int priorPatternCount;
00872 struct joinLink *theLinks;
00873
00874 if ((joinPtr->joinFromTheRight) && enteredJoinFromRight)
00875 { priorPatternCount = CountPriorPatterns(joinPtr->lastLevel); }
00876 else
00877 { priorPatternCount = 0; }
00878
00879 if (joinPtr->marked)
00880 { }
00881 else if (joinPtr->ruleToActivate != NULL)
00882 {
00883 joinPtr->marked = 1;
00884 name = EnvGetDefruleName(theEnv,joinPtr->ruleToActivate);
00885 EnvPrintRouter(theEnv,WERROR,indentSpaces);
00886
00887 EnvPrintRouter(theEnv,WERROR,"Of pattern #");
00888 PrintLongInteger(theEnv,WERROR,priorRightJoinPatterns+priorPatternCount);
00889 EnvPrintRouter(theEnv,WERROR," in rule ");
00890 EnvPrintRouter(theEnv,WERROR,name);
00891 EnvPrintRouter(theEnv,WERROR,"\n");
00892 }
00893 else
00894 {
00895 joinPtr->marked = 1;
00896
00897 theLinks = joinPtr->nextLinks;
00898 while (theLinks != NULL)
00899 {
00900 TraceErrorToRuleDriver(theEnv,theLinks->join,indentSpaces,
00901 priorRightJoinPatterns+priorPatternCount,
00902 (theLinks->enterDirection == RHS));
00903 theLinks = theLinks->next;
00904 }
00905 }
00906 }
00907
00908
00909
00910
00911 static int CountPriorPatterns(
00912 struct joinNode *joinPtr)
00913 {
00914 int count = 0;
00915
00916 while (joinPtr != NULL)
00917 {
00918 if (joinPtr->joinFromTheRight)
00919 { count += CountPriorPatterns((struct joinNode *) joinPtr->rightSideEntryStructure); }
00920 else
00921 { count++; }
00922
00923 joinPtr = joinPtr->lastLevel;
00924 }
00925
00926 return(count);
00927 }
00928
00929
00930
00931
00932
00933 globle void MarkRuleNetwork(
00934 void *theEnv,
00935 int value)
00936 {
00937 struct defrule *rulePtr;
00938 struct joinNode *joinPtr;
00939 struct defmodule *modulePtr;
00940
00941
00942
00943
00944
00945 SaveCurrentModule(theEnv);
00946 for (modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
00947 modulePtr != NULL;
00948 modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,modulePtr))
00949 {
00950 EnvSetCurrentModule(theEnv,(void *) modulePtr);
00951
00952
00953
00954
00955
00956 rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,NULL);
00957 while (rulePtr != NULL)
00958 {
00959
00960
00961
00962
00963
00964 joinPtr = rulePtr->lastJoin;
00965 MarkRuleJoins(joinPtr,value);
00966
00967
00968
00969
00970
00971
00972 if (rulePtr->disjunct != NULL) rulePtr = rulePtr->disjunct;
00973 else rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,rulePtr);
00974 }
00975
00976 }
00977
00978 RestoreCurrentModule(theEnv);
00979 }
00980
00981
00982
00983
00984 globle void MarkRuleJoins(
00985 struct joinNode *joinPtr,
00986 int value)
00987 {
00988 while (joinPtr != NULL)
00989 {
00990 if (joinPtr->joinFromTheRight)
00991 { MarkRuleJoins((struct joinNode *) joinPtr->rightSideEntryStructure,value); }
00992
00993 joinPtr->marked = value;
00994 joinPtr = joinPtr->lastLevel;
00995 }
00996 }
00997
00998
00999
01000
01001
01002 globle struct partialMatch *GetAlphaMemory(
01003 void *theEnv,
01004 struct patternNodeHeader *theHeader,
01005 unsigned long hashOffset)
01006 {
01007 struct alphaMemoryHash *theAlphaMemory;
01008 unsigned long hashValue;
01009
01010 hashValue = AlphaMemoryHashValue(theHeader,hashOffset);
01011 theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue);
01012
01013 if (theAlphaMemory == NULL)
01014 { return NULL; }
01015
01016 return theAlphaMemory->alphaMemory;
01017 }
01018
01019
01020
01021
01022
01023 globle struct partialMatch *GetLeftBetaMemory(
01024 struct joinNode *theJoin,
01025 unsigned long hashValue)
01026 {
01027 unsigned long betaLocation;
01028
01029 betaLocation = hashValue % theJoin->leftMemory->size;
01030
01031 return theJoin->leftMemory->beta[betaLocation];
01032 }
01033
01034
01035
01036
01037
01038 globle struct partialMatch *GetRightBetaMemory(
01039 struct joinNode *theJoin,
01040 unsigned long hashValue)
01041 {
01042 unsigned long betaLocation;
01043
01044 betaLocation = hashValue % theJoin->rightMemory->size;
01045
01046 return theJoin->rightMemory->beta[betaLocation];
01047 }
01048
01049
01050
01051
01052
01053 globle void ReturnLeftMemory(
01054 void *theEnv,
01055 struct joinNode *theJoin)
01056 {
01057 if (theJoin->leftMemory == NULL) return;
01058 genfree(theEnv,theJoin->leftMemory->beta,sizeof(struct partialMatch *) * theJoin->leftMemory->size);
01059 rtn_struct(theEnv,betaMemory,theJoin->leftMemory);
01060 theJoin->leftMemory = NULL;
01061 }
01062
01063
01064
01065
01066
01067 globle void ReturnRightMemory(
01068 void *theEnv,
01069 struct joinNode *theJoin)
01070 {
01071 if (theJoin->rightMemory == NULL) return;
01072 genfree(theEnv,theJoin->rightMemory->beta,sizeof(struct partialMatch *) * theJoin->rightMemory->size);
01073 genfree(theEnv,theJoin->rightMemory->last,sizeof(struct partialMatch *) * theJoin->rightMemory->size);
01074 rtn_struct(theEnv,betaMemory,theJoin->rightMemory);
01075 theJoin->rightMemory = NULL;
01076 }
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 globle void DestroyBetaMemory(
01087 void *theEnv,
01088 struct joinNode *theJoin,
01089 int side)
01090 {
01091 unsigned long i;
01092
01093 if (side == LHS)
01094 {
01095 if (theJoin->leftMemory == NULL) return;
01096
01097 for (i = 0; i < theJoin->leftMemory->size; i++)
01098 { DestroyAlphaBetaMemory(theEnv,theJoin->leftMemory->beta[i]); }
01099 }
01100 else
01101 {
01102 if (theJoin->rightMemory == NULL) return;
01103
01104 for (i = 0; i < theJoin->rightMemory->size; i++)
01105 { DestroyAlphaBetaMemory(theEnv,theJoin->rightMemory->beta[i]); }
01106 }
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116 globle void FlushBetaMemory(
01117 void *theEnv,
01118 struct joinNode *theJoin,
01119 int side)
01120 {
01121 unsigned long i;
01122
01123 if (side == LHS)
01124 {
01125 if (theJoin->leftMemory == NULL) return;
01126
01127 for (i = 0; i < theJoin->leftMemory->size; i++)
01128 { FlushAlphaBetaMemory(theEnv,theJoin->leftMemory->beta[i]); }
01129 }
01130 else
01131 {
01132 if (theJoin->rightMemory == NULL) return;
01133
01134 for (i = 0; i < theJoin->rightMemory->size; i++)
01135 { FlushAlphaBetaMemory(theEnv,theJoin->rightMemory->beta[i]); }
01136 }
01137 }
01138
01139
01140
01141
01142 globle intBool BetaMemoryNotEmpty(
01143 struct joinNode *theJoin)
01144 {
01145 if (theJoin->leftMemory != NULL)
01146 {
01147 if (theJoin->leftMemory->count > 0)
01148 { return(TRUE); }
01149 }
01150
01151 if (theJoin->rightMemory != NULL)
01152 {
01153 if (theJoin->rightMemory->count > 0)
01154 { return(TRUE); }
01155 }
01156
01157 return(FALSE);
01158 }
01159
01160
01161
01162
01163
01164 globle void RemoveAlphaMemoryMatches(
01165 void *theEnv,
01166 struct patternNodeHeader *theHeader,
01167 struct partialMatch *theMatch,
01168 struct alphaMatch *theAlphaMatch)
01169 {
01170 struct alphaMemoryHash *theAlphaMemory = NULL;
01171 unsigned long hashValue;
01172
01173 if ((theMatch->prevInMemory == NULL) || (theMatch->nextInMemory == NULL))
01174 {
01175 hashValue = theAlphaMatch->bucket;
01176 theAlphaMemory = FindAlphaMemory(theEnv,theHeader,hashValue);
01177 }
01178
01179 if (theMatch->prevInMemory != NULL)
01180 { theMatch->prevInMemory->nextInMemory = theMatch->nextInMemory; }
01181 else
01182 { theAlphaMemory->alphaMemory = theMatch->nextInMemory; }
01183
01184 if (theMatch->nextInMemory != NULL)
01185 { theMatch->nextInMemory->prevInMemory = theMatch->prevInMemory; }
01186 else
01187 { theAlphaMemory->endOfQueue = theMatch->prevInMemory; }
01188
01189
01190
01191
01192
01193 theMatch->nextInMemory = EngineData(theEnv)->GarbagePartialMatches;
01194 EngineData(theEnv)->GarbagePartialMatches = theMatch;
01195
01196 if ((theAlphaMemory != NULL) && (theAlphaMemory->alphaMemory == NULL))
01197 { UnlinkAlphaMemory(theEnv,theHeader,theAlphaMemory); }
01198 }
01199
01200
01201
01202
01203 globle void DestroyAlphaMemory(
01204 void *theEnv,
01205 struct patternNodeHeader *theHeader,
01206 int unlink)
01207 {
01208 struct alphaMemoryHash *theAlphaMemory, *tempMemory;
01209
01210 theAlphaMemory = theHeader->firstHash;
01211
01212 while (theAlphaMemory != NULL)
01213 {
01214 tempMemory = theAlphaMemory->nextHash;
01215 DestroyAlphaBetaMemory(theEnv,theAlphaMemory->alphaMemory);
01216 if (unlink)
01217 { UnlinkAlphaMemoryBucketSiblings(theEnv,theAlphaMemory); }
01218 rtn_struct(theEnv,alphaMemoryHash,theAlphaMemory);
01219 theAlphaMemory = tempMemory;
01220 }
01221
01222 theHeader->firstHash = NULL;
01223 theHeader->lastHash = NULL;
01224 }
01225
01226
01227
01228
01229 globle void FlushAlphaMemory(
01230 void *theEnv,
01231 struct patternNodeHeader *theHeader)
01232 {
01233 struct alphaMemoryHash *theAlphaMemory, *tempMemory;
01234
01235 theAlphaMemory = theHeader->firstHash;
01236
01237 while (theAlphaMemory != NULL)
01238 {
01239 tempMemory = theAlphaMemory->nextHash;
01240 FlushAlphaBetaMemory(theEnv,theAlphaMemory->alphaMemory);
01241 UnlinkAlphaMemoryBucketSiblings(theEnv,theAlphaMemory);
01242 rtn_struct(theEnv,alphaMemoryHash,theAlphaMemory);
01243 theAlphaMemory = tempMemory;
01244 }
01245
01246 theHeader->firstHash = NULL;
01247 theHeader->lastHash = NULL;
01248 }
01249
01250
01251
01252
01253 static struct alphaMemoryHash *FindAlphaMemory(
01254 void *theEnv,
01255 struct patternNodeHeader *theHeader,
01256 unsigned long hashValue)
01257 {
01258 struct alphaMemoryHash *theAlphaMemory;
01259
01260 theAlphaMemory = DefruleData(theEnv)->AlphaMemoryTable[hashValue];
01261
01262 if (theAlphaMemory != NULL)
01263 {
01264 while ((theAlphaMemory != NULL) && (theAlphaMemory->owner != theHeader))
01265 { theAlphaMemory = theAlphaMemory->next; }
01266 }
01267
01268 return theAlphaMemory;
01269 }
01270
01271
01272
01273
01274 static unsigned long AlphaMemoryHashValue(
01275 struct patternNodeHeader *theHeader,
01276 unsigned long hashOffset)
01277 {
01278 unsigned long hashValue;
01279 union
01280 {
01281 void *vv;
01282 unsigned uv;
01283 } fis;
01284
01285 fis.uv = 0;
01286 fis.vv = theHeader;
01287
01288 hashValue = fis.uv + hashOffset;
01289 hashValue = hashValue % ALPHA_MEMORY_HASH_SIZE;
01290
01291 return hashValue;
01292 }
01293
01294
01295
01296
01297 static void UnlinkAlphaMemory(
01298 void *theEnv,
01299 struct patternNodeHeader *theHeader,
01300 struct alphaMemoryHash *theAlphaMemory)
01301 {
01302
01303
01304
01305
01306 UnlinkAlphaMemoryBucketSiblings(theEnv,theAlphaMemory);
01307
01308
01309
01310
01311
01312 if (theAlphaMemory == theHeader->firstHash)
01313 { theHeader->firstHash = theAlphaMemory->nextHash; }
01314
01315 if (theAlphaMemory == theHeader->lastHash)
01316 { theHeader->lastHash = theAlphaMemory->prevHash; }
01317
01318
01319
01320
01321
01322 if (theAlphaMemory->prevHash != NULL)
01323 { theAlphaMemory->prevHash->nextHash = theAlphaMemory->nextHash; }
01324
01325 if (theAlphaMemory->nextHash != NULL)
01326 { theAlphaMemory->nextHash->prevHash = theAlphaMemory->prevHash; }
01327
01328 rtn_struct(theEnv,alphaMemoryHash,theAlphaMemory);
01329 }
01330
01331
01332
01333
01334 static void UnlinkAlphaMemoryBucketSiblings(
01335 void *theEnv,
01336 struct alphaMemoryHash *theAlphaMemory)
01337 {
01338 if (theAlphaMemory->prev == NULL)
01339 { DefruleData(theEnv)->AlphaMemoryTable[theAlphaMemory->bucket] = theAlphaMemory->next; }
01340 else
01341 { theAlphaMemory->prev->next = theAlphaMemory->next; }
01342
01343 if (theAlphaMemory->next != NULL)
01344 { theAlphaMemory->next->prev = theAlphaMemory->prev; }
01345 }
01346
01347
01348
01349
01350 unsigned long ComputeRightHashValue(
01351 void *theEnv,
01352 struct patternNodeHeader *theHeader)
01353 {
01354 struct expr *tempExpr;
01355 unsigned long hashValue = 0;
01356 unsigned long multiplier = 1;
01357
01358 if (theHeader->rightHash == NULL)
01359 { return hashValue; }
01360
01361 for (tempExpr = theHeader->rightHash;
01362 tempExpr != NULL;
01363 tempExpr = tempExpr->nextArg, multiplier = multiplier * 509)
01364 {
01365 DATA_OBJECT theResult;
01366 struct expr *oldArgument;
01367
01368 oldArgument = EvaluationData(theEnv)->CurrentExpression;
01369 EvaluationData(theEnv)->CurrentExpression = tempExpr;
01370 (*EvaluationData(theEnv)->PrimitivesArray[tempExpr->type]->evaluateFunction)(theEnv,tempExpr->value,&theResult);
01371 EvaluationData(theEnv)->CurrentExpression = oldArgument;
01372
01373 switch (theResult.type)
01374 {
01375 case STRING:
01376 case SYMBOL:
01377 case INSTANCE_NAME:
01378 hashValue += (((SYMBOL_HN *) theResult.value)->bucket * multiplier);
01379 break;
01380
01381 case INTEGER:
01382 hashValue += (((INTEGER_HN *) theResult.value)->bucket * multiplier);
01383 break;
01384
01385 case FLOAT:
01386 hashValue += (((FLOAT_HN *) theResult.value)->bucket * multiplier);
01387 break;
01388 }
01389 }
01390
01391 return hashValue;
01392 }
01393
01394
01395
01396
01397 globle void ResizeBetaMemory(
01398 void *theEnv,
01399 struct betaMemory *theMemory)
01400 {
01401 struct partialMatch **oldArray, **lastAdd, *thePM, *nextPM;
01402 unsigned long i, oldSize, betaLocation;
01403
01404 oldSize = theMemory->size;
01405 oldArray = theMemory->beta;
01406
01407 theMemory->size = oldSize * 11;
01408 theMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
01409
01410 lastAdd = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
01411 memset(theMemory->beta,0,sizeof(struct partialMatch *) * theMemory->size);
01412 memset(lastAdd,0,sizeof(struct partialMatch *) * theMemory->size);
01413
01414 for (i = 0; i < oldSize; i++)
01415 {
01416 thePM = oldArray[i];
01417 while (thePM != NULL)
01418 {
01419 nextPM = thePM->nextInMemory;
01420
01421 thePM->nextInMemory = NULL;
01422
01423 betaLocation = thePM->hashValue % theMemory->size;
01424 thePM->prevInMemory = lastAdd[betaLocation];
01425
01426 if (lastAdd[betaLocation] != NULL)
01427 { lastAdd[betaLocation]->nextInMemory = thePM; }
01428 else
01429 { theMemory->beta[betaLocation] = thePM; }
01430
01431 lastAdd[betaLocation] = thePM;
01432
01433 thePM = nextPM;
01434 }
01435 }
01436
01437 if (theMemory->last != NULL)
01438 {
01439 genfree(theEnv,theMemory->last,sizeof(struct partialMatch *) * oldSize);
01440 theMemory->last = lastAdd;
01441 }
01442 else
01443 { genfree(theEnv,lastAdd,sizeof(struct partialMatch *) * theMemory->size); }
01444
01445 genfree(theEnv,oldArray,sizeof(struct partialMatch *) * oldSize);
01446 }
01447
01448
01449
01450
01451 static void ResetBetaMemory(
01452 void *theEnv,
01453 struct betaMemory *theMemory)
01454 {
01455 struct partialMatch **oldArray, **lastAdd;
01456 unsigned long oldSize;
01457
01458 if ((theMemory->size == 1) ||
01459 (theMemory->size == INITIAL_BETA_HASH_SIZE))
01460 { return; }
01461
01462 oldSize = theMemory->size;
01463 oldArray = theMemory->beta;
01464
01465 theMemory->size = INITIAL_BETA_HASH_SIZE;
01466 theMemory->beta = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
01467 memset(theMemory->beta,0,sizeof(struct partialMatch *) * theMemory->size);
01468 genfree(theEnv,oldArray,sizeof(struct partialMatch *) * oldSize);
01469
01470 if (theMemory->last != NULL)
01471 {
01472 lastAdd = (struct partialMatch **) genalloc(theEnv,sizeof(struct partialMatch *) * theMemory->size);
01473 memset(lastAdd,0,sizeof(struct partialMatch *) * theMemory->size);
01474 genfree(theEnv,theMemory->last,sizeof(struct partialMatch *) * oldSize);
01475 theMemory->last = lastAdd;
01476 }
01477 }
01478
01479 #if (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME)
01480
01481
01482
01483
01484
01485
01486
01487 globle void TagRuleNetwork(
01488 void *theEnv,
01489 long int *moduleCount,
01490 long int *ruleCount,
01491 long int *joinCount,
01492 long int *linkCount)
01493 {
01494 struct defmodule *modulePtr;
01495 struct defrule *rulePtr;
01496 struct joinLink *theLink;
01497
01498 *moduleCount = 0;
01499 *ruleCount = 0;
01500 *joinCount = 0;
01501 *linkCount = 0;
01502
01503 MarkRuleNetwork(theEnv,0);
01504
01505 for (theLink = DefruleData(theEnv)->LeftPrimeJoins;
01506 theLink != NULL;
01507 theLink = theLink->next)
01508 {
01509 theLink->bsaveID = *linkCount;
01510 (*linkCount)++;
01511 }
01512
01513 for (theLink = DefruleData(theEnv)->RightPrimeJoins;
01514 theLink != NULL;
01515 theLink = theLink->next)
01516 {
01517 theLink->bsaveID = *linkCount;
01518 (*linkCount)++;
01519 }
01520
01521
01522
01523
01524
01525 for (modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
01526 modulePtr != NULL;
01527 modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,modulePtr))
01528 {
01529 (*moduleCount)++;
01530 EnvSetCurrentModule(theEnv,(void *) modulePtr);
01531
01532
01533
01534
01535
01536 rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,NULL);
01537
01538 while (rulePtr != NULL)
01539 {
01540 rulePtr->header.bsaveID = *ruleCount;
01541 (*ruleCount)++;
01542
01543
01544
01545
01546
01547 TagNetworkTraverseJoins(theEnv,joinCount,linkCount,rulePtr->lastJoin);
01548
01549 if (rulePtr->disjunct != NULL) rulePtr = rulePtr->disjunct;
01550 else rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,rulePtr);
01551 }
01552 }
01553 }
01554
01555
01556
01557
01558 static void TagNetworkTraverseJoins(
01559 void *theEnv,
01560 long int *joinCount,
01561 long int *linkCount,
01562 struct joinNode *joinPtr)
01563 {
01564 struct joinLink *theLink;
01565 for (;
01566 joinPtr != NULL;
01567 joinPtr = joinPtr->lastLevel)
01568 {
01569 if (joinPtr->marked == 0)
01570 {
01571 joinPtr->marked = 1;
01572 joinPtr->bsaveID = *joinCount;
01573 (*joinCount)++;
01574 for (theLink = joinPtr->nextLinks;
01575 theLink != NULL;
01576 theLink = theLink->next)
01577 {
01578 theLink->bsaveID = *linkCount;
01579 (*linkCount)++;
01580 }
01581 }
01582
01583 if (joinPtr->joinFromTheRight)
01584 { TagNetworkTraverseJoins(theEnv,joinCount,linkCount,(struct joinNode *) joinPtr->rightSideEntryStructure); }
01585 }
01586 }
01587
01588 #endif
01589
01590 #endif
01591
01592
01593
01594
01595