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 #define _RULEDLT_SOURCE_
00030
00031 #include "setup.h"
00032
00033 #if DEFRULE_CONSTRUCT
00034
00035 #include <stdio.h>
00036 #define _STDIO_INCLUDED_
00037 #include <string.h>
00038
00039 #include "memalloc.h"
00040 #include "engine.h"
00041 #include "envrnmnt.h"
00042 #include "reteutil.h"
00043 #include "pattern.h"
00044 #include "agenda.h"
00045 #include "drive.h"
00046 #include "retract.h"
00047 #include "constrct.h"
00048
00049 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
00050 #include "bload.h"
00051 #endif
00052
00053 #include "ruledlt.h"
00054
00055
00056
00057
00058
00059 #if (! RUN_TIME) && (! BLOAD_ONLY)
00060 static void RemoveIntranetworkLink(void *,struct joinNode *);
00061 #endif
00062 static void DetachJoins(void *,struct joinNode *,intBool);
00063 static void DetachJoinsDriver(void *,struct defrule *,intBool);
00064
00065
00066
00067
00068
00069
00070
00071
00072 globle void ReturnDefrule(
00073 void *theEnv,
00074 void *vWaste)
00075 {
00076 #if (MAC_MCW || WIN_MCW) && (RUN_TIME || BLOAD_ONLY)
00077 #pragma unused(theEnv,vWaste)
00078 #endif
00079
00080 #if (! RUN_TIME) && (! BLOAD_ONLY)
00081 struct defrule *waste = (struct defrule *) vWaste;
00082 int first = TRUE;
00083 struct defrule *nextPtr, *tmpPtr;
00084
00085 if (waste == NULL) return;
00086
00087
00088
00089
00090
00091
00092 #if DEBUGGING_FUNCTIONS
00093 DefruleData(theEnv)->DeletedRuleDebugFlags = 0;
00094 if (waste->afterBreakpoint) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,0);
00095 if (waste->watchActivation) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,1);
00096 if (waste->watchFiring) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,2);
00097 #endif
00098
00099
00100
00101
00102
00103
00104 ClearRuleFromAgenda(theEnv,waste);
00105
00106
00107
00108
00109
00110 while (waste != NULL)
00111 {
00112
00113
00114
00115
00116 DetachJoinsDriver(theEnv,waste,FALSE);
00117
00118
00119
00120
00121
00122
00123 if (first)
00124 {
00125 if (waste->dynamicSalience != NULL)
00126 {
00127 ExpressionDeinstall(theEnv,waste->dynamicSalience);
00128 ReturnPackedExpression(theEnv,waste->dynamicSalience);
00129 waste->dynamicSalience = NULL;
00130 }
00131 if (waste->header.ppForm != NULL)
00132 {
00133 rm(theEnv,waste->header.ppForm,strlen(waste->header.ppForm) + 1);
00134 waste->header.ppForm = NULL;
00135
00136
00137
00138
00139
00140
00141 for (tmpPtr = waste->disjunct; tmpPtr != NULL; tmpPtr = tmpPtr->disjunct)
00142 { tmpPtr->header.ppForm = NULL; }
00143 }
00144
00145 first = FALSE;
00146 }
00147
00148
00149
00150
00151
00152 if (waste->header.usrData != NULL)
00153 { ClearUserDataList(theEnv,waste->header.usrData); }
00154
00155
00156
00157
00158
00159 DecrementSymbolCount(theEnv,waste->header.name);
00160
00161
00162
00163
00164
00165 if (waste->actions != NULL)
00166 {
00167 ExpressionDeinstall(theEnv,waste->actions);
00168 ReturnPackedExpression(theEnv,waste->actions);
00169 }
00170
00171
00172
00173
00174
00175 nextPtr = waste->disjunct;
00176 rtn_struct(theEnv,defrule,waste);
00177 waste = nextPtr;
00178 }
00179
00180
00181
00182
00183
00184 if (EngineData(theEnv)->ExecutingRule == NULL) FlushGarbagePartialMatches(theEnv);
00185 #endif
00186 }
00187
00188
00189
00190
00191
00192 globle void DestroyDefrule(
00193 void *theEnv,
00194 void *vTheDefrule)
00195 {
00196 struct defrule *theDefrule = (struct defrule *) vTheDefrule;
00197 struct defrule *nextDisjunct, *tmpPtr;
00198 int first = TRUE;
00199
00200 if (theDefrule == NULL) return;
00201
00202 while (theDefrule != NULL)
00203 {
00204 DetachJoinsDriver(theEnv,theDefrule,TRUE);
00205
00206 if (first)
00207 {
00208 #if (! BLOAD_ONLY) && (! RUN_TIME)
00209 if (theDefrule->dynamicSalience != NULL)
00210 { ReturnPackedExpression(theEnv,theDefrule->dynamicSalience); }
00211
00212 if (theDefrule->header.ppForm != NULL)
00213 {
00214 rm(theEnv,theDefrule->header.ppForm,strlen(theDefrule->header.ppForm) + 1);
00215
00216
00217
00218
00219
00220
00221 for (tmpPtr = theDefrule->disjunct; tmpPtr != NULL; tmpPtr = tmpPtr->disjunct)
00222 { tmpPtr->header.ppForm = NULL; }
00223 }
00224 #endif
00225
00226 first = FALSE;
00227 }
00228
00229 if (theDefrule->header.usrData != NULL)
00230 { ClearUserDataList(theEnv,theDefrule->header.usrData); }
00231
00232 #if (! BLOAD_ONLY) && (! RUN_TIME)
00233 if (theDefrule->actions != NULL)
00234 { ReturnPackedExpression(theEnv,theDefrule->actions); }
00235 #endif
00236
00237 nextDisjunct = theDefrule->disjunct;
00238
00239 #if (! BLOAD_ONLY) && (! RUN_TIME)
00240 rtn_struct(theEnv,defrule,theDefrule);
00241 #endif
00242
00243 theDefrule = nextDisjunct;
00244 }
00245 }
00246
00247
00248
00249
00250 static void DetachJoinsDriver(
00251 void *theEnv,
00252 struct defrule *theRule,
00253 intBool destroy)
00254 {
00255 struct joinNode *join;
00256
00257
00258
00259
00260
00261 join = theRule->lastJoin;
00262 theRule->lastJoin = NULL;
00263 if (join == NULL) return;
00264
00265
00266
00267
00268
00269
00270
00271
00272 join->ruleToActivate = NULL;
00273 if (join->nextLinks != NULL) return;
00274
00275 DetachJoins(theEnv,join,destroy);
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 static void DetachJoins(
00288 void *theEnv,
00289 struct joinNode *join,
00290 intBool destroy)
00291 {
00292 struct joinNode *prevJoin, *rightJoin;
00293 struct joinLink *lastLink, *theLink;
00294 int lastMark;
00295
00296
00297
00298
00299
00300 while (join != NULL)
00301 {
00302 if (join->marked) return;
00303
00304
00305
00306
00307
00308
00309
00310 prevJoin = join->lastLevel;
00311 if (join->joinFromTheRight)
00312 { rightJoin = (struct joinNode *) join->rightSideEntryStructure; }
00313 else
00314 { rightJoin = NULL; }
00315
00316
00317
00318
00319
00320
00321
00322 #if (! RUN_TIME) && (! BLOAD_ONLY)
00323 if (! destroy)
00324 {
00325 if ((join->rightSideEntryStructure != NULL) && (join->joinFromTheRight == FALSE))
00326 { RemoveIntranetworkLink(theEnv,join); }
00327 }
00328 #endif
00329
00330
00331
00332
00333
00334
00335 if (destroy)
00336 {
00337 DestroyBetaMemory(theEnv,join,LHS);
00338 DestroyBetaMemory(theEnv,join,RHS);
00339 }
00340 else
00341 {
00342 FlushBetaMemory(theEnv,join,LHS);
00343 FlushBetaMemory(theEnv,join,RHS);
00344 }
00345
00346 ReturnLeftMemory(theEnv,join);
00347 ReturnRightMemory(theEnv,join);
00348
00349
00350
00351
00352
00353
00354 #if (! RUN_TIME) && (! BLOAD_ONLY)
00355 if (! destroy)
00356 {
00357 RemoveHashedExpression(theEnv,join->networkTest);
00358 RemoveHashedExpression(theEnv,join->secondaryNetworkTest);
00359 RemoveHashedExpression(theEnv,join->leftHash);
00360 RemoveHashedExpression(theEnv,join->rightHash);
00361 }
00362 #endif
00363
00364
00365
00366
00367
00368 if (join->firstJoin && (join->rightSideEntryStructure == NULL))
00369 {
00370 lastLink = NULL;
00371
00372 theLink = DefruleData(theEnv)->RightPrimeJoins;
00373 while (theLink != NULL)
00374 {
00375 if (theLink->join == join)
00376 {
00377 if (lastLink == NULL)
00378 { DefruleData(theEnv)->RightPrimeJoins = theLink->next; }
00379 else
00380 { lastLink->next = theLink->next; }
00381
00382 #if (! RUN_TIME) && (! BLOAD_ONLY)
00383 rtn_struct(theEnv,joinLink,theLink);
00384 #endif
00385
00386 theLink = NULL;
00387 }
00388 else
00389 {
00390 lastLink = theLink;
00391 theLink = lastLink->next;
00392 }
00393 }
00394 }
00395
00396
00397
00398
00399
00400 if (join->firstJoin && (join->patternIsNegated || join->joinFromTheRight) && (! join->patternIsExists))
00401 {
00402 lastLink = NULL;
00403 theLink = DefruleData(theEnv)->LeftPrimeJoins;
00404 while (theLink != NULL)
00405 {
00406 if (theLink->join == join)
00407 {
00408 if (lastLink == NULL)
00409 { DefruleData(theEnv)->LeftPrimeJoins = theLink->next; }
00410 else
00411 { lastLink->next = theLink->next; }
00412
00413 #if (! RUN_TIME) && (! BLOAD_ONLY)
00414 rtn_struct(theEnv,joinLink,theLink);
00415 #endif
00416
00417 theLink = NULL;
00418 }
00419 else
00420 {
00421 lastLink = theLink;
00422 theLink = theLink->next;
00423 }
00424 }
00425 }
00426
00427
00428
00429
00430
00431 if (prevJoin != NULL)
00432 {
00433 lastLink = NULL;
00434 theLink = prevJoin->nextLinks;
00435 while (theLink != NULL)
00436 {
00437 if (theLink->join == join)
00438 {
00439 if (lastLink == NULL)
00440 { prevJoin->nextLinks = theLink->next; }
00441 else
00442 { lastLink->next = theLink->next; }
00443
00444 #if (! RUN_TIME) && (! BLOAD_ONLY)
00445 rtn_struct(theEnv,joinLink,theLink);
00446 #endif
00447
00448 theLink = NULL;
00449 }
00450 else
00451 {
00452 lastLink = theLink;
00453 theLink = theLink->next;
00454 }
00455 }
00456 }
00457
00458
00459
00460
00461
00462 if (rightJoin != NULL)
00463 {
00464 lastLink = NULL;
00465 theLink = rightJoin->nextLinks;
00466 while (theLink != NULL)
00467 {
00468 if (theLink->join == join)
00469 {
00470 if (lastLink == NULL)
00471 { rightJoin->nextLinks = theLink->next; }
00472 else
00473 { lastLink->next = theLink->next; }
00474
00475 #if (! RUN_TIME) && (! BLOAD_ONLY)
00476 rtn_struct(theEnv,joinLink,theLink);
00477 #endif
00478 theLink = NULL;
00479 }
00480 else
00481 {
00482 lastLink = theLink;
00483 theLink = theLink->next;
00484 }
00485 }
00486
00487 if ((rightJoin->nextLinks == NULL) &&
00488 (rightJoin->ruleToActivate == NULL))
00489 {
00490 if (prevJoin != NULL)
00491 {
00492 lastMark = prevJoin->marked;
00493 prevJoin->marked = TRUE;
00494 DetachJoins(theEnv,rightJoin,destroy);
00495 prevJoin->marked = lastMark;
00496 }
00497 else
00498 { DetachJoins(theEnv,rightJoin,destroy); }
00499 }
00500 }
00501
00502
00503
00504
00505
00506 #if (! RUN_TIME) && (! BLOAD_ONLY)
00507 rtn_struct(theEnv,joinNode,join);
00508 #endif
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 if (prevJoin == NULL)
00520 { return; }
00521 else if (prevJoin->ruleToActivate != NULL)
00522 { return; }
00523 else if (prevJoin->nextLinks == NULL)
00524 { join = prevJoin; }
00525 else
00526 { return; }
00527 }
00528 }
00529
00530 #if (! RUN_TIME) && (! BLOAD_ONLY)
00531
00532
00533
00534
00535
00536
00537
00538 static void RemoveIntranetworkLink(
00539 void *theEnv,
00540 struct joinNode *join)
00541 {
00542 struct patternNodeHeader *patternPtr;
00543 struct joinNode *joinPtr, *lastJoin;
00544
00545
00546
00547
00548
00549
00550
00551 patternPtr = (struct patternNodeHeader *) join->rightSideEntryStructure;
00552 joinPtr = patternPtr->entryJoin;
00553 lastJoin = NULL;
00554
00555
00556
00557
00558
00559
00560
00561 while (joinPtr != NULL)
00562 {
00563 if (joinPtr == join)
00564 {
00565 if (lastJoin == NULL)
00566 { patternPtr->entryJoin = joinPtr->rightMatchNode; }
00567 else
00568 { lastJoin->rightMatchNode = joinPtr->rightMatchNode; }
00569
00570 joinPtr = NULL;
00571 }
00572 else
00573 {
00574 lastJoin = joinPtr;
00575 joinPtr = joinPtr->rightMatchNode;
00576 }
00577 }
00578
00579
00580
00581
00582
00583
00584 if (patternPtr->entryJoin == NULL)
00585 { DetachPattern(theEnv,(int) join->rhsType,patternPtr); }
00586 }
00587
00588 #endif
00589
00590 #endif
00591
00592
00593