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 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028
00029 #include "debugs/debug_tables.h"
00030 #include "debugs/debug_delay.h"
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035
00036 #include "auxlry.h"
00037 #include "cell_xsb.h"
00038 #include "heap_xsb.h"
00039 #include "memory_xsb.h"
00040 #include "register.h"
00041 #include "binding.h"
00042 #include "psc_xsb.h"
00043 #include "table_stats.h"
00044 #include "trie_internals.h"
00045 #include "macro_xsb.h"
00046 #include "error_xsb.h"
00047 #include "flags_xsb.h"
00048 #include "tst_utils.h"
00049 #include "loader_xsb.h"
00050
00051 #include "tables.h"
00052 #include "thread_xsb.h"
00053
00054 #include "sub_tables_xsb_i.h"
00055 #include "debug_xsb.h"
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifndef MULTI_THREAD
00071 Structure_Manager smProdSF = SM_InitDecl(subsumptive_producer_sf,
00072 SUBGOAL_FRAMES_PER_BLOCK,
00073 "Subsumptive Producer Subgoal Frame");
00074
00075 Structure_Manager smConsSF = SM_InitDecl(subsumptive_consumer_sf,
00076 SUBGOAL_FRAMES_PER_BLOCK,
00077 "Subsumptive Consumer Subgoal Frame");
00078
00079 #define subsumptive_smALN smALN
00080 #endif
00081
00082 Structure_Manager smVarSF = SM_InitDecl(variant_subgoal_frame,
00083 SUBGOAL_FRAMES_PER_BLOCK,
00084 "Variant Subgoal Frame");
00085 Structure_Manager smALN = SM_InitDecl(AnsListNode, ALNs_PER_BLOCK,
00086 "Answer List Node");
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 #ifndef WIN32
00108 inline
00109 #endif
00110 VariantSF NewProducerSF(CTXTdeclc BTNptr Leaf,TIFptr TableInfo) {
00111
00112 void *pNewSF;
00113
00114 if ( IsVariantPredicate(TableInfo) ) {
00115 #ifdef MULTI_THREAD
00116 if (threads_current_sm == PRIVATE_SM) {
00117 SM_AllocateStruct(smVarSF,pNewSF);
00118 pNewSF = memset(pNewSF,0,sizeof(variant_subgoal_frame));
00119 subg_sf_type(pNewSF) = PRIVATE_VARIANT_PRODUCER_SFT;
00120 } else {
00121 SM_AllocateSharedStruct(smVarSF,pNewSF);
00122 pNewSF = memset(pNewSF,0,sizeof(variant_subgoal_frame));
00123 subg_sf_type(pNewSF) = SHARED_VARIANT_PRODUCER_SFT;
00124 }
00125 }
00126 #else
00127 SM_AllocateStruct(smVarSF,pNewSF);
00128 pNewSF = memset(pNewSF,0,sizeof(variant_subgoal_frame));
00129 subg_sf_type(pNewSF) = PRIVATE_VARIANT_PRODUCER_SFT;
00130 }
00131 #endif
00132 else {
00133 SM_AllocateStruct(smProdSF,pNewSF);
00134 pNewSF = memset(pNewSF,0,sizeof(subsumptive_producer_sf));
00135 subg_sf_type(pNewSF) = SUBSUMPTIVE_PRODUCER_SFT;
00136 }
00137 subg_deltf_ptr(pNewSF) = NULL;
00138 subg_tif_ptr(pNewSF) = TableInfo;
00139 subg_dll_add_sf(pNewSF,TIF_Subgoals(TableInfo),TIF_Subgoals(TableInfo));
00140 subg_leaf_ptr(pNewSF) = Leaf;
00141 CallTrieLeaf_SetSF(Leaf,pNewSF);
00142 subg_ans_list_ptr(pNewSF) = empty_return_handle(pNewSF);
00143 subg_compl_stack_ptr(pNewSF) = openreg - COMPLFRAMESIZE;
00144 return (VariantSF)pNewSF;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 inline static BTNptr newCallIndex(CTXTdeclc Psc predicate) {
00162
00163 BTNptr pRoot;
00164
00165 New_BTN( pRoot, CALL_TRIE_TT, TRIE_ROOT_NT, EncodeTriePSC(predicate),
00166 NULL, NULL );
00167 return pRoot;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 void table_call_search(CTXTdeclc TabledCallInfo *call_info,
00181 CallLookupResults *results) {
00182
00183 TIFptr tif;
00184
00185 tif = CallInfo_TableInfo(*call_info);
00186 if ( IsNULL(TIF_CallTrie(tif)) )
00187 TIF_CallTrie(tif) = newCallIndex(CTXTc TIF_PSC(tif));
00188 if ( IsVariantPredicate(tif) )
00189 variant_call_search(CTXTc call_info,results);
00190 else
00191 subsumptive_call_search(CTXTc call_info,results);
00192 {
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 CPtr tmplt_component, tmplt_var_addr, hrg_addr;
00205 int size, j;
00206
00207 tmplt_component = CallLUR_VarVector(*results);
00208 size = int_val(*tmplt_component) & 0xffff;
00209 xsb_dbgmsg((LOG_TRIE,
00210 "done with vcs, answer_template %x\n",tmplt_component));
00211
00212
00213 if ((pb)top_of_localstk < (pb)top_of_heap + size +
00214 OVERFLOW_MARGIN) {
00215 xsb_abort("{table_call_search} Heap overflow copying answer template");
00216 }
00217
00218 for ( j = size - 1, tmplt_component = tmplt_component + size;
00219 j >= 0;
00220 j--, tmplt_component-- ) {
00221 tmplt_var_addr = (CPtr)*tmplt_component;
00222 xsb_dbgmsg((LOG_TRIE,"in TSC, copying AT to heap At[%d]: %x val: %x",
00223 (size-(j)),tmplt_component,tmplt_var_addr));
00224
00225 hrg_addr = hreg+j;
00226 bld_copy(hrg_addr, (Cell)(tmplt_var_addr));
00227 }
00228 hreg += size;
00229 bld_copy(hreg, cell(CallLUR_VarVector(*results)));
00230 hreg++;
00231
00232 CallLUR_VarVector(*results) = CallLUR_VarVector(*results) + size + 1;
00233 }
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 BTNptr table_answer_search(CTXTdeclc VariantSF producer, int size, int attv_num,
00251 CPtr templ, xsbBool *is_new) {
00252
00253 void *answer;
00254
00255 if ( IsSubsumptiveProducer(producer) ) {
00256 answer =
00257 subsumptive_answer_search(CTXTc (SubProdSF)producer,size,templ,is_new);
00258 if ( *is_new ) {
00259 ALNptr newALN;
00260 New_Private_ALN(newALN,answer,NULL);
00261 SF_AppendNewAnswer(producer,newALN);
00262 }
00263
00264
00265
00266
00267 if ( IsNonNULL(delayreg) ) {
00268 fprintf(stdwarn, "\n++Warning: Derivation of conditional answer for "
00269 "subsumptive subgoal ");
00270 sfPrintGoal(stdwarn, producer, NO);
00271 fprintf(stdwarn, "\n");
00272 if ( *is_new ) {
00273 fprintf(stderr, "++Error: The answer is new: ");
00274 printTriePath(stderr, answer, NO);
00275 fprintf(stderr, "\n");
00276 xsb_abort("Unsupported table operation: conditional-answer insertion");
00277 }
00278 else {
00279 fprintf(stdwarn, "++Warning: Answer is subsumed by: ");
00280 printTriePath(stdwarn, answer, NO);
00281 fprintf(stdwarn, "\n++Warning: Answer is rejected as redundant. "
00282 "Continuing...\n");
00283 }
00284 }
00285 }
00286 else {
00287
00288
00289
00290
00291 xsbBool wasFound = TRUE;
00292
00293 #ifndef IGNORE_DELAYVAR
00294 ans_var_pos_reg = hreg++;
00295 #endif
00296
00297 answer = variant_answer_search(CTXTc size,attv_num,templ,producer,&wasFound);
00298
00299 #ifdef DEBUG_DELAYVAR
00300 #ifndef IGNORE_DELAYVAR
00301 fprintf(stddbg, ">>>> ans_var_pos_reg = ");
00302 if (isinteger(cell(ans_var_pos_reg)))
00303 fprintf(stddbg, "\"ret\"\n");
00304 else
00305 fprintf(stddbg, "%s/%d\n", get_name((Psc)(cell(ans_var_pos_reg))),
00306 get_arity((Psc)(cell(ans_var_pos_reg))));
00307 #endif
00308 #endif
00309
00310 do_delay_stuff(CTXTc (NODEptr)answer, producer, wasFound);
00311
00312 #ifndef IGNORE_DELAYVAR
00313 undo_answer_bindings(CTXT);
00314 #endif
00315
00316 *is_new = ! wasFound;
00317 }
00318 return (BTNptr)answer;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void table_consume_answer(CTXTdeclc BTNptr answer, int size, int attv_num,
00330 CPtr templ, TIFptr predicate) {
00331
00332 if ( size > 0 ) {
00333 if ( IsSubsumptivePredicate(predicate) )
00334 consume_subsumptive_answer(CTXTc answer,size,templ);
00335 else
00336
00337 load_solution_trie(CTXTc size,attv_num,templ,answer);
00338 }
00339 else if ( size == 0 ) {
00340 if ( ! IsEscapeNode(answer) )
00341 xsb_abort("Size of answer template is 0 but producer contains an "
00342 "answer\nwith a non-empty substitution!\n");
00343 }
00344 else
00345 xsb_abort("table_consume_answer(): "
00346 "Answer template has negative size: %d\n", size);
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 ALNptr table_identify_relevant_answers(CTXTdeclc SubProdSF prodSF, SubConsSF consSF,
00367 CPtr templ) {
00368
00369 int size;
00370 TimeStamp ts;
00371
00372 TSTNptr tstRoot;
00373 ALNptr answers;
00374
00375
00376 #ifdef DEBUG_ASSERTIONS
00377 if ( ((SubProdSF)consSF == prodSF) || (! IsSubsumptiveProducer(prodSF))
00378 || (! IsProperlySubsumed(consSF)) )
00379 xsb_abort("Relevant Answer Identification apparently triggered for a "
00380 "variant!\nPerhaps SF type is corrupt?");
00381 #endif
00382 size = int_val(*templ);
00383 templ--;
00384
00385 ts = conssf_timestamp(consSF);
00386 tstRoot = (TSTNptr)subg_ans_root_ptr(prodSF);
00387 NumSubOps_IdentifyRelevantAnswers++;
00388 answers = tst_collect_relevant_answers(CTXTc tstRoot,ts,size,templ);
00389 conssf_timestamp(consSF) = TSTN_TimeStamp(tstRoot);
00390 if ( IsNonNULL(answers) )
00391 SF_AppendNewAnswerList(consSF,answers);
00392 return answers;
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 void table_complete_entry(CTXTdeclc VariantSF producerSF) {
00429
00430 SubConsSF pSF;
00431 ALNptr pRealAnsList, pALN, tag;
00432 TSTHTptr ht;
00433 TSINptr tsi_entry;
00434
00435 dbg_print_subgoal(LOG_STRUCT_MANAGER, stddbg, producerSF);
00436 xsb_dbgmsg((LOG_STRUCT_MANAGER, " complete... reclaiming structures.\n"));
00437
00438 if (flags[TRACE_STA])
00439 compute_maximum_tablespace_stats(CTXT);
00440
00441
00442
00443 if ( ProducerSubsumesSubgoals(producerSF) &&
00444 IsNonNULL(subg_ans_root_ptr(producerSF)) )
00445
00446 for ( ht = TSTRoot_GetHTList(subg_ans_root_ptr(producerSF));
00447 IsNonNULL(ht); ht = TSTHT_InternalLink(ht) ) {
00448
00449
00450 for ( tsi_entry = TSTHT_IndexHead(ht); IsNonNULL(tsi_entry);
00451 tsi_entry = TSIN_Next(tsi_entry) )
00452 TSTN_TimeStamp(TSIN_TSTNode(tsi_entry)) = TSIN_TimeStamp(tsi_entry);
00453
00454
00455 if ( IsNULL(TSTHT_IndexTail(ht)) ||
00456 IsNonNULL(TSIN_Next(TSTHT_IndexTail(ht))) ||
00457 IsNULL(TSTHT_IndexHead(ht)) ||
00458 IsNonNULL(TSIN_Prev(TSTHT_IndexHead(ht))) )
00459 xsb_warn("Malconstructed TSI");
00460
00461 xsb_dbgmsg((LOG_STRUCT_MANAGER, " Reclaiming TS Index\n"));
00462 dbg_smPrint(LOG_STRUCT_MANAGER, smTSIN, " before chain reclamation");
00463
00464
00465 SM_DeallocateStructList(smTSIN,TSTHT_IndexTail(ht),TSTHT_IndexHead(ht));
00466 TSTHT_IndexHead(ht) = TSTHT_IndexTail(ht) = NULL;
00467
00468 dbg_smPrint(LOG_STRUCT_MANAGER, smTSIN, " after chain reclamation");
00469 }
00470
00471
00472
00473 if ( has_answers(producerSF) ) {
00474 pALN = pRealAnsList = subg_answers(producerSF);
00475 tag = UNCOND_ANSWERS;
00476 do {
00477 if ( is_conditional_answer(ALN_Answer(pALN)) ) {
00478 tag = COND_ANSWERS;
00479 break;
00480 }
00481 pALN = ALN_Next(pALN);
00482 } while ( IsNonNULL(pALN) );
00483 #ifndef CONC_COMPL
00484 subg_answers(producerSF) = tag;
00485 #else
00486 subg_tag(producerSF) = tag;
00487 #endif
00488
00489 xsb_dbgmsg((LOG_STRUCT_MANAGER, " Reclaiming ALN chain for subgoal\n"));
00490 dbg_smPrint(LOG_STRUCT_MANAGER, smALN, " before chain reclamation");
00491
00492 if ( IsNULL(subg_ans_list_tail(producerSF)) ||
00493 IsNonNULL(ALN_Next(subg_ans_list_tail(producerSF))) )
00494 xsb_abort("Answer-List exception: Tail pointer incorrectly maintained");
00495 #ifndef CONC_COMPL
00496 #ifdef MULTI_THREAD
00497 if (IsSharedSF(producerSF)) {
00498 SM_DeallocateSharedStructList(smALN,pRealAnsList,
00499 subg_ans_list_tail(producerSF));
00500 } else {
00501 SM_DeallocateStructList(*private_smALN,pRealAnsList,
00502 subg_ans_list_tail(producerSF));
00503 }
00504 #else
00505 SM_DeallocateStructList(smALN,pRealAnsList,
00506 subg_ans_list_tail(producerSF));
00507 #endif
00508 subg_ans_list_tail(producerSF) = NULL;
00509 #endif
00510
00511 dbg_smPrint(LOG_STRUCT_MANAGER, smALN, " after chain reclamation");
00512 }
00513
00514
00515
00516 if ( IsSubsumptiveProducer(producerSF) ) {
00517 pSF = subg_consumers(producerSF);
00518
00519
00520 if (IsNonNULL(pSF)) {
00521 xsb_dbgmsg((LOG_STRUCT_MANAGER,
00522 "Reclaiming structures from consumers of "));
00523 dbg_print_subgoal(LOG_STRUCT_MANAGER, stddbg, producerSF);
00524 xsb_dbgmsg((LOG_STRUCT_MANAGER, "\n"));
00525 }
00526
00527 while ( IsNonNULL(pSF) ) {
00528
00529 xsb_dbgmsg((LOG_STRUCT_MANAGER, " Reclaiming ALN chain for consumer\n"));
00530 dbg_smPrint(LOG_STRUCT_MANAGER, smALN, " before chain reclamation");
00531
00532 if ( has_answers(pSF) )
00533 SM_DeallocateStructList(subsumptive_smALN,subg_ans_list_ptr(pSF),
00534 subg_ans_list_tail(pSF))
00535 else
00536 SM_DeallocateStruct(subsumptive_smALN,subg_ans_list_ptr(pSF))
00537 dbg_smPrint(LOG_STRUCT_MANAGER, smALN, " after chain reclamation");
00538
00539 subg_ans_list_ptr(pSF) = subg_ans_list_tail(pSF) = NULL;
00540 pSF = conssf_consumers(pSF);
00541 }
00542 }
00543
00544 xsb_dbgmsg((LOG_STRUCT_MANAGER, "Subgoal structure-reclamation complete!\n"));
00545 }
00546
00547
00548
00549
00550
00551
00552
00553 inline TIFptr New_TIF(CTXTdeclc Psc pPSC) {
00554 TIFptr pTIF;
00555
00556 pTIF = (TIFptr)mem_alloc(sizeof(TableInfoFrame),TABLE_SPACE);
00557 if ( IsNULL(pTIF) )
00558 xsb_abort("Ran out of memory in allocation of TableInfoFrame");
00559 TIF_PSC(pTIF) = pPSC;
00560 if (get_tabled(pPSC)==T_TABLED) {
00561 TIF_EvalMethod(pTIF) = (TabledEvalMethod)pflags[TABLING_METHOD];
00562 if (TIF_EvalMethod(pTIF) == VARIANT_EVAL_METHOD)
00563 set_tabled(pPSC,T_TABLED_VAR);
00564 else set_tabled(pPSC,T_TABLED_SUB);
00565 }
00566 else if (get_tabled(pPSC)==T_TABLED_VAR)
00567 TIF_EvalMethod(pTIF) = VARIANT_EVAL_METHOD;
00568 else if (get_tabled(pPSC)==T_TABLED_SUB)
00569 TIF_EvalMethod(pTIF) = SUBSUMPTIVE_EVAL_METHOD;
00570 else {
00571 xsb_warn("%s/%d not identified as tabled in .xwam file, Recompile (variant assumed)", \
00572 get_name(pPSC),get_arity(pPSC));
00573 TIF_EvalMethod(pTIF) = VARIANT_EVAL_METHOD;
00574 set_tabled(pPSC,T_TABLED_VAR);
00575 }
00576 TIF_CallTrie(pTIF) = NULL;
00577 TIF_Mark(pTIF) = 0;
00578 TIF_DelTF(pTIF) = NULL;
00579 TIF_Subgoals(pTIF) = NULL;
00580 TIF_NextTIF(pTIF) = NULL;
00581 #ifdef MULTI_THREAD
00582 if (get_shared(pPSC)) {
00583 SYS_MUTEX_LOCK( MUTEX_TABLE );
00584 if ( IsNonNULL(tif_list.last) )
00585 TIF_NextTIF(tif_list.last) = pTIF;
00586 else
00587 tif_list.first = pTIF;
00588 tif_list.last = pTIF;
00589 SYS_MUTEX_UNLOCK( MUTEX_TABLE );
00590 } else {
00591 if ( IsNonNULL(private_tif_list.last) )
00592 TIF_NextTIF(private_tif_list.last) = pTIF;
00593 else
00594 private_tif_list.first = pTIF;
00595 private_tif_list.last = pTIF;
00596 }
00597 #else
00598 if ( IsNonNULL(tif_list.last) )
00599 TIF_NextTIF(tif_list.last) = pTIF;
00600 else
00601 tif_list.first = pTIF;
00602 tif_list.last = pTIF;
00603 #endif
00604 return pTIF;
00605 }
00606
00607