UDI: some code refactor, simple code when no index intersection is needed
This commit is contained in:
parent
bae26c618b
commit
58962f2595
338
C/udi.c
338
C/udi.c
@ -4,15 +4,14 @@
|
|||||||
#include "Yap.h"
|
#include "Yap.h"
|
||||||
#include "YapInterface.h"
|
#include "YapInterface.h"
|
||||||
#include "clause.h"
|
#include "clause.h"
|
||||||
#include "clause_list.h"
|
|
||||||
#include "udi_private.h"
|
#include "udi_private.h"
|
||||||
|
|
||||||
/* to keep a vector of udi indexers */
|
/* to keep an array with the registered udi indexers */
|
||||||
UT_icd udicb_icd = {sizeof(UdiControlBlock), NULL, NULL, NULL};
|
UT_icd udicb_icd = {sizeof(UdiControlBlock), NULL, NULL, NULL};
|
||||||
UT_array *indexing_structures;
|
UT_array *indexing_structures;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* New user indexed predicate (used by the public udi interface)
|
* Register a new user indexer
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Yap_UdiRegister(UdiControlBlock cb){
|
Yap_UdiRegister(UdiControlBlock cb){
|
||||||
@ -33,8 +32,6 @@ p_new_udi( USES_REGS1 )
|
|||||||
UdiInfo blk;
|
UdiInfo blk;
|
||||||
int info;
|
int info;
|
||||||
|
|
||||||
//fprintf(stderr,"new pred\n");
|
|
||||||
|
|
||||||
/* get the predicate from the spec, copied from cdmgr.c */
|
/* get the predicate from the spec, copied from cdmgr.c */
|
||||||
if (IsVarTerm(spec)) {
|
if (IsVarTerm(spec)) {
|
||||||
Yap_Error(INSTANTIATION_ERROR,spec,"new user index/1");
|
Yap_Error(INSTANTIATION_ERROR,spec,"new user index/1");
|
||||||
@ -79,59 +76,63 @@ p_new_udi( USES_REGS1 )
|
|||||||
/* this is the real work */
|
/* this is the real work */
|
||||||
blk = (UdiInfo) Yap_AllocCodeSpace(sizeof(struct udi_info));
|
blk = (UdiInfo) Yap_AllocCodeSpace(sizeof(struct udi_info));
|
||||||
memset((void *) blk,0, sizeof(struct udi_info));
|
memset((void *) blk,0, sizeof(struct udi_info));
|
||||||
|
|
||||||
if (!blk) {
|
if (!blk) {
|
||||||
Yap_Error(OUT_OF_HEAP_ERROR, spec, "new user index/1");
|
Yap_Error(OUT_OF_HEAP_ERROR, spec, "new user index/1");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
utarray_new(blk->clauselist, &cl_icd);
|
|
||||||
utarray_new(blk->args, &arg_icd);
|
|
||||||
blk->p = p;
|
|
||||||
HASH_ADD_UdiInfo(UdiControlBlocks, p, blk);
|
|
||||||
//fprintf(stderr,"PRED %p\n",p);
|
|
||||||
|
|
||||||
info = Yap_udi_args_init(spec, p->ArityOfPE, blk);
|
/*Init UdiInfo */
|
||||||
if (!info) /*TODO: clear blk here*/
|
utarray_new(blk->args, &arg_icd);
|
||||||
return FALSE;
|
utarray_new(blk->clauselist, &cl_icd);
|
||||||
|
blk->p = p;
|
||||||
|
|
||||||
|
/*Now Init args list*/
|
||||||
|
info = p_udi_args_init(spec, p->ArityOfPE, blk);
|
||||||
|
if (!info)
|
||||||
|
{
|
||||||
|
utarray_free(blk->args);
|
||||||
|
utarray_free(blk->clauselist);
|
||||||
|
Yap_FreeCodeSpace((char *) blk);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Push into the hash*/
|
||||||
|
HASH_ADD_UdiInfo(UdiControlBlocks, p, blk);
|
||||||
|
|
||||||
p->PredFlags |= UDIPredFlag;
|
p->PredFlags |= UDIPredFlag;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we initialize the arguments indexing
|
* Here we initialize the arguments indexing
|
||||||
*/
|
*/
|
||||||
int
|
YAP_Int
|
||||||
Yap_udi_args_init(Term spec, int arity, UdiInfo blk)
|
p_udi_args_init(Term spec, int arity, UdiInfo blk)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Term arg;
|
Term arg;
|
||||||
Atom idxtype;
|
Atom idxtype;
|
||||||
UdiControlBlock *p;
|
UdiControlBlock *cb;
|
||||||
struct udi_p_args p_arg;
|
struct udi_p_args p_arg;
|
||||||
|
|
||||||
//fprintf(stderr,"udi init\n");
|
|
||||||
|
|
||||||
for (i = 1; i <= arity; i++) {
|
for (i = 1; i <= arity; i++) {
|
||||||
arg = ArgOfTerm(i,spec);
|
arg = ArgOfTerm(i,spec);
|
||||||
if (IsAtomTerm(arg)) {
|
if (IsAtomTerm(arg)) {
|
||||||
idxtype = AtomOfTerm(arg);
|
idxtype = AtomOfTerm(arg);
|
||||||
// fprintf(stderr,"%p-%s %p-%s\n",idxtype, YAP_AtomName(idxtype),
|
if (idxtype == AtomMinus) //skip this argument
|
||||||
// AtomMinus, YAP_AtomName(AtomMinus));
|
|
||||||
if (idxtype == AtomMinus)
|
|
||||||
continue;
|
continue;
|
||||||
p_arg.control = NULL;
|
p_arg.control = NULL;
|
||||||
p = NULL;
|
cb = NULL;
|
||||||
while ((p = (UdiControlBlock *) utarray_next(indexing_structures, p))) {
|
while ((cb = (UdiControlBlock *) utarray_next(indexing_structures, cb))) {
|
||||||
//fprintf(stderr,"cb: %p %p-%s\n", *p, (*p)->decl, YAP_AtomName((*p)->decl));
|
if (idxtype == (*cb)->decl){
|
||||||
if (idxtype == (*p)->decl){
|
|
||||||
p_arg.arg = i;
|
p_arg.arg = i;
|
||||||
p_arg.control = *p;
|
p_arg.control = *cb;
|
||||||
p_arg.idxstr = (*p)->init(spec, i, arity);
|
p_arg.idxstr = (*cb)->init(spec, i, arity);
|
||||||
utarray_push_back(blk->args, &p_arg);
|
utarray_push_back(blk->args, &p_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p_arg.control == NULL){ /* not "-" and not found*/
|
if (p_arg.control == NULL){ /* not "-" and not found */
|
||||||
fprintf(stderr, "Invalid Spec (%s)\n", AtomName(idxtype));
|
fprintf(stderr, "Invalid Spec (%s)\n", AtomName(idxtype));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -140,36 +141,54 @@ Yap_udi_args_init(Term spec, int arity, UdiInfo blk)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just pass info to user, called from cdmgr.c */
|
/*
|
||||||
|
* From now on this is called in several places of yap
|
||||||
|
* when the predicate has the UDIPredFlag
|
||||||
|
* and is what actually triggers the insert/search/abolish of indexing structures
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init Yap udi interface
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Yap_udi_init(void)
|
||||||
|
{
|
||||||
|
UdiControlBlocks = NULL;
|
||||||
|
|
||||||
|
/*init indexing structures array*/
|
||||||
|
utarray_new(indexing_structures, &udicb_icd);
|
||||||
|
|
||||||
|
Yap_InitCPred("$udi_init", 1, p_new_udi, 0);
|
||||||
|
/* TODO: decide if udi.yap should be loaded automaticaly in init.yap */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called from cdmgr.c
|
||||||
|
*
|
||||||
|
* for each assert of a udipredicate
|
||||||
|
* to pass info to user structure
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
Yap_new_udi_clause(PredEntry *p, yamop *cl, Term t)
|
Yap_new_udi_clause(PredEntry *p, yamop *cl, Term t)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
UdiPArg parg;
|
UdiPArg parg;
|
||||||
UdiInfo info;
|
UdiInfo info;
|
||||||
int index;
|
YAP_Int index;
|
||||||
// yamop **x;
|
|
||||||
|
|
||||||
/* try to find our structure*/
|
/* try to find our structure */
|
||||||
HASH_FIND_UdiInfo(UdiControlBlocks,p,info);
|
HASH_FIND_UdiInfo(UdiControlBlocks,p,info);
|
||||||
if (!info)
|
if (!info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/*insert into clauselist will be used latter*/
|
/* insert into clauselist */
|
||||||
utarray_push_back(info->clauselist, &cl);
|
utarray_push_back(info->clauselist, &cl);
|
||||||
|
|
||||||
for (i = 0; i < utarray_len(info->args) ; i++) {
|
for (i = 0; i < utarray_len(info->args) ; i++) {
|
||||||
parg = (UdiPArg) utarray_eltptr(info->args,i);
|
parg = (UdiPArg) utarray_eltptr(info->args,i);
|
||||||
index = utarray_len(info->clauselist);
|
index = (YAP_Int) utarray_len(info->clauselist);
|
||||||
// x = (yamop **) utarray_eltptr(info->clauselist, index);
|
|
||||||
// fprintf(stderr,"Insert (%p %p %d) %d - %p %p %p\n",
|
|
||||||
// info->clauselist,info->clauselist->d,info->clauselist->icd.sz,
|
|
||||||
// index,
|
|
||||||
// cl, *x, *((yamop **) utarray_eltptr(info->clauselist, index)));
|
|
||||||
parg->idxstr = parg->control->insert(parg->idxstr, t,
|
parg->idxstr = parg->control->insert(parg->idxstr, t,
|
||||||
parg->arg,
|
parg->arg,
|
||||||
(void *) index);
|
(void *) index);
|
||||||
//info->cb = info->functions->insert(t, info->cb, (void *)cl);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -187,136 +206,158 @@ static inline int callback(void *key, void *data, void *arg)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* index, called from absmi.c */
|
/* 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 *
|
yamop *
|
||||||
Yap_udi_search(PredEntry *p)
|
Yap_udi_search(PredEntry *p)
|
||||||
{
|
{
|
||||||
int i, r;
|
int r;
|
||||||
struct ClauseList clauselist;
|
struct ClauseList clauselist;
|
||||||
// struct CallbackM cm;
|
|
||||||
// callback_m_t c;
|
|
||||||
UdiPArg parg;
|
UdiPArg parg;
|
||||||
UdiInfo info;
|
UdiInfo info;
|
||||||
Pvoid_t tmp, result;
|
|
||||||
Word_t count;
|
|
||||||
Word_t idx_r = 0L;
|
|
||||||
yamop **x;
|
|
||||||
|
|
||||||
/* find our structure*/
|
/* find our structure*/
|
||||||
HASH_FIND_UdiInfo(UdiControlBlocks,p,info);
|
HASH_FIND_UdiInfo(UdiControlBlocks,p,info);
|
||||||
if (!info)
|
if (!info || utarray_len(info->args) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// /*TODO: handle intersection*/
|
if (utarray_len(info->args) == 1){ //simple case no intersection needed
|
||||||
// c = &cm;
|
struct si_callback_h c;
|
||||||
// c->cl = Yap_ClauseListInit(&clauselist);
|
|
||||||
// c->pred = p;
|
|
||||||
|
|
||||||
/*
|
c.cl = Yap_ClauseListInit(&clauselist);
|
||||||
* I will start with the simplest case
|
c.clauselist = info->clauselist;
|
||||||
* for each index create a set and intersect it with the
|
c.pred = info->p;
|
||||||
* next
|
if (!c.cl)
|
||||||
*/
|
return NULL;
|
||||||
result = (Pvoid_t) NULL;
|
|
||||||
tmp = (Pvoid_t) NULL;
|
|
||||||
r = -1;
|
|
||||||
for (i = 0; i < utarray_len(info->args) ; i++) {
|
|
||||||
// fprintf(stderr,"Start Search\n");
|
|
||||||
parg = (UdiPArg) utarray_eltptr(info->args,i);
|
|
||||||
r = parg->control->search(parg->idxstr, parg->arg, callback, &tmp);
|
|
||||||
|
|
||||||
if (r == -1) /*this arg does not prune search*/
|
parg = (UdiPArg) utarray_eltptr(info->args,0);
|
||||||
continue;
|
r = parg->control->search(parg->idxstr, parg->arg, si_callback, (void *) &c);
|
||||||
|
Yap_ClauseListClose(c.cl);
|
||||||
|
|
||||||
J1C(count, result, 0, -1);
|
if (r == -1) {
|
||||||
|
Yap_ClauseListDestroy(c.cl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (r == 0)
|
if (Yap_ClauseListCount(c.cl) == 0) {
|
||||||
{
|
Yap_ClauseListDestroy(c.cl);
|
||||||
if (count > 0) // clear previous result if it exists
|
|
||||||
J1FA(count, result);
|
|
||||||
fprintf(stderr,"Search Failed");
|
|
||||||
return Yap_FAILCODE();
|
return Yap_FAILCODE();
|
||||||
}
|
}
|
||||||
|
} else {//intersection needed using Judy1
|
||||||
|
/*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;
|
||||||
|
|
||||||
if (r > 0 && count == 0) // first result_set
|
/*
|
||||||
{
|
* I will start with the simplest approach
|
||||||
result = tmp;
|
* for each index create a set and intersect it with the
|
||||||
tmp = (Pvoid_t) NULL;
|
* next
|
||||||
}
|
*
|
||||||
else
|
* In the future it could pay to sort according to index type
|
||||||
{/*intersection*/
|
* to improve intersection part
|
||||||
Word_t idx_tmp = 0L;
|
*/
|
||||||
|
for (i = 0; i < utarray_len(info->args) ; i++) {
|
||||||
idx_r = 0L;
|
parg = (UdiPArg) utarray_eltptr(info->args,i);
|
||||||
J1F(count, result, idx_r);//succeeds one time at least
|
r = parg->control->search(parg->idxstr, parg->arg, callback, &tmp);
|
||||||
J1F(count, tmp, idx_tmp); //succeeds one time at least
|
if (r == -1) /*this arg does not prune search*/
|
||||||
while (count)
|
continue;
|
||||||
|
rc ++;
|
||||||
|
J1C(count, result, 0, -1);
|
||||||
|
if (r == 0) /* this arg gave 0 results -> FAIL*/
|
||||||
{
|
{
|
||||||
while (idx_r < idx_tmp)
|
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
|
J1U(count, result, idx_r); //does not belong
|
||||||
J1N(count, result, idx_r); //next
|
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
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
J1FA(count, tmp); //free tmp
|
||||||
}
|
}
|
||||||
J1F(count, result, idx_r); // first starting in idx_r
|
}
|
||||||
//clear up the rest
|
if (rc == 0) /*no search performed*/
|
||||||
while (idx_r > idx_tmp && count) //result has more setted values
|
return NULL;
|
||||||
{
|
|
||||||
J1U(count, result, idx_r); //does not belong
|
J1C(count, result, 0, -1);
|
||||||
J1N(count, result, idx_r); //next
|
if (count == 0) { /*result set empty -> FAIL */
|
||||||
}
|
J1FA(count, result);
|
||||||
J1FA(count, tmp);
|
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 %d bytes for %d clausules\n",
|
||||||
|
count, Yap_ClauseListCount(&clauselist));
|
||||||
|
Yap_ClauseListClose(&clauselist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Yap_ClauseListInit(&clauselist);
|
|
||||||
idx_r = 0L;
|
|
||||||
J1F(count, result, idx_r);
|
|
||||||
while (count)
|
|
||||||
{
|
|
||||||
x = (yamop **) utarray_eltptr(info->clauselist, idx_r - 1);
|
|
||||||
// fprintf(stderr,"Clausule %d of %d: %p\n",
|
|
||||||
// idx_r, utarray_len(info->clauselist),
|
|
||||||
// *x);
|
|
||||||
Yap_ClauseListExtend(
|
|
||||||
&clauselist,
|
|
||||||
*x,
|
|
||||||
info->p);
|
|
||||||
J1N(count, result, idx_r);
|
|
||||||
}
|
|
||||||
J1FA(count,result);
|
|
||||||
// fprintf(stderr,"J1 used space %d bytes for %d clausules\n",
|
|
||||||
// count, Yap_ClauseListCount(&clauselist));
|
|
||||||
Yap_ClauseListClose(&clauselist);
|
|
||||||
|
|
||||||
if (Yap_ClauseListCount(&clauselist) == 0)
|
|
||||||
{
|
|
||||||
Yap_ClauseListDestroy(&clauselist);
|
|
||||||
// fprintf(stderr,"Search Not needed\n");
|
|
||||||
return NULL; /*FAIL CODE handled before*/
|
|
||||||
}
|
|
||||||
if (Yap_ClauseListCount(&clauselist) == 1)
|
if (Yap_ClauseListCount(&clauselist) == 1)
|
||||||
{
|
|
||||||
// fprintf(stderr,"Returning 1 value\n");
|
|
||||||
return Yap_ClauseListToClause(&clauselist);
|
return Yap_ClauseListToClause(&clauselist);
|
||||||
}
|
|
||||||
// fprintf(stderr,"Returning Multiple values (%d)\n", Yap_ClauseListCount(&clauselist));
|
|
||||||
return Yap_ClauseListCode(&clauselist);
|
return Yap_ClauseListCode(&clauselist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,18 +367,3 @@ Yap_udi_abolish(PredEntry *p)
|
|||||||
{
|
{
|
||||||
/* tell the predicate destroy */
|
/* tell the predicate destroy */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Init Yap udi interface
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
Yap_udi_init(void)
|
|
||||||
{
|
|
||||||
UdiControlBlocks = NULL;
|
|
||||||
|
|
||||||
/*init indexing structures array*/
|
|
||||||
utarray_new(indexing_structures, &udicb_icd);
|
|
||||||
|
|
||||||
Yap_InitCPred("$udi_init", 1, p_new_udi, 0);
|
|
||||||
/* TODO: decide if udi.yap should be loaded automaticaly in init.yap */
|
|
||||||
}
|
|
||||||
|
@ -332,8 +332,9 @@ Term STD_PROTO(Yap_LUInstance,(LogUpdClause *, UInt));
|
|||||||
|
|
||||||
/* udi.c */
|
/* udi.c */
|
||||||
void STD_PROTO(Yap_udi_init,(void));
|
void STD_PROTO(Yap_udi_init,(void));
|
||||||
yamop *STD_PROTO(Yap_udi_search,(PredEntry *));
|
|
||||||
int STD_PROTO(Yap_new_udi_clause,(PredEntry *, yamop *, Term));
|
int STD_PROTO(Yap_new_udi_clause,(PredEntry *, yamop *, Term));
|
||||||
|
yamop *STD_PROTO(Yap_udi_search,(PredEntry *));
|
||||||
|
void STD_PROTO(Yap_udi_abolish,(PredEntry *p));
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void STD_PROTO(Yap_bug_location,(yamop *));
|
void STD_PROTO(Yap_bug_location,(yamop *));
|
||||||
|
@ -11,10 +11,7 @@ struct udi_p_args {
|
|||||||
typedef struct udi_p_args *UdiPArg;
|
typedef struct udi_p_args *UdiPArg;
|
||||||
UT_icd arg_icd = {sizeof(struct udi_p_args), NULL, NULL, NULL };
|
UT_icd arg_icd = {sizeof(struct udi_p_args), NULL, NULL, NULL };
|
||||||
|
|
||||||
/* a pointer utarray list
|
/* clauselist */
|
||||||
* This is a hack, becouse I do no know the real type of clauses
|
|
||||||
* Not completely used for now
|
|
||||||
*/
|
|
||||||
UT_icd cl_icd = {sizeof(yamop *), NULL, NULL, NULL };
|
UT_icd cl_icd = {sizeof(yamop *), NULL, NULL, NULL };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -26,30 +23,38 @@ struct udi_info
|
|||||||
PredEntry *p; //predicate (need to identify asserts)
|
PredEntry *p; //predicate (need to identify asserts)
|
||||||
UT_array *clauselist; //clause list used on returns
|
UT_array *clauselist; //clause list used on returns
|
||||||
UT_array *args; //indexed args
|
UT_array *args; //indexed args
|
||||||
UT_hash_handle hh;
|
UT_hash_handle hh; //uthash handle
|
||||||
};
|
};
|
||||||
typedef struct udi_info *UdiInfo;
|
typedef struct udi_info *UdiInfo;
|
||||||
|
|
||||||
/* to ease code for a UdiInfo hash table*/
|
/* to ease code for a UdiInfo hash table*/
|
||||||
#define HASH_FIND_UdiInfo(head,find,out) \
|
#define HASH_FIND_UdiInfo(head,find,out) \
|
||||||
HASH_FIND(hh,head,find,sizeof(PredEntry *),out)
|
HASH_FIND(hh,head,find,sizeof(PredEntry *),out)
|
||||||
#define HASH_ADD_UdiInfo(head,p,add) \
|
#define HASH_ADD_UdiInfo(head,p,add) \
|
||||||
HASH_ADD_KEYPTR(hh,head,p,sizeof(PredEntry *),add)
|
HASH_ADD_KEYPTR(hh,head,p,sizeof(PredEntry *),add)
|
||||||
|
|
||||||
int Yap_udi_args_init(Term spec, int arity, UdiInfo blk);
|
/* used during init */
|
||||||
|
static YAP_Int p_new_udi( USES_REGS1 );
|
||||||
|
static YAP_Int p_udi_args_init(Term spec, int arity, UdiInfo blk);
|
||||||
|
|
||||||
///* temporary */
|
/*
|
||||||
//struct CallbackM
|
* Indexing Search and intersection Helpers
|
||||||
//{
|
*/
|
||||||
// clause_list_t cl;
|
|
||||||
// void * pred;
|
|
||||||
//};
|
|
||||||
//typedef struct CallbackM * callback_m_t;
|
|
||||||
//
|
|
||||||
//static inline int callback(void *key, void *data, void *arg)
|
|
||||||
//{
|
|
||||||
// callback_m_t x;
|
|
||||||
// x = (callback_m_t) arg;
|
|
||||||
// return Yap_ClauseListExtend(x->cl,data,x->pred);
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
/* single indexing helpers (no intersection needed just create clauselist) */
|
||||||
|
#include "clause_list.h"
|
||||||
|
struct si_callback_h
|
||||||
|
{
|
||||||
|
clause_list_t cl;
|
||||||
|
UT_array *clauselist;
|
||||||
|
void * pred;
|
||||||
|
};
|
||||||
|
typedef struct si_callback_h * si_callback_h_t;
|
||||||
|
|
||||||
|
static inline int si_callback(void *key, void *data, void *arg)
|
||||||
|
{
|
||||||
|
si_callback_h_t c = (si_callback_h_t) arg;
|
||||||
|
yamop **cl = (yamop **) utarray_eltptr(c->clauselist, ((YAP_Int) data) - 1);
|
||||||
|
return Yap_ClauseListExtend(c->cl, *cl, c->pred);
|
||||||
|
}
|
||||||
|
/* Judy1 integer sparse set intersection */
|
||||||
|
@ -52,7 +52,7 @@ typedef int (* Yap_UdiCallback)
|
|||||||
|
|
||||||
/* Called upon search
|
/* Called upon search
|
||||||
*
|
*
|
||||||
* If there is any search to do with this struture should return >= 0
|
* If there is any search to do with this structure should return >= 0
|
||||||
* corresponding to the values found
|
* corresponding to the values found
|
||||||
*
|
*
|
||||||
* returns -1 if there is nothing to search with this indexing structure
|
* returns -1 if there is nothing to search with this indexing structure
|
||||||
@ -62,9 +62,9 @@ typedef int (* Yap_UdiSearch)
|
|||||||
(void * control, /* indexing structure opaque handle */
|
(void * control, /* indexing structure opaque handle */
|
||||||
int arg, /* argument regarding this call */
|
int arg, /* argument regarding this call */
|
||||||
Yap_UdiCallback f, /* callback on each found value */
|
Yap_UdiCallback f, /* callback on each found value */
|
||||||
void *args); /* auxiliary data to callback */
|
void *args); /* auxiliary data to callback */
|
||||||
|
|
||||||
/* Called upond abolish of the term
|
/* Called upon abolish of the term
|
||||||
* to allow for a clean destroy of the indexing structures
|
* to allow for a clean destroy of the indexing structures
|
||||||
*/
|
*/
|
||||||
typedef int (* Yap_UdiDestroy)
|
typedef int (* Yap_UdiDestroy)
|
||||||
|
Reference in New Issue
Block a user