From 4b826e76ae889ef045a98968b03f06c5142f8f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Thu, 12 Feb 2009 16:39:20 +0000 Subject: [PATCH] support for user defined indexing: step 1 basic routines. --- C/udi.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++ H/Heap.h | 2 + H/Yatom.h | 5 +- H/clause.h | 5 ++ H/iatoms.h | 1 + H/ratoms.h | 1 + H/tatoms.h | 2 + Makefile.in | 6 +++ include/udi.h | 34 +++++++++++++ misc/ATOMS | 1 + 10 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 C/udi.c create mode 100644 include/udi.h diff --git a/C/udi.c b/C/udi.c new file mode 100644 index 000000000..438205ffa --- /dev/null +++ b/C/udi.c @@ -0,0 +1,131 @@ + +#include "Yap.h" +#include "clause.h" +#include "udi.h" + +/* we can have this stactic because it is written once */ +static struct udi_control_block RtreeCmd; + +typedef struct udi_info +{ + PredEntry *p; + void *cb; + UdiControlBlock functions; + struct udi_info *next; +} *UdiInfo; + +static int +add_udi_block(void *info, PredEntry *p, UdiControlBlock cmd) +{ + UdiInfo blk = (UdiInfo)Yap_AllocCodeSpace(sizeof(struct udi_info)); + if (!blk) + return FALSE; + blk->next = UdiControlBlocks; + UdiControlBlocks = blk; + blk->p = p; + blk->functions = cmd; + blk->cb = info; + return TRUE; +} + +static Int +p_new_udi(void) +{ + Term spec = Deref(ARG2), udi_type = Deref(ARG1); + PredEntry *p; + UdiControlBlock cmd; + Atom udi_t; + void *info; + + if (IsVarTerm(spec)) { + Yap_Error(INSTANTIATION_ERROR,spec,"new user index/1"); + return FALSE; + } else if (!IsApplTerm(spec)) { + Yap_Error(TYPE_ERROR_COMPOUND,spec,"new user index/1"); + return FALSE; + } else { + Functor fun = FunctorOfTerm(spec); + Term tmod = CurrentModule; + + while (fun == FunctorModule) { + tmod = ArgOfTerm(1,spec); + if (IsVarTerm(tmod) ) { + Yap_Error(INSTANTIATION_ERROR, spec, "new user index/1"); + return FALSE; + } + if (!IsAtomTerm(tmod) ) { + Yap_Error(TYPE_ERROR_ATOM, spec, "new user index/1"); + return FALSE; + } + spec = ArgOfTerm(2, spec); + fun = FunctorOfTerm(spec); + } + p = RepPredProp(Yap_GetPredPropByFunc(fun, tmod)); + } + if ((p->PredFlags & (DynamicPredFlag|LogUpdatePredFlag|UserCPredFlag|CArgsPredFlag|NumberDBPredFlag|AtomDBPredFlag|TestPredFlag|AsmPredFlag|CPredFlag|BinaryPredFlag)) || + (p->ModuleOfPred == PROLOG_MODULE)) { + Yap_Error(PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE, spec, "udi/2"); + return FALSE; + } + if (p->PredFlags & (DynamicPredFlag|LogUpdatePredFlag|TabledPredFlag)) { + Yap_Error(PERMISSION_ERROR_ACCESS_PRIVATE_PROCEDURE, spec, "udi/2"); + return FALSE; + } + if (IsVarTerm(udi_type)) { + Yap_Error(INSTANTIATION_ERROR,spec,"new user index/1"); + return FALSE; + } else if (!IsAtomTerm(udi_type)) { + Yap_Error(TYPE_ERROR_ATOM,spec,"new user index/1"); + return FALSE; + } + udi_t = AtomOfTerm(udi_type); + if (udi_t == AtomRTree) { + cmd = &RtreeCmd; + } else { + Yap_Error(TYPE_ERROR_ATOM,spec,"new user index/1"); + return FALSE; + } + info = cmd->init(spec, (void *)p, p->ArityOfPE); + if (!info) + return FALSE; + if (!add_udi_block(info, p, cmd)) { + Yap_Error(OUT_OF_HEAP_ERROR, spec, "new user index/1"); + return FALSE; + } + p->PredFlags |= UDIPredFlag; + return TRUE; +} + +int +Yap_new_udi_clause(PredEntry *p, yamop *cl, Term t) +{ + struct udi_info *info = UdiControlBlocks; + while (info->p != p && info) + info = info->next; + if (!info) + return FALSE; + info->cb = info->functions->insert(t, info->cb, (void *)cl); + return TRUE; +} + +yamop * +Yap_udi_search(PredEntry *p) +{ + struct udi_info *info = UdiControlBlocks; + while (info->p != p && info) + info = info->next; + if (!info) + return NULL; + return info->functions->search(info->cb); +} + +void +Yap_udi_init(void) +{ + UdiControlBlocks = NULL; + /* to be filled in by David */ + RtreeCmd.init = NULL; + RtreeCmd.insert = NULL; + RtreeCmd.search = NULL; + Yap_InitCPred("$init_udi", 2, p_new_udi, 0); +} diff --git a/H/Heap.h b/H/Heap.h index 394c85a77..1976be855 100644 --- a/H/Heap.h +++ b/H/Heap.h @@ -307,6 +307,7 @@ typedef struct various_codes { #if USE_THREADED_CODE opentry *op_rtable; #endif + struct udi_info *udi_control_blocks; #ifdef COROUTINING int num_of_atts; /* max. number of attributes we have for a variable */ struct pred_entry *wake_up_code; @@ -527,6 +528,7 @@ extern struct various_codes *Yap_heap_regs; #if USE_THREADED_CODE #define OP_RTABLE Yap_heap_regs->op_rtable #endif +#define UdiControlBlocks Yap_heap_regs->udi_control_blocks #define PROFILING Yap_heap_regs->system_profiling #define CALL_COUNTING Yap_heap_regs->system_call_counting #define PRED_GOAL_EXPANSION_ALL Yap_heap_regs->system_pred_goal_expansion_all diff --git a/H/Yatom.h b/H/Yatom.h index 11ca40be0..692eb7c68 100644 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -635,7 +635,7 @@ IsValProperty (int flags) */ typedef enum { - MegaClausePredFlag = 0x80000000L, /* predicate is implemented as a mega-clause */ + MegaClausePredFlag = 0x80000000L, /* predicate is implemented as a mega-clause */ ThreadLocalPredFlag = 0x40000000L, /* local to a thread */ MultiFileFlag = 0x20000000L, /* is multi-file */ UserCPredFlag = 0x10000000L, /* CPred defined by the user */ @@ -665,7 +665,8 @@ typedef enum ProfiledPredFlag = 0x00000010L, /* pred is being profiled */ MyddasPredFlag = 0x00000008L, /* Myddas Imported pred */ ModuleTransparentPredFlag = 0x00000004L, /* ModuleTransparent pred */ - SWIEnvPredFlag = 0x00000002L /* new SWI interface */ + SWIEnvPredFlag = 0x00000002L, /* new SWI interface */ + UDIPredFlag = 0x00000001L /* User Defined Indexing */ } pred_flag; /* profile data */ diff --git a/H/clause.h b/H/clause.h index f0aaa51a6..49854c1f8 100644 --- a/H/clause.h +++ b/H/clause.h @@ -330,6 +330,11 @@ PredEntry *STD_PROTO(Yap_PredEntryForCode,(yamop *, find_pred_type, CODEADDR *, LogUpdClause *STD_PROTO(Yap_new_ludbe,(Term, PredEntry *, UInt)); Term STD_PROTO(Yap_LUInstance,(LogUpdClause *, UInt)); +/* udi.c */ +void STD_PROTO(Yap_udi_init,(void)); +yamop *STD_PROTO(Yap_udi_search,(PredEntry *)); +int STD_PROTO(Yap_new_udi_clause,(PredEntry *, yamop *, Term)); + #ifdef DEBUG void STD_PROTO(Yap_bug_location,(yamop *)); #endif diff --git a/H/iatoms.h b/H/iatoms.h index addc172f7..717f0b908 100644 --- a/H/iatoms.h +++ b/H/iatoms.h @@ -210,6 +210,7 @@ AtomResourceError = Yap_LookupAtom("resource_error"); AtomRestoreRegs = Yap_FullLookupAtom("$restore_regs"); AtomRetryCounter = Yap_LookupAtom("retry_counter"); + AtomRTree = Yap_LookupAtom("rtree"); AtomSame = Yap_LookupAtom("=="); AtomSemic = Yap_LookupAtom(";"); AtomShiftCountOverflow = Yap_LookupAtom("shift_count_overflow"); diff --git a/H/ratoms.h b/H/ratoms.h index 77d848a94..071fb333a 100644 --- a/H/ratoms.h +++ b/H/ratoms.h @@ -212,6 +212,7 @@ AtomResourceError = AtomAdjust(AtomResourceError); AtomRestoreRegs = AtomAdjust(AtomRestoreRegs); AtomRetryCounter = AtomAdjust(AtomRetryCounter); + AtomRTree = AtomAdjust(AtomRTree); AtomSame = AtomAdjust(AtomSame); AtomSemic = AtomAdjust(AtomSemic); AtomShiftCountOverflow = AtomAdjust(AtomShiftCountOverflow); diff --git a/H/tatoms.h b/H/tatoms.h index 46cb0f99b..5cd4aa82b 100644 --- a/H/tatoms.h +++ b/H/tatoms.h @@ -426,6 +426,8 @@ #define AtomRestoreRegs Yap_heap_regs->AtomRestoreRegs_ Atom AtomRetryCounter_; #define AtomRetryCounter Yap_heap_regs->AtomRetryCounter_ + Atom AtomRTree_; +#define AtomRTree Yap_heap_regs->AtomRTree_ Atom AtomSame_; #define AtomSame Yap_heap_regs->AtomSame_ Atom AtomSemic_; diff --git a/Makefile.in b/Makefile.in index 28ee88a90..c0332786e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -100,6 +100,7 @@ MYDDAS_VERSION=MYDDAS-0.9.1 INTERFACE_HEADERS = \ $(srcdir)/include/c_interface.h \ $(srcdir)/include/clause_list.h \ + $(srcdir)/include/udi.h \ $(srcdir)/include/yap_structs.h \ $(srcdir)/include/YapInterface.h \ $(srcdir)/include/SWI-Prolog.h \ @@ -173,6 +174,7 @@ C_SOURCES= \ $(srcdir)/C/sort.c $(srcdir)/C/stdpreds.c $(srcdir)/C/sysbits.c \ $(srcdir)/C/threads.c \ $(srcdir)/C/tracer.c $(srcdir)/C/unify.c $(srcdir)/C/userpreds.c \ + $(srcdir)/C/udi.c \ $(srcdir)/C/utilpreds.c $(srcdir)/C/write.c $(srcdir)/console/yap.c \ $(srcdir)/C/ypsocks.c $(srcdir)/C/ypstdio.c \ $(srcdir)/BEAM/eam_am.c $(srcdir)/BEAM/eam_showcode.c \ @@ -241,6 +243,7 @@ ENGINE_OBJECTS = \ myddas_wkb2prolog.o modules.o other.o \ parser.o readutil.o save.o scanner.o sort.o stdpreds.o \ sysbits.o threads.o tracer.o \ + udi.o \ unify.o userpreds.o utilpreds.o \ write.o \ yap2swi.o ypsocks.o ypstdio.o @MPI_OBJS@ @@ -446,6 +449,9 @@ threads.o: $(srcdir)/C/threads.c tracer.o: $(srcdir)/C/tracer.c $(CC) -c $(CFLAGS) $(srcdir)/C/tracer.c -o $@ +udi.o: $(srcdir)/C/udi.c + $(CC) -c $(C_INTERF_FLAGS) $(srcdir)/C/udi.c -o $@ + unify.o: $(srcdir)/C/unify.c $(CC) -c $(CFLAGS) $(srcdir)/C/unify.c -o $@ diff --git a/include/udi.h b/include/udi.h new file mode 100644 index 000000000..8e99b137b --- /dev/null +++ b/include/udi.h @@ -0,0 +1,34 @@ + +/*chamada a cada index/2 + controi estrutura de control, para definir a indexação, contem a + rtree p.e. + retorna a estrutura de control +*/ +typedef void * +(* Yap_UdiInit)( + Term spec, /* mode spec */ + void *pred, /* pass predicate information */ + int arity); + +/*chamada a cada assert*/ +typedef void * +(* Yap_UdiInsert)(Term t, /* termo asserted */ + void *control, /* estrutura de control*/ + void *clausule); /* valor a guardar na arvore, para retornar na pesquisa */ + +/* chamada cada vez que um predicado indexado aparece no código + Returns: + NULL quando não há indexação usavel no predicado (fallback to +yap indexing) + FALSE + TRY_RETRY_TRUST quando há resultados positivos +*/ +typedef void * +(* Yap_UdiSearch)(void * control); + +typedef struct udi_control_block { + Yap_UdiInit init; + Yap_UdiInsert insert; + Yap_UdiSearch search; +} *UdiControlBlock; + diff --git a/misc/ATOMS b/misc/ATOMS index d6e847d94..05c5f7614 100644 --- a/misc/ATOMS +++ b/misc/ATOMS @@ -221,6 +221,7 @@ A Resize N "resize" A ResourceError N "resource_error" A RestoreRegs F "$restore_regs" A RetryCounter N "retry_counter" +A RTree N "rtree" A Same N "==" A Semic N ";" A ShiftCountOverflow N "shift_count_overflow"