/*ARGS ARE AVAILABLE*/ void *RtreeUdiSearch (control_t *control) { rect_t r; int i; struct ClauseList clauselist; struct CallbackM cm; callback_m_t c; YAP_Term Constraints; /*RTreePrint ((*control)[0].tree);*/ for (i = 0; i < NARGS && (*control)[i].arg != 0 ; i++) if (YAP_IsAttVar(YAP_A((*control)[i].arg))) { /*get the constraits rect*/ Constraints = YAP_AttsOfVar(YAP_A((*control)[i].arg)); /* Yap_DebugPlWrite(Constraints); */ r = RectOfTerm(YAP_ArgOfTerm(2,Constraints)); c = &cm; c->cl = Yap_ClauseListInit(&clauselist); c->pred = (*control)[i].pred; if (!c->cl) return NULL; /*? or fail*/ RTreeSearch((*control)[i].tree, r, callback, c); Yap_ClauseListClose(c->cl); if (Yap_ClauseListCount(c->cl) == 0) { Yap_ClauseListDestroy(c->cl); return Yap_FAILCODE(); } if (Yap_ClauseListCount(c->cl) == 1) { return Yap_ClauseListToClause(c->cl); } return Yap_ClauseListCode(c->cl); } return NULL; /*YAP FALLBACK*/ }
/* index, called from absmi.c * * Returns: * NULL (yap fallback) No usable indexing available * * Yap_FAILCODE() (fail) No result found * Yap_CauseListToClause(cl) 1 solution found * Yap_ClauseListCode(cl) 2+ solutions found */ yamop * Yap_udi_search(PredEntry *p) { int r; struct ClauseList clauselist; UdiPArg parg; UdiInfo info; /* find our structure*/ HASH_FIND_UdiInfo(UdiControlBlocks,p,info); if (!info || utarray_len(info->args) == 0) return NULL; if (utarray_len(info->args) == 1){ //simple case no intersection needed struct si_callback_h c; c.cl = Yap_ClauseListInit(&clauselist); c.clauselist = info->clauselist; c.pred = info->p; if (!c.cl) return NULL; parg = (UdiPArg) utarray_eltptr(info->args,0); r = parg->control->search(parg->idxstr, parg->arg, si_callback, (void *) &c); Yap_ClauseListClose(c.cl); if (r == -1) { Yap_ClauseListDestroy(c.cl); return NULL; } if (Yap_ClauseListCount(c.cl) == 0) { Yap_ClauseListDestroy(c.cl); return Yap_FAILCODE(); } } else {//intersection needed using Judy1 #ifdef USE_JUDY /*TODO: do more tests to this algorithm*/ int i; Pvoid_t tmp = (Pvoid_t) NULL; Pvoid_t result = (Pvoid_t) NULL; Word_t count = 0L; Word_t idx_r = 0L; Word_t idx_tmp = 0L; int rc = 0; yamop **x; /* * I will start with the simplest approach * for each index create a set and intersect it with the * next * * In the future it could pay to sort according to index type * to improve intersection part */ for (i = 0; i < utarray_len(info->args) ; i++) { parg = (UdiPArg) utarray_eltptr(info->args,i); r = parg->control->search(parg->idxstr, parg->arg, j1_callback, &tmp); if (r == -1) /*this arg does not prune search*/ continue; rc ++; J1C(count, result, 0, -1); if (r == 0) /* this arg gave 0 results -> FAIL*/ { if (count > 0) // clear previous result if they exists J1FA(count, result); return Yap_FAILCODE(); } if (count == 0) // first result_set { result = tmp; tmp = (Pvoid_t) NULL; } else /*intersection*/ { idx_tmp = 0L; idx_r = 0L; J1F(count, result, idx_r); //succeeds one time at least assert(count > 0); J1F(count, tmp, idx_tmp); //succeeds one time at least assert(count > 0); while (count) { while (idx_r < idx_tmp) { J1U(count, result, idx_r); //does not belong J1N(count, result, idx_r); //next if (! count) break; //end result set } if(idx_r == idx_tmp) { J1N(count, result, idx_r); //next if (! count) break; //end result set J1N(count, tmp, idx_tmp); //next tmp //if (! count) break; //end tmp set will break while } else // (idx_r > idx_tmp) { idx_tmp = idx_r; // fast forward J1F(count, tmp, idx_tmp); // first starting in idx_r //if (! count) break; //end tmp set will break while } } J1F(count, result, idx_r); // first starting in idx_r //clear up the rest while (idx_r > idx_tmp && count) //result has more setted values { J1U(count, result, idx_r); //does not belong J1N(count, result, idx_r); //next } J1FA(count, tmp); //free tmp } } if (rc == 0) /*no search performed*/ return NULL; J1C(count, result, 0, -1); if (count == 0) { /*result set empty -> FAIL */ J1FA(count, result); return Yap_FAILCODE(); } /*convert Juddy1 to clauselist*/ Yap_ClauseListInit(&clauselist); idx_r = 0L; J1F(count, result, idx_r); while (count) { x = (yamop **) utarray_eltptr(info->clauselist, idx_r - 1); Yap_ClauseListExtend( &clauselist, *x, info->p); J1N(count, result, idx_r); } J1FA(count,result); fprintf(stderr,"J1 used space %ld bytes for %d clausules\n", count, Yap_ClauseListCount(&clauselist)); Yap_ClauseListClose(&clauselist); #else fprintf(stderr,"Without libJudy only one argument indexed is allowed." "Falling back to Yap Indexing\n"); return NULL; //NO Judy Available #endif } if (Yap_ClauseListCount(&clauselist) == 1) return Yap_ClauseListToClause(&clauselist); return Yap_ClauseListCode(&clauselist); }