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
00032
00033
00034 #include "setup.h"
00035
00036 #if FACT_SET_QUERIES
00037
00038 #include "argacces.h"
00039 #include "envrnmnt.h"
00040 #include "memalloc.h"
00041 #include "exprnpsr.h"
00042 #include "modulutl.h"
00043 #include "tmpltutl.h"
00044 #include "insfun.h"
00045 #include "factqpsr.h"
00046 #include "prcdrfun.h"
00047 #include "router.h"
00048 #include "utility.h"
00049
00050 #define _FACTQURY_SOURCE_
00051 #include "factqury.h"
00052
00053
00054
00055
00056
00057
00058
00059 static void PushQueryCore(void *);
00060 static void PopQueryCore(void *);
00061 static QUERY_CORE *FindQueryCore(void *,int);
00062 static QUERY_TEMPLATE *DetermineQueryTemplates(void *,EXPRESSION *,char *,unsigned *);
00063 static QUERY_TEMPLATE *FormChain(void *,char *,DATA_OBJECT *);
00064 static void DeleteQueryTemplates(void *,QUERY_TEMPLATE *);
00065 static int TestForFirstInChain(void *,QUERY_TEMPLATE *,int);
00066 static int TestForFirstFactInTemplate(void *,struct deftemplate *,QUERY_TEMPLATE *,int);
00067 static void TestEntireChain(void *,QUERY_TEMPLATE *,int);
00068 static void TestEntireTemplate(void *,struct deftemplate *,QUERY_TEMPLATE *,int);
00069 static void AddSolution(void *);
00070 static void PopQuerySoln(void *);
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 globle void SetupFactQuery(
00082 void *theEnv)
00083 {
00084 AllocateEnvironmentData(theEnv,FACT_QUERY_DATA,sizeof(struct factQueryData),NULL);
00085
00086 #if RUN_TIME
00087 FactQueryData(theEnv)->QUERY_DELIMETER_SYMBOL = FindSymbolHN(theEnv,QUERY_DELIMETER_STRING);
00088 #endif
00089
00090 #if ! RUN_TIME
00091 FactQueryData(theEnv)->QUERY_DELIMETER_SYMBOL = (SYMBOL_HN *) EnvAddSymbol(theEnv,QUERY_DELIMETER_STRING);
00092 IncrementSymbolCount(FactQueryData(theEnv)->QUERY_DELIMETER_SYMBOL);
00093
00094 EnvDefineFunction2(theEnv,"(query-fact)",'u',
00095 PTIEF GetQueryFact,"GetQueryFact",NULL);
00096
00097 EnvDefineFunction2(theEnv,"(query-fact-slot)",'u',
00098 PTIEF GetQueryFactSlot,"GetQueryFactSlot",NULL);
00099
00100 EnvDefineFunction2(theEnv,"any-factp",'b',PTIEF AnyFacts,"AnyFacts",NULL);
00101 AddFunctionParser(theEnv,"any-factp",FactParseQueryNoAction);
00102
00103 EnvDefineFunction2(theEnv,"find-fact",'m',
00104 PTIEF QueryFindFact,"QueryFindFact",NULL);
00105 AddFunctionParser(theEnv,"find-fact",FactParseQueryNoAction);
00106
00107 EnvDefineFunction2(theEnv,"find-all-facts",'m',
00108 PTIEF QueryFindAllFacts,"QueryFindAllFacts",NULL);
00109 AddFunctionParser(theEnv,"find-all-facts",FactParseQueryNoAction);
00110
00111 EnvDefineFunction2(theEnv,"do-for-fact",'u',
00112 PTIEF QueryDoForFact,"QueryDoForFact",NULL);
00113 AddFunctionParser(theEnv,"do-for-fact",FactParseQueryAction);
00114
00115 EnvDefineFunction2(theEnv,"do-for-all-facts",'u',
00116 PTIEF QueryDoForAllFacts,"QueryDoForAllFacts",NULL);
00117 AddFunctionParser(theEnv,"do-for-all-facts",FactParseQueryAction);
00118
00119 EnvDefineFunction2(theEnv,"delayed-do-for-all-facts",'u',
00120 PTIEF DelayedQueryDoForAllFacts,
00121 "DelayedQueryDoForAllFacts",NULL);
00122 AddFunctionParser(theEnv,"delayed-do-for-all-facts",FactParseQueryAction);
00123 #endif
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 globle void GetQueryFact(
00136 void *theEnv,
00137 DATA_OBJECT *result)
00138 {
00139 register QUERY_CORE *core;
00140
00141 core = FindQueryCore(theEnv,ValueToInteger(GetpValue(GetFirstArgument())));
00142
00143 result->type = FACT_ADDRESS;
00144 result->value = core->solns[ValueToInteger(GetpValue(GetFirstArgument()->nextArg))];
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 globle void GetQueryFactSlot(
00157 void *theEnv,
00158 DATA_OBJECT *result)
00159 {
00160 struct fact *theFact;
00161 DATA_OBJECT temp;
00162 QUERY_CORE *core;
00163 short position;
00164
00165 result->type = SYMBOL;
00166 result->value = EnvFalseSymbol(theEnv);
00167
00168 core = FindQueryCore(theEnv,ValueToInteger(GetpValue(GetFirstArgument())));
00169 theFact = core->solns[ValueToInteger(GetpValue(GetFirstArgument()->nextArg))];
00170 EvaluateExpression(theEnv,GetFirstArgument()->nextArg->nextArg,&temp);
00171 if (temp.type != SYMBOL)
00172 {
00173 ExpectedTypeError1(theEnv,"get",1,"symbol");
00174 SetEvaluationError(theEnv,TRUE);
00175 return;
00176 }
00177
00178
00179
00180
00181
00182
00183 if (theFact->whichDeftemplate->implied)
00184 {
00185 if (strcmp(ValueToString(temp.value),"implied") != 0)
00186 {
00187 SlotExistError(theEnv,ValueToString(temp.value),"fact-set query");
00188 return;
00189 }
00190 position = 1;
00191 }
00192
00193 else if (FindSlot((struct deftemplate *) theFact->whichDeftemplate,
00194 (struct symbolHashNode *) temp.value,&position) == NULL)
00195 {
00196 SlotExistError(theEnv,ValueToString(temp.value),"fact-set query");
00197 return;
00198 }
00199
00200 result->type = theFact->theProposition.theFields[position-1].type;
00201 result->value = theFact->theProposition.theFields[position-1].value;
00202 if (result->type == MULTIFIELD)
00203 {
00204 SetpDOBegin(result,1);
00205 SetpDOEnd(result,((struct multifield *) result->value)->multifieldLength);
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 globle intBool AnyFacts(
00269 void *theEnv)
00270 {
00271 QUERY_TEMPLATE *qtemplates;
00272 unsigned rcnt;
00273 int TestResult;
00274
00275 qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
00276 "any-factp",&rcnt);
00277 if (qtemplates == NULL)
00278 return(FALSE);
00279 PushQueryCore(theEnv);
00280 FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00281 FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
00282 FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00283 TestResult = TestForFirstInChain(theEnv,qtemplates,0);
00284 FactQueryData(theEnv)->AbortQuery = FALSE;
00285 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
00286 rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
00287 PopQueryCore(theEnv);
00288 DeleteQueryTemplates(theEnv,qtemplates);
00289 return(TestResult);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 globle void QueryFindFact(
00305 void *theEnv,
00306 DATA_OBJECT *result)
00307 {
00308 QUERY_TEMPLATE *qtemplates;
00309 unsigned rcnt,i;
00310
00311 result->type = MULTIFIELD;
00312 result->begin = 0;
00313 result->end = -1;
00314 qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
00315 "find-fact",&rcnt);
00316 if (qtemplates == NULL)
00317 {
00318 result->value = (void *) EnvCreateMultifield(theEnv,0L);
00319 return;
00320 }
00321 PushQueryCore(theEnv);
00322 FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00323 FactQueryData(theEnv)->QueryCore->solns = (struct fact **)
00324 gm2(theEnv,(sizeof(struct fact *) * rcnt));
00325 FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00326 if (TestForFirstInChain(theEnv,qtemplates,0) == TRUE)
00327 {
00328 result->value = (void *) EnvCreateMultifield(theEnv,rcnt);
00329 SetpDOEnd(result,rcnt);
00330 for (i = 1 ; i <= rcnt ; i++)
00331 {
00332 SetMFType(result->value,i,FACT_ADDRESS);
00333 SetMFValue(result->value,i,FactQueryData(theEnv)->QueryCore->solns[i - 1]);
00334 }
00335 }
00336 else
00337 result->value = (void *) EnvCreateMultifield(theEnv,0L);
00338 FactQueryData(theEnv)->AbortQuery = FALSE;
00339 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
00340 rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
00341 PopQueryCore(theEnv);
00342 DeleteQueryTemplates(theEnv,qtemplates);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 globle void QueryFindAllFacts(
00364 void *theEnv,
00365 DATA_OBJECT *result)
00366 {
00367 QUERY_TEMPLATE *qtemplates;
00368 unsigned rcnt;
00369 register unsigned i,j;
00370
00371 result->type = MULTIFIELD;
00372 result->begin = 0;
00373 result->end = -1;
00374 qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg,
00375 "find-all-facts",&rcnt);
00376 if (qtemplates == NULL)
00377 {
00378 result->value = (void *) EnvCreateMultifield(theEnv,0L);
00379 return;
00380 }
00381 PushQueryCore(theEnv);
00382 FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00383 FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
00384 FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00385 FactQueryData(theEnv)->QueryCore->action = NULL;
00386 FactQueryData(theEnv)->QueryCore->soln_set = NULL;
00387 FactQueryData(theEnv)->QueryCore->soln_size = rcnt;
00388 FactQueryData(theEnv)->QueryCore->soln_cnt = 0;
00389 TestEntireChain(theEnv,qtemplates,0);
00390 FactQueryData(theEnv)->AbortQuery = FALSE;
00391 result->value = (void *) EnvCreateMultifield(theEnv,FactQueryData(theEnv)->QueryCore->soln_cnt * rcnt);
00392 while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
00393 {
00394 for (i = 0 , j = (unsigned) (result->end + 2) ; i < rcnt ; i++ , j++)
00395 {
00396 SetMFType(result->value,j,FACT_ADDRESS);
00397 SetMFValue(result->value,j,FactQueryData(theEnv)->QueryCore->soln_set->soln[i]);
00398 }
00399 result->end = (long) j-2;
00400 PopQuerySoln(theEnv);
00401 }
00402 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
00403 rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
00404 PopQueryCore(theEnv);
00405 DeleteQueryTemplates(theEnv,qtemplates);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 globle void QueryDoForFact(
00423 void *theEnv,
00424 DATA_OBJECT *result)
00425 {
00426 QUERY_TEMPLATE *qtemplates;
00427 unsigned rcnt;
00428
00429 result->type = SYMBOL;
00430 result->value = EnvFalseSymbol(theEnv);
00431 qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
00432 "do-for-fact",&rcnt);
00433 if (qtemplates == NULL)
00434 return;
00435 PushQueryCore(theEnv);
00436 FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00437 FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
00438 FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00439 FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
00440 if (TestForFirstInChain(theEnv,qtemplates,0) == TRUE)
00441 EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,result);
00442 FactQueryData(theEnv)->AbortQuery = FALSE;
00443 ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
00444 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
00445 rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
00446 PopQueryCore(theEnv);
00447 DeleteQueryTemplates(theEnv,qtemplates);
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 globle void QueryDoForAllFacts(
00464 void *theEnv,
00465 DATA_OBJECT *result)
00466 {
00467 QUERY_TEMPLATE *qtemplates;
00468 unsigned rcnt;
00469
00470 result->type = SYMBOL;
00471 result->value = EnvFalseSymbol(theEnv);
00472 qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
00473 "do-for-all-facts",&rcnt);
00474 if (qtemplates == NULL)
00475 return;
00476 PushQueryCore(theEnv);
00477 FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00478 FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
00479 FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00480 FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
00481 FactQueryData(theEnv)->QueryCore->result = result;
00482 ValueInstall(theEnv,FactQueryData(theEnv)->QueryCore->result);
00483 TestEntireChain(theEnv,qtemplates,0);
00484 ValueDeinstall(theEnv,FactQueryData(theEnv)->QueryCore->result);
00485 PropagateReturnValue(theEnv,FactQueryData(theEnv)->QueryCore->result);
00486 FactQueryData(theEnv)->AbortQuery = FALSE;
00487 ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
00488 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
00489 rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
00490 PopQueryCore(theEnv);
00491 DeleteQueryTemplates(theEnv,qtemplates);
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 globle void DelayedQueryDoForAllFacts(
00512 void *theEnv,
00513 DATA_OBJECT *result)
00514 {
00515 QUERY_TEMPLATE *qtemplates;
00516 unsigned rcnt;
00517 register unsigned i;
00518
00519 result->type = SYMBOL;
00520 result->value = EnvFalseSymbol(theEnv);
00521 qtemplates = DetermineQueryTemplates(theEnv,GetFirstArgument()->nextArg->nextArg,
00522 "delayed-do-for-all-facts",&rcnt);
00523 if (qtemplates == NULL)
00524 return;
00525 PushQueryCore(theEnv);
00526 FactQueryData(theEnv)->QueryCore = get_struct(theEnv,query_core);
00527 FactQueryData(theEnv)->QueryCore->solns = (struct fact **) gm2(theEnv,(sizeof(struct fact *) * rcnt));
00528 FactQueryData(theEnv)->QueryCore->query = GetFirstArgument();
00529 FactQueryData(theEnv)->QueryCore->action = NULL;
00530 FactQueryData(theEnv)->QueryCore->soln_set = NULL;
00531 FactQueryData(theEnv)->QueryCore->soln_size = rcnt;
00532 FactQueryData(theEnv)->QueryCore->soln_cnt = 0;
00533 TestEntireChain(theEnv,qtemplates,0);
00534 FactQueryData(theEnv)->AbortQuery = FALSE;
00535 FactQueryData(theEnv)->QueryCore->action = GetFirstArgument()->nextArg;
00536 while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
00537 {
00538 for (i = 0 ; i < rcnt ; i++)
00539 FactQueryData(theEnv)->QueryCore->solns[i] = FactQueryData(theEnv)->QueryCore->soln_set->soln[i];
00540 PopQuerySoln(theEnv);
00541 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00542 EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,result);
00543 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00544 if (ProcedureFunctionData(theEnv)->ReturnFlag == TRUE)
00545 { PropagateReturnValue(theEnv,result); }
00546 PeriodicCleanup(theEnv,FALSE,TRUE);
00547 if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
00548 {
00549 while (FactQueryData(theEnv)->QueryCore->soln_set != NULL)
00550 PopQuerySoln(theEnv);
00551 break;
00552 }
00553 }
00554 ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
00555 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->solns,(sizeof(struct fact *) * rcnt));
00556 rtn_struct(theEnv,query_core,FactQueryData(theEnv)->QueryCore);
00557 PopQueryCore(theEnv);
00558 DeleteQueryTemplates(theEnv,qtemplates);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 static void PushQueryCore(
00577 void *theEnv)
00578 {
00579 QUERY_STACK *qptr;
00580
00581 qptr = get_struct(theEnv,query_stack);
00582 qptr->core = FactQueryData(theEnv)->QueryCore;
00583 qptr->nxt = FactQueryData(theEnv)->QueryCoreStack;
00584 FactQueryData(theEnv)->QueryCoreStack = qptr;
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 static void PopQueryCore(
00598 void *theEnv)
00599 {
00600 QUERY_STACK *qptr;
00601
00602 FactQueryData(theEnv)->QueryCore = FactQueryData(theEnv)->QueryCoreStack->core;
00603 qptr = FactQueryData(theEnv)->QueryCoreStack;
00604 FactQueryData(theEnv)->QueryCoreStack = FactQueryData(theEnv)->QueryCoreStack->nxt;
00605 rtn_struct(theEnv,query_stack,qptr);
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 static QUERY_CORE *FindQueryCore(
00619 void *theEnv,
00620 int depth)
00621 {
00622 QUERY_STACK *qptr;
00623
00624 if (depth == 0)
00625 return(FactQueryData(theEnv)->QueryCore);
00626 qptr = FactQueryData(theEnv)->QueryCoreStack;
00627 while (depth > 1)
00628 {
00629 qptr = qptr->nxt;
00630 depth--;
00631 }
00632 return(qptr->core);
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 static QUERY_TEMPLATE *DetermineQueryTemplates(
00656 void *theEnv,
00657 EXPRESSION *templateExp,
00658 char *func,
00659 unsigned *rcnt)
00660 {
00661 QUERY_TEMPLATE *clist = NULL,*cnxt = NULL,*cchain = NULL,*tmp;
00662 int new_list = FALSE;
00663 DATA_OBJECT temp;
00664
00665 *rcnt = 0;
00666 while (templateExp != NULL)
00667 {
00668 if (EvaluateExpression(theEnv,templateExp,&temp))
00669 {
00670 DeleteQueryTemplates(theEnv,clist);
00671 return(NULL);
00672 }
00673 if ((temp.type == SYMBOL) && (temp.value == (void *) FactQueryData(theEnv)->QUERY_DELIMETER_SYMBOL))
00674 {
00675 new_list = TRUE;
00676 (*rcnt)++;
00677 }
00678 else if ((tmp = FormChain(theEnv,func,&temp)) != NULL)
00679 {
00680 if (clist == NULL)
00681 clist = cnxt = cchain = tmp;
00682 else if (new_list == TRUE)
00683 {
00684 new_list = FALSE;
00685 cnxt->nxt = tmp;
00686 cnxt = cchain = tmp;
00687 }
00688 else
00689 cchain->chain = tmp;
00690 while (cchain->chain != NULL)
00691 cchain = cchain->chain;
00692 }
00693 else
00694 {
00695 SyntaxErrorMessage(theEnv,"fact-set query class restrictions");
00696 DeleteQueryTemplates(theEnv,clist);
00697 SetEvaluationError(theEnv,TRUE);
00698 return(NULL);
00699 }
00700 templateExp = templateExp->nextArg;
00701 }
00702 return(clist);
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 static QUERY_TEMPLATE *FormChain(
00719 void *theEnv,
00720 char *func,
00721 DATA_OBJECT *val)
00722 {
00723 struct deftemplate *templatePtr;
00724 QUERY_TEMPLATE *head,*bot,*tmp;
00725 register long i,end;
00726 char *templateName;
00727 int count;
00728
00729 if (val->type == DEFTEMPLATE_PTR)
00730 {
00731 IncrementDeftemplateBusyCount(theEnv,(void *) val->value);
00732 head = get_struct(theEnv,query_template);
00733 head->templatePtr = (struct deftemplate *) val->value;
00734
00735 head->chain = NULL;
00736 head->nxt = NULL;
00737 return(head);
00738 }
00739 if (val->type == SYMBOL)
00740 {
00741
00742
00743
00744
00745
00746
00747
00748 templatePtr = (struct deftemplate *)
00749 FindImportedConstruct(theEnv,"deftemplate",NULL,DOPToString(val),
00750 &count,TRUE,NULL);
00751 if (templatePtr == NULL)
00752 {
00753 CantFindItemInFunctionErrorMessage(theEnv,"deftemplate",DOPToString(val),func);
00754 return(NULL);
00755 }
00756 IncrementDeftemplateBusyCount(theEnv,(void *) templatePtr);
00757 head = get_struct(theEnv,query_template);
00758 head->templatePtr = templatePtr;
00759
00760 head->chain = NULL;
00761 head->nxt = NULL;
00762 return(head);
00763 }
00764 if (val->type == MULTIFIELD)
00765 {
00766 head = bot = NULL;
00767 end = GetpDOEnd(val);
00768 for (i = GetpDOBegin(val) ; i <= end ; i++)
00769 {
00770 if (GetMFType(val->value,i) == SYMBOL)
00771 {
00772 templateName = ValueToString(GetMFValue(val->value,i));
00773
00774 templatePtr = (struct deftemplate *)
00775 FindImportedConstruct(theEnv,"deftemplate",NULL,templateName,
00776 &count,TRUE,NULL);
00777
00778 if (templatePtr == NULL)
00779 {
00780 CantFindItemInFunctionErrorMessage(theEnv,"deftemplate",templateName,func);
00781 DeleteQueryTemplates(theEnv,head);
00782 return(NULL);
00783 }
00784 }
00785 else
00786 {
00787 DeleteQueryTemplates(theEnv,head);
00788 return(NULL);
00789 }
00790 IncrementDeftemplateBusyCount(theEnv,(void *) templatePtr);
00791 tmp = get_struct(theEnv,query_template);
00792 tmp->templatePtr = templatePtr;
00793
00794 tmp->chain = NULL;
00795 tmp->nxt = NULL;
00796 if (head == NULL)
00797 head = tmp;
00798 else
00799 bot->chain = tmp;
00800 bot = tmp;
00801 }
00802 return(head);
00803 }
00804 return(NULL);
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 static void DeleteQueryTemplates(
00817 void *theEnv,
00818 QUERY_TEMPLATE *qlist)
00819 {
00820 QUERY_TEMPLATE *tmp;
00821
00822 while (qlist != NULL)
00823 {
00824 while (qlist->chain != NULL)
00825 {
00826 tmp = qlist->chain;
00827 qlist->chain = qlist->chain->chain;
00828 DecrementDeftemplateBusyCount(theEnv,(void *) tmp->templatePtr);
00829 rtn_struct(theEnv,query_template,tmp);
00830 }
00831 tmp = qlist;
00832 qlist = qlist->nxt;
00833 DecrementDeftemplateBusyCount(theEnv,(void *) tmp->templatePtr);
00834 rtn_struct(theEnv,query_template,tmp);
00835 }
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 static int TestForFirstInChain(
00851 void *theEnv,
00852 QUERY_TEMPLATE *qchain,
00853 int indx)
00854 {
00855 QUERY_TEMPLATE *qptr;
00856
00857 FactQueryData(theEnv)->AbortQuery = TRUE;
00858 for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain)
00859 {
00860 FactQueryData(theEnv)->AbortQuery = FALSE;
00861
00862 if (TestForFirstFactInTemplate(theEnv,qptr->templatePtr,qchain,indx))
00863 { return(TRUE); }
00864
00865 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (FactQueryData(theEnv)->AbortQuery == TRUE))
00866 return(FALSE);
00867 }
00868 return(FALSE);
00869 }
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 static int TestForFirstFactInTemplate(
00883 void *theEnv,
00884 struct deftemplate *templatePtr,
00885 QUERY_TEMPLATE *qchain,
00886 int indx)
00887 {
00888 struct fact *theFact;
00889 DATA_OBJECT temp;
00890
00891 theFact = templatePtr->factList;
00892 while (theFact != NULL)
00893 {
00894 FactQueryData(theEnv)->QueryCore->solns[indx] = theFact;
00895 if (qchain->nxt != NULL)
00896 {
00897 theFact->factHeader.busyCount++;
00898 if (TestForFirstInChain(theEnv,qchain->nxt,indx+1) == TRUE)
00899 {
00900 theFact->factHeader.busyCount--;
00901 break;
00902 }
00903 theFact->factHeader.busyCount--;
00904 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (FactQueryData(theEnv)->AbortQuery == TRUE))
00905 break;
00906 }
00907 else
00908 {
00909 theFact->factHeader.busyCount++;
00910 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00911 EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->query,&temp);
00912 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00913 PeriodicCleanup(theEnv,FALSE,TRUE);
00914 theFact->factHeader.busyCount--;
00915 if (EvaluationData(theEnv)->HaltExecution == TRUE)
00916 break;
00917 if ((temp.type != SYMBOL) ? TRUE :
00918 (temp.value != EnvFalseSymbol(theEnv)))
00919 break;
00920 }
00921 theFact = theFact->nextTemplateFact;
00922 while ((theFact != NULL) ? (theFact->garbage == 1) : FALSE)
00923 theFact = theFact->nextTemplateFact;
00924 }
00925
00926 if (theFact != NULL)
00927 return(((EvaluationData(theEnv)->HaltExecution == TRUE) || (FactQueryData(theEnv)->AbortQuery == TRUE))
00928 ? FALSE : TRUE);
00929
00930 return(FALSE);
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 static void TestEntireChain(
00947 void *theEnv,
00948 QUERY_TEMPLATE *qchain,
00949 int indx)
00950 {
00951 QUERY_TEMPLATE *qptr;
00952
00953 FactQueryData(theEnv)->AbortQuery = TRUE;
00954 for (qptr = qchain ; qptr != NULL ; qptr = qptr->chain)
00955 {
00956 FactQueryData(theEnv)->AbortQuery = FALSE;
00957
00958 TestEntireTemplate(theEnv,qptr->templatePtr,qchain,indx);
00959
00960 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (FactQueryData(theEnv)->AbortQuery == TRUE))
00961 return;
00962 }
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 static void TestEntireTemplate(
00979 void *theEnv,
00980 struct deftemplate *templatePtr,
00981 QUERY_TEMPLATE *qchain,
00982 int indx)
00983 {
00984 struct fact *theFact;
00985 DATA_OBJECT temp;
00986
00987 theFact = templatePtr->factList;
00988 while (theFact != NULL)
00989 {
00990 FactQueryData(theEnv)->QueryCore->solns[indx] = theFact;
00991 if (qchain->nxt != NULL)
00992 {
00993 theFact->factHeader.busyCount++;
00994 TestEntireChain(theEnv,qchain->nxt,indx+1);
00995 theFact->factHeader.busyCount--;
00996 if ((EvaluationData(theEnv)->HaltExecution == TRUE) || (FactQueryData(theEnv)->AbortQuery == TRUE))
00997 break;
00998 }
00999 else
01000 {
01001 theFact->factHeader.busyCount++;
01002 EvaluationData(theEnv)->CurrentEvaluationDepth++;
01003 EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->query,&temp);
01004 EvaluationData(theEnv)->CurrentEvaluationDepth--;
01005 PeriodicCleanup(theEnv,FALSE,TRUE);
01006 theFact->factHeader.busyCount--;
01007 if (EvaluationData(theEnv)->HaltExecution == TRUE)
01008 break;
01009 if ((temp.type != SYMBOL) ? TRUE :
01010 (temp.value != EnvFalseSymbol(theEnv)))
01011 {
01012 if (FactQueryData(theEnv)->QueryCore->action != NULL)
01013 {
01014 theFact->factHeader.busyCount++;
01015 EvaluationData(theEnv)->CurrentEvaluationDepth++;
01016 ValueDeinstall(theEnv,FactQueryData(theEnv)->QueryCore->result);
01017 EvaluateExpression(theEnv,FactQueryData(theEnv)->QueryCore->action,FactQueryData(theEnv)->QueryCore->result);
01018 ValueInstall(theEnv,FactQueryData(theEnv)->QueryCore->result);
01019 EvaluationData(theEnv)->CurrentEvaluationDepth--;
01020 PeriodicCleanup(theEnv,FALSE,TRUE);
01021 theFact->factHeader.busyCount--;
01022 if (ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
01023 {
01024 FactQueryData(theEnv)->AbortQuery = TRUE;
01025 break;
01026 }
01027 if (EvaluationData(theEnv)->HaltExecution == TRUE)
01028 break;
01029 }
01030 else
01031 AddSolution(theEnv);
01032 }
01033 }
01034
01035 theFact = theFact->nextTemplateFact;
01036 while ((theFact != NULL) ? (theFact->garbage == 1) : FALSE)
01037 theFact = theFact->nextTemplateFact;
01038 }
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 static void AddSolution(
01051 void *theEnv)
01052 {
01053 QUERY_SOLN *new_soln;
01054 register unsigned i;
01055
01056 new_soln = (QUERY_SOLN *) gm2(theEnv,(int) sizeof(QUERY_SOLN));
01057 new_soln->soln = (struct fact **)
01058 gm2(theEnv,(sizeof(struct fact *) * (FactQueryData(theEnv)->QueryCore->soln_size)));
01059 for (i = 0 ; i < FactQueryData(theEnv)->QueryCore->soln_size ; i++)
01060 new_soln->soln[i] = FactQueryData(theEnv)->QueryCore->solns[i];
01061 new_soln->nxt = NULL;
01062 if (FactQueryData(theEnv)->QueryCore->soln_set == NULL)
01063 FactQueryData(theEnv)->QueryCore->soln_set = new_soln;
01064 else
01065 FactQueryData(theEnv)->QueryCore->soln_bottom->nxt = new_soln;
01066 FactQueryData(theEnv)->QueryCore->soln_bottom = new_soln;
01067 FactQueryData(theEnv)->QueryCore->soln_cnt++;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 static void PopQuerySoln(
01080 void *theEnv)
01081 {
01082 FactQueryData(theEnv)->QueryCore->soln_bottom = FactQueryData(theEnv)->QueryCore->soln_set;
01083 FactQueryData(theEnv)->QueryCore->soln_set = FactQueryData(theEnv)->QueryCore->soln_set->nxt;
01084 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->soln_bottom->soln,
01085 (sizeof(struct fact *) * FactQueryData(theEnv)->QueryCore->soln_size));
01086 rm(theEnv,(void *) FactQueryData(theEnv)->QueryCore->soln_bottom,sizeof(QUERY_SOLN));
01087 }
01088
01089 #endif
01090
01091