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 #define _RULECMP_SOURCE_
00028
00029 #include "setup.h"
00030
00031 #if DEFRULE_CONSTRUCT && (! RUN_TIME) && CONSTRUCT_COMPILER
00032
00033 #include <stdio.h>
00034 #define _STDIO_INCLUDED_
00035 #include <string.h>
00036
00037 #include "envrnmnt.h"
00038 #include "factbld.h"
00039 #include "reteutil.h"
00040
00041 #include "rulecmp.h"
00042
00043
00044
00045
00046
00047 static int ConstructToCode(void *,char *,char *,char *,int,FILE *,int,int);
00048 static void JoinToCode(void *,FILE *,struct joinNode *,int,int);
00049 static void LinkToCode(void *,FILE *,struct joinLink *,int,int);
00050 static void DefruleModuleToCode(void *,FILE *,struct defmodule *,int,int,int);
00051 static void DefruleToCode(void *,FILE *,struct defrule *,int,int,int);
00052 static void CloseDefruleFiles(void *,FILE *,FILE *,FILE *,FILE*,int);
00053 static void BeforeDefrulesCode(void *);
00054 static void InitDefruleCode(void *,FILE *,int,int);
00055 static int RuleCompilerTraverseJoins(void *,struct joinNode *,char *,char *,char *,int,
00056 FILE *,int,int,FILE **,FILE **,
00057 int *,int *,int *,int *,int *);
00058 static int TraverseJoinLinks(void *,struct joinLink *,char *,char *,char *,int,FILE *,
00059 int,int,FILE **,int *,int *, int *);
00060
00061
00062
00063
00064
00065 globle void DefruleCompilerSetup(
00066 void *theEnv)
00067 {
00068 DefruleData(theEnv)->DefruleCodeItem = AddCodeGeneratorItem(theEnv,"defrules",0,BeforeDefrulesCode,
00069 InitDefruleCode,ConstructToCode,4);
00070 }
00071
00072
00073
00074
00075
00076
00077 static void BeforeDefrulesCode(
00078 void *theEnv)
00079 {
00080 long int moduleCount, ruleCount, joinCount, linkCount;
00081
00082 TagRuleNetwork(theEnv,&moduleCount,&ruleCount,&joinCount, &linkCount);
00083 }
00084
00085
00086
00087
00088
00089 static int ConstructToCode(
00090 void *theEnv,
00091 char *fileName,
00092 char *pathName,
00093 char *fileNameBuffer,
00094 int fileID,
00095 FILE *headerFP,
00096 int imageID,
00097 int maxIndices)
00098 {
00099 int fileCount = 1;
00100 struct defmodule *theModule;
00101 struct defrule *theDefrule;
00102 int joinArrayCount = 0, joinArrayVersion = 1;
00103 int linkArrayCount = 0, linkArrayVersion = 1;
00104 int moduleCount = 0, moduleArrayCount = 0, moduleArrayVersion = 1;
00105 int defruleArrayCount = 0, defruleArrayVersion = 1;
00106 FILE *joinFile = NULL, *moduleFile = NULL, *defruleFile = NULL, *linkFile = NULL;
00107
00108
00109
00110
00111
00112 fprintf(headerFP,"#include \"ruledef.h\"\n");
00113
00114
00115
00116
00117
00118 if (! TraverseJoinLinks(theEnv,DefruleData(theEnv)->LeftPrimeJoins,fileName,pathName,fileNameBuffer,fileID,headerFP,imageID,
00119 maxIndices,&linkFile,&fileCount,&linkArrayVersion,&linkArrayCount))
00120 {
00121 CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices);
00122 return(0);
00123 }
00124
00125 if (! TraverseJoinLinks(theEnv,DefruleData(theEnv)->RightPrimeJoins,fileName,pathName,fileNameBuffer,fileID,headerFP,imageID,
00126 maxIndices,&linkFile,&fileCount,&linkArrayVersion,&linkArrayCount))
00127 {
00128 CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices);
00129 return(0);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
00139 theModule != NULL;
00140 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
00141 {
00142
00143
00144
00145
00146 EnvSetCurrentModule(theEnv,(void *) theModule);
00147
00148
00149
00150
00151
00152 moduleFile = OpenFileIfNeeded(theEnv,moduleFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
00153 moduleArrayVersion,headerFP,
00154 "struct defruleModule",ModulePrefix(DefruleData(theEnv)->DefruleCodeItem),
00155 FALSE,NULL);
00156
00157 if (moduleFile == NULL)
00158 {
00159 CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices);
00160 return(0);
00161 }
00162
00163 DefruleModuleToCode(theEnv,moduleFile,theModule,imageID,maxIndices,moduleCount);
00164 moduleFile = CloseFileIfNeeded(theEnv,moduleFile,&moduleArrayCount,&moduleArrayVersion,
00165 maxIndices,NULL,NULL);
00166
00167
00168
00169
00170
00171
00172 theDefrule = (struct defrule *) EnvGetNextDefrule(theEnv,NULL);
00173
00174 while (theDefrule != NULL)
00175 {
00176
00177
00178
00179
00180 defruleFile = OpenFileIfNeeded(theEnv,defruleFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
00181 defruleArrayVersion,headerFP,
00182 "struct defrule",ConstructPrefix(DefruleData(theEnv)->DefruleCodeItem),
00183 FALSE,NULL);
00184 if (defruleFile == NULL)
00185 {
00186 CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices);
00187 return(0);
00188 }
00189
00190 DefruleToCode(theEnv,defruleFile,theDefrule,imageID,maxIndices,
00191 moduleCount);
00192 defruleArrayCount++;
00193 defruleFile = CloseFileIfNeeded(theEnv,defruleFile,&defruleArrayCount,&defruleArrayVersion,
00194 maxIndices,NULL,NULL);
00195
00196
00197
00198
00199
00200 if (! RuleCompilerTraverseJoins(theEnv,theDefrule->lastJoin,fileName,pathName,fileNameBuffer,fileID,headerFP,imageID,
00201 maxIndices,&joinFile,&linkFile,&fileCount,&joinArrayVersion,&joinArrayCount,
00202 &linkArrayVersion,&linkArrayCount))
00203 {
00204 CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices);
00205 return(0);
00206 }
00207
00208
00209
00210
00211
00212 if (theDefrule->disjunct != NULL) theDefrule = theDefrule->disjunct;
00213 else theDefrule = (struct defrule *) EnvGetNextDefrule(theEnv,theDefrule);
00214 }
00215
00216 moduleCount++;
00217 moduleArrayCount++;
00218 }
00219
00220 CloseDefruleFiles(theEnv,moduleFile,defruleFile,joinFile,linkFile,maxIndices);
00221
00222 return(1);
00223 }
00224
00225
00226
00227
00228 static int RuleCompilerTraverseJoins(
00229 void *theEnv,
00230 struct joinNode *joinPtr,
00231 char *fileName,
00232 char *pathName,
00233 char *fileNameBuffer,
00234 int fileID,
00235 FILE *headerFP,
00236 int imageID,
00237 int maxIndices,
00238 FILE **joinFile,
00239 FILE **linkFile,
00240 int *fileCount,
00241 int *joinArrayVersion,
00242 int *joinArrayCount,
00243 int *linkArrayVersion,
00244 int *linkArrayCount)
00245 {
00246 for (;
00247 joinPtr != NULL;
00248 joinPtr = joinPtr->lastLevel)
00249 {
00250 if (joinPtr->marked)
00251 {
00252 *joinFile = OpenFileIfNeeded(theEnv,*joinFile,fileName,pathName,fileNameBuffer,fileID,imageID,fileCount,
00253 *joinArrayVersion,headerFP,
00254 "struct joinNode",JoinPrefix(),FALSE,NULL);
00255 if (*joinFile == NULL)
00256 { return(FALSE); }
00257
00258 JoinToCode(theEnv,*joinFile,joinPtr,imageID,maxIndices);
00259 (*joinArrayCount)++;
00260 *joinFile = CloseFileIfNeeded(theEnv,*joinFile,joinArrayCount,joinArrayVersion,
00261 maxIndices,NULL,NULL);
00262
00263
00264 if (! TraverseJoinLinks(theEnv,joinPtr->nextLinks,fileName,pathName,fileNameBuffer,fileID,headerFP,imageID,
00265 maxIndices,linkFile,fileCount,linkArrayVersion,linkArrayCount))
00266 { return(FALSE); }
00267 }
00268
00269 if (joinPtr->joinFromTheRight)
00270 {
00271 if (RuleCompilerTraverseJoins(theEnv,(struct joinNode *) joinPtr->rightSideEntryStructure,fileName,pathName,
00272 fileNameBuffer,fileID,headerFP,imageID,maxIndices,joinFile,linkFile,fileCount,
00273 joinArrayVersion,joinArrayCount,
00274 linkArrayVersion,linkArrayCount) == FALSE)
00275 { return(FALSE); }
00276 }
00277 }
00278
00279 return(TRUE);
00280 }
00281
00282
00283
00284
00285 static int TraverseJoinLinks(
00286 void *theEnv,
00287 struct joinLink *linkPtr,
00288 char *fileName,
00289 char *pathName,
00290 char *fileNameBuffer,
00291 int fileID,
00292 FILE *headerFP,
00293 int imageID,
00294 int maxIndices,
00295 FILE **linkFile,
00296 int *fileCount,
00297 int *linkArrayVersion,
00298 int *linkArrayCount)
00299 {
00300 for (;
00301 linkPtr != NULL;
00302 linkPtr = linkPtr->next)
00303 {
00304 *linkFile = OpenFileIfNeeded(theEnv,*linkFile,fileName,pathName,fileNameBuffer,fileID,imageID,fileCount,
00305 *linkArrayVersion,headerFP,
00306 "struct joinLink",LinkPrefix(),FALSE,NULL);
00307
00308 if (*linkFile == NULL)
00309 { return(FALSE); }
00310
00311 LinkToCode(theEnv,*linkFile,linkPtr,imageID,maxIndices);
00312 (*linkArrayCount)++;
00313 *linkFile = CloseFileIfNeeded(theEnv,*linkFile,linkArrayCount,linkArrayVersion,
00314 maxIndices,NULL,NULL);
00315 }
00316
00317 return(TRUE);
00318 }
00319
00320
00321
00322
00323
00324
00325 static void CloseDefruleFiles(
00326 void *theEnv,
00327 FILE *moduleFile,
00328 FILE *defruleFile,
00329 FILE *joinFile,
00330 FILE *linkFile,
00331 int maxIndices)
00332 {
00333 int count = maxIndices;
00334 int arrayVersion = 0;
00335
00336 if (linkFile != NULL)
00337 {
00338 count = maxIndices;
00339 CloseFileIfNeeded(theEnv,linkFile,&count,&arrayVersion,maxIndices,NULL,NULL);
00340 }
00341
00342 if (joinFile != NULL)
00343 {
00344 count = maxIndices;
00345 CloseFileIfNeeded(theEnv,joinFile,&count,&arrayVersion,maxIndices,NULL,NULL);
00346 }
00347
00348 if (defruleFile != NULL)
00349 {
00350 count = maxIndices;
00351 CloseFileIfNeeded(theEnv,defruleFile,&count,&arrayVersion,maxIndices,NULL,NULL);
00352 }
00353
00354 if (moduleFile != NULL)
00355 {
00356 count = maxIndices;
00357 CloseFileIfNeeded(theEnv,moduleFile,&count,&arrayVersion,maxIndices,NULL,NULL);
00358 }
00359 }
00360
00361
00362
00363
00364
00365 #if WIN_BTC
00366 #pragma argsused
00367 #endif
00368 static void DefruleModuleToCode(
00369 void *theEnv,
00370 FILE *theFile,
00371 struct defmodule *theModule,
00372 int imageID,
00373 int maxIndices,
00374 int moduleCount)
00375 {
00376 #if MAC_MCW || WIN_MCW || MAC_XCD
00377 #pragma unused(moduleCount)
00378 #endif
00379
00380 fprintf(theFile,"{");
00381
00382 ConstructModuleToCode(theEnv,theFile,theModule,imageID,maxIndices,
00383 DefruleData(theEnv)->DefruleModuleIndex,ConstructPrefix(DefruleData(theEnv)->DefruleCodeItem));
00384
00385 fprintf(theFile,",NULL}");
00386 }
00387
00388
00389
00390
00391
00392 static void DefruleToCode(
00393 void *theEnv,
00394 FILE *theFile,
00395 struct defrule *theDefrule,
00396 int imageID,
00397 int maxIndices,
00398 int moduleCount)
00399 {
00400
00401
00402
00403
00404 fprintf(theFile,"{");
00405
00406 ConstructHeaderToCode(theEnv,theFile,&theDefrule->header,imageID,maxIndices,
00407 moduleCount,ModulePrefix(DefruleData(theEnv)->DefruleCodeItem),
00408 ConstructPrefix(DefruleData(theEnv)->DefruleCodeItem));
00409
00410
00411
00412
00413
00414 fprintf(theFile,",%d,%d,%d,%d,%d,%d,%d,%d,",
00415 theDefrule->salience,theDefrule->localVarCnt,
00416 theDefrule->complexity,theDefrule->afterBreakpoint,
00417 theDefrule->watchActivation,theDefrule->watchFiring,
00418 theDefrule->autoFocus,theDefrule->executing);
00419
00420
00421
00422
00423
00424 ExpressionToCode(theEnv,theFile,theDefrule->dynamicSalience);
00425 fprintf(theFile,",");
00426
00427
00428
00429
00430
00431 ExpressionToCode(theEnv,theFile,theDefrule->actions);
00432 fprintf(theFile,",");
00433
00434
00435
00436
00437
00438 if (theDefrule->logicalJoin != NULL)
00439 {
00440 fprintf(theFile,"&%s%d_%ld[%ld],",JoinPrefix(),
00441 imageID,(theDefrule->logicalJoin->bsaveID / maxIndices) + 1,
00442 theDefrule->logicalJoin->bsaveID % maxIndices);
00443 }
00444 else
00445 { fprintf(theFile,"NULL,"); }
00446
00447
00448
00449
00450
00451 if (theDefrule->lastJoin != NULL)
00452 {
00453 fprintf(theFile,"&%s%d_%ld[%ld],",JoinPrefix(),
00454 imageID,(theDefrule->lastJoin->bsaveID / maxIndices) + 1,
00455 theDefrule->lastJoin->bsaveID % maxIndices);
00456 }
00457 else
00458 { fprintf(theFile,"NULL,"); }
00459
00460
00461
00462
00463
00464 if (theDefrule->disjunct != NULL)
00465 {
00466 fprintf(theFile,"&%s%d_%ld[%ld]}",ConstructPrefix(DefruleData(theEnv)->DefruleCodeItem),
00467 imageID,(theDefrule->disjunct->header.bsaveID / maxIndices) + 1,
00468 theDefrule->disjunct->header.bsaveID % maxIndices);
00469 }
00470 else
00471 { fprintf(theFile,"NULL}"); }
00472 }
00473
00474
00475
00476
00477
00478 static void JoinToCode(
00479 void *theEnv,
00480 FILE *joinFile,
00481 struct joinNode *theJoin,
00482 int imageID,
00483 int maxIndices)
00484 {
00485 struct patternParser *theParser;
00486
00487
00488
00489
00490
00491 theJoin->marked = 0;
00492
00493
00494
00495
00496
00497 fprintf(joinFile,"{%d,%d,%d,%d,%d,0,0,%d,%d,0,0,0,0,",
00498 theJoin->firstJoin,theJoin->logicalJoin,
00499 theJoin->joinFromTheRight,theJoin->patternIsNegated,
00500 theJoin->patternIsExists,
00501 theJoin->rhsType,theJoin->depth);
00502
00503
00504
00505
00506
00507 fprintf(joinFile,"NULL,NULL,");
00508
00509
00510
00511
00512
00513 PrintHashedExpressionReference(theEnv,joinFile,theJoin->networkTest,imageID,maxIndices);
00514 fprintf(joinFile,",");
00515
00516 PrintHashedExpressionReference(theEnv,joinFile,theJoin->secondaryNetworkTest,imageID,maxIndices);
00517 fprintf(joinFile,",");
00518
00519 PrintHashedExpressionReference(theEnv,joinFile,theJoin->leftHash,imageID,maxIndices);
00520 fprintf(joinFile,",");
00521
00522 PrintHashedExpressionReference(theEnv,joinFile,theJoin->rightHash,imageID,maxIndices);
00523 fprintf(joinFile,",");
00524
00525
00526
00527
00528
00529 if (theJoin->rightSideEntryStructure == NULL)
00530 { fprintf(joinFile,"NULL,"); }
00531 else if (theJoin->joinFromTheRight == FALSE)
00532 {
00533 theParser = GetPatternParser(theEnv,(int) theJoin->rhsType);
00534 if (theParser->codeReferenceFunction == NULL) fprintf(joinFile,"NULL,");
00535 else
00536 {
00537 fprintf(joinFile,"VS ");
00538 (*theParser->codeReferenceFunction)(theEnv,theJoin->rightSideEntryStructure,
00539 joinFile,imageID,maxIndices);
00540 fprintf(joinFile,",");
00541 }
00542 }
00543 else
00544 {
00545 fprintf(joinFile,"&%s%d_%ld[%ld],",JoinPrefix(),
00546 imageID,(((struct joinNode *) theJoin->rightSideEntryStructure)->bsaveID / maxIndices) + 1,
00547 ((struct joinNode *) theJoin->rightSideEntryStructure)->bsaveID % maxIndices);
00548 }
00549
00550
00551
00552
00553
00554 if (theJoin->nextLinks == NULL)
00555 { fprintf(joinFile,"NULL,"); }
00556 else
00557 {
00558 fprintf(joinFile,"&%s%d_%ld[%ld],",LinkPrefix(),
00559 imageID,(theJoin->nextLinks->bsaveID / maxIndices) + 1,
00560 theJoin->nextLinks->bsaveID % maxIndices);
00561 }
00562
00563
00564
00565
00566
00567 if (theJoin->lastLevel == NULL)
00568 { fprintf(joinFile,"NULL,"); }
00569 else
00570 {
00571 fprintf(joinFile,"&%s%d_%ld[%ld],",JoinPrefix(),
00572 imageID,(theJoin->lastLevel->bsaveID / maxIndices) + 1,
00573 theJoin->lastLevel->bsaveID % maxIndices);
00574 }
00575
00576
00577
00578
00579
00580 if (theJoin->rightMatchNode == NULL)
00581 { fprintf(joinFile,"NULL,"); }
00582 else
00583 {
00584 fprintf(joinFile,"&%s%d_%ld[%ld],",JoinPrefix(),
00585 imageID,(theJoin->rightMatchNode->bsaveID / maxIndices) + 1,
00586 theJoin->rightMatchNode->bsaveID % maxIndices);
00587 }
00588
00589
00590
00591
00592
00593 if (theJoin->ruleToActivate == NULL)
00594 { fprintf(joinFile,"NULL}"); }
00595 else
00596 {
00597 fprintf(joinFile,"&%s%d_%ld[%ld]}",ConstructPrefix(DefruleData(theEnv)->DefruleCodeItem),imageID,
00598 (theJoin->ruleToActivate->header.bsaveID / maxIndices) + 1,
00599 theJoin->ruleToActivate->header.bsaveID % maxIndices);
00600 }
00601 }
00602
00603
00604
00605
00606
00607 static void LinkToCode(
00608 void *theEnv,
00609 FILE *theFile,
00610 struct joinLink *theLink,
00611 int imageID,
00612 int maxIndices)
00613 {
00614
00615
00616
00617
00618 fprintf(theFile,"{%d,",theLink->enterDirection);
00619
00620
00621
00622
00623
00624 if (theLink->join == NULL)
00625 { fprintf(theFile,"NULL,"); }
00626 else
00627 {
00628 fprintf(theFile,"&%s%d_%ld[%ld],",JoinPrefix(),
00629 imageID,(theLink->join->bsaveID / maxIndices) + 1,
00630 theLink->join->bsaveID % maxIndices);
00631 }
00632
00633
00634
00635
00636
00637 if (theLink->next == NULL)
00638 { fprintf(theFile,"NULL,"); }
00639 else
00640 {
00641 fprintf(theFile,"&%s%d_%ld[%ld],",LinkPrefix(),
00642 imageID,(theLink->next->bsaveID / maxIndices) + 1,
00643 theLink->next->bsaveID % maxIndices);
00644 }
00645
00646
00647
00648
00649
00650 fprintf(theFile,"0}");
00651 }
00652
00653
00654
00655
00656
00657 globle void DefruleCModuleReference(
00658 void *theEnv,
00659 FILE *theFile,
00660 int count,
00661 int imageID,
00662 int maxIndices)
00663 {
00664 fprintf(theFile,"MIHS &%s%d_%d[%d]",ModulePrefix(DefruleData(theEnv)->DefruleCodeItem),
00665 imageID,
00666 (count / maxIndices) + 1,
00667 (count % maxIndices));
00668 }
00669
00670
00671
00672
00673
00674 #if WIN_BTC
00675 #pragma argsused
00676 #endif
00677 static void InitDefruleCode(
00678 void *theEnv,
00679 FILE *initFP,
00680 int imageID,
00681 int maxIndices)
00682 {
00683 #if MAC_MCW || WIN_MCW || MAC_XCD
00684 #pragma unused(maxIndices)
00685 #pragma unused(theEnv)
00686 #pragma unused(imageID)
00687 #endif
00688
00689 fprintf(initFP," DefruleRunTimeInitialize(theEnv,");
00690
00691 if (DefruleData(theEnv)->RightPrimeJoins == NULL)
00692 { fprintf(initFP,"NULL,"); }
00693 else
00694 {
00695 fprintf(initFP,"&%s%d_%ld[%ld],",LinkPrefix(),
00696 imageID,(DefruleData(theEnv)->RightPrimeJoins->bsaveID / maxIndices) + 1,
00697 DefruleData(theEnv)->RightPrimeJoins->bsaveID % maxIndices);
00698 }
00699
00700 if (DefruleData(theEnv)->LeftPrimeJoins == NULL)
00701 { fprintf(initFP,"NULL);\n"); }
00702 else
00703 {
00704 fprintf(initFP,"&%s%d_%ld[%ld]);\n",LinkPrefix(),
00705 imageID,(DefruleData(theEnv)->LeftPrimeJoins->bsaveID / maxIndices) + 1,
00706 DefruleData(theEnv)->LeftPrimeJoins->bsaveID % maxIndices);
00707 }
00708 }
00709
00710 #endif
00711
00712