support for user defined indexing: step 1 basic routines.
This commit is contained in:
		
							
								
								
									
										131
									
								
								C/udi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								C/udi.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								H/Heap.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								H/Heap.h
									
									
									
									
									
								
							| @@ -307,6 +307,7 @@ typedef struct various_codes { | |||||||
| #if USE_THREADED_CODE | #if USE_THREADED_CODE | ||||||
|   opentry *op_rtable; |   opentry *op_rtable; | ||||||
| #endif | #endif | ||||||
|  |   struct udi_info *udi_control_blocks; | ||||||
| #ifdef COROUTINING | #ifdef COROUTINING | ||||||
|   int  num_of_atts;            /* max. number of attributes we have for a variable */ |   int  num_of_atts;            /* max. number of attributes we have for a variable */ | ||||||
|   struct pred_entry  *wake_up_code; |   struct pred_entry  *wake_up_code; | ||||||
| @@ -527,6 +528,7 @@ extern struct various_codes *Yap_heap_regs; | |||||||
| #if USE_THREADED_CODE | #if USE_THREADED_CODE | ||||||
| #define  OP_RTABLE                Yap_heap_regs->op_rtable | #define  OP_RTABLE                Yap_heap_regs->op_rtable | ||||||
| #endif | #endif | ||||||
|  | #define  UdiControlBlocks	  Yap_heap_regs->udi_control_blocks | ||||||
| #define  PROFILING                Yap_heap_regs->system_profiling | #define  PROFILING                Yap_heap_regs->system_profiling | ||||||
| #define  CALL_COUNTING            Yap_heap_regs->system_call_counting | #define  CALL_COUNTING            Yap_heap_regs->system_call_counting | ||||||
| #define  PRED_GOAL_EXPANSION_ALL  Yap_heap_regs->system_pred_goal_expansion_all | #define  PRED_GOAL_EXPANSION_ALL  Yap_heap_regs->system_pred_goal_expansion_all | ||||||
|   | |||||||
| @@ -635,7 +635,7 @@ IsValProperty (int flags) | |||||||
| */ | */ | ||||||
| typedef enum | 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 */ |   ThreadLocalPredFlag = 0x40000000L,	/* local to a thread */ | ||||||
|   MultiFileFlag = 0x20000000L,	/* is multi-file */ |   MultiFileFlag = 0x20000000L,	/* is multi-file */ | ||||||
|   UserCPredFlag = 0x10000000L,	/* CPred defined by the user */ |   UserCPredFlag = 0x10000000L,	/* CPred defined by the user */ | ||||||
| @@ -665,7 +665,8 @@ typedef enum | |||||||
|   ProfiledPredFlag = 0x00000010L,	/* pred is being profiled   */ |   ProfiledPredFlag = 0x00000010L,	/* pred is being profiled   */ | ||||||
|   MyddasPredFlag = 0x00000008L,	/* Myddas Imported pred  */ |   MyddasPredFlag = 0x00000008L,	/* Myddas Imported pred  */ | ||||||
|   ModuleTransparentPredFlag = 0x00000004L,	/* ModuleTransparent pred  */ |   ModuleTransparentPredFlag = 0x00000004L,	/* ModuleTransparent pred  */ | ||||||
|   SWIEnvPredFlag = 0x00000002L	/* new SWI interface */ |   SWIEnvPredFlag = 0x00000002L,	/* new SWI interface */ | ||||||
|  |   UDIPredFlag = 0x00000001L	/* User Defined Indexing */ | ||||||
| } pred_flag; | } pred_flag; | ||||||
|  |  | ||||||
| /* profile data */ | /* profile data */ | ||||||
|   | |||||||
| @@ -330,6 +330,11 @@ PredEntry *STD_PROTO(Yap_PredEntryForCode,(yamop *, find_pred_type, CODEADDR *, | |||||||
| LogUpdClause   *STD_PROTO(Yap_new_ludbe,(Term, PredEntry *, UInt)); | LogUpdClause   *STD_PROTO(Yap_new_ludbe,(Term, PredEntry *, UInt)); | ||||||
| Term            STD_PROTO(Yap_LUInstance,(LogUpdClause *, 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 | #ifdef DEBUG | ||||||
| void    STD_PROTO(Yap_bug_location,(yamop *)); | void    STD_PROTO(Yap_bug_location,(yamop *)); | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -210,6 +210,7 @@ | |||||||
|   AtomResourceError = Yap_LookupAtom("resource_error"); |   AtomResourceError = Yap_LookupAtom("resource_error"); | ||||||
|   AtomRestoreRegs = Yap_FullLookupAtom("$restore_regs"); |   AtomRestoreRegs = Yap_FullLookupAtom("$restore_regs"); | ||||||
|   AtomRetryCounter = Yap_LookupAtom("retry_counter"); |   AtomRetryCounter = Yap_LookupAtom("retry_counter"); | ||||||
|  |   AtomRTree = Yap_LookupAtom("rtree"); | ||||||
|   AtomSame = Yap_LookupAtom("=="); |   AtomSame = Yap_LookupAtom("=="); | ||||||
|   AtomSemic = Yap_LookupAtom(";"); |   AtomSemic = Yap_LookupAtom(";"); | ||||||
|   AtomShiftCountOverflow = Yap_LookupAtom("shift_count_overflow"); |   AtomShiftCountOverflow = Yap_LookupAtom("shift_count_overflow"); | ||||||
|   | |||||||
| @@ -212,6 +212,7 @@ | |||||||
|   AtomResourceError = AtomAdjust(AtomResourceError); |   AtomResourceError = AtomAdjust(AtomResourceError); | ||||||
|   AtomRestoreRegs = AtomAdjust(AtomRestoreRegs); |   AtomRestoreRegs = AtomAdjust(AtomRestoreRegs); | ||||||
|   AtomRetryCounter = AtomAdjust(AtomRetryCounter); |   AtomRetryCounter = AtomAdjust(AtomRetryCounter); | ||||||
|  |   AtomRTree = AtomAdjust(AtomRTree); | ||||||
|   AtomSame = AtomAdjust(AtomSame); |   AtomSame = AtomAdjust(AtomSame); | ||||||
|   AtomSemic = AtomAdjust(AtomSemic); |   AtomSemic = AtomAdjust(AtomSemic); | ||||||
|   AtomShiftCountOverflow = AtomAdjust(AtomShiftCountOverflow); |   AtomShiftCountOverflow = AtomAdjust(AtomShiftCountOverflow); | ||||||
|   | |||||||
| @@ -426,6 +426,8 @@ | |||||||
| #define AtomRestoreRegs Yap_heap_regs->AtomRestoreRegs_ | #define AtomRestoreRegs Yap_heap_regs->AtomRestoreRegs_ | ||||||
|   Atom AtomRetryCounter_; |   Atom AtomRetryCounter_; | ||||||
| #define AtomRetryCounter Yap_heap_regs->AtomRetryCounter_ | #define AtomRetryCounter Yap_heap_regs->AtomRetryCounter_ | ||||||
|  |   Atom AtomRTree_; | ||||||
|  | #define AtomRTree Yap_heap_regs->AtomRTree_ | ||||||
|   Atom AtomSame_; |   Atom AtomSame_; | ||||||
| #define AtomSame Yap_heap_regs->AtomSame_ | #define AtomSame Yap_heap_regs->AtomSame_ | ||||||
|   Atom AtomSemic_; |   Atom AtomSemic_; | ||||||
|   | |||||||
| @@ -100,6 +100,7 @@ MYDDAS_VERSION=MYDDAS-0.9.1 | |||||||
| INTERFACE_HEADERS = \ | INTERFACE_HEADERS = \ | ||||||
| 	$(srcdir)/include/c_interface.h \ | 	$(srcdir)/include/c_interface.h \ | ||||||
| 	$(srcdir)/include/clause_list.h \ | 	$(srcdir)/include/clause_list.h \ | ||||||
|  | 	$(srcdir)/include/udi.h \ | ||||||
| 	$(srcdir)/include/yap_structs.h \ | 	$(srcdir)/include/yap_structs.h \ | ||||||
| 	$(srcdir)/include/YapInterface.h \ | 	$(srcdir)/include/YapInterface.h \ | ||||||
| 	$(srcdir)/include/SWI-Prolog.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/sort.c $(srcdir)/C/stdpreds.c $(srcdir)/C/sysbits.c \ | ||||||
| 	$(srcdir)/C/threads.c \ | 	$(srcdir)/C/threads.c \ | ||||||
| 	$(srcdir)/C/tracer.c $(srcdir)/C/unify.c $(srcdir)/C/userpreds.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/utilpreds.c $(srcdir)/C/write.c $(srcdir)/console/yap.c \ | ||||||
| 	$(srcdir)/C/ypsocks.c $(srcdir)/C/ypstdio.c \ | 	$(srcdir)/C/ypsocks.c $(srcdir)/C/ypstdio.c \ | ||||||
| 	$(srcdir)/BEAM/eam_am.c $(srcdir)/BEAM/eam_showcode.c \ | 	$(srcdir)/BEAM/eam_am.c $(srcdir)/BEAM/eam_showcode.c \ | ||||||
| @@ -241,6 +243,7 @@ ENGINE_OBJECTS = \ | |||||||
| 	myddas_wkb2prolog.o modules.o other.o   \ | 	myddas_wkb2prolog.o modules.o other.o   \ | ||||||
| 	parser.o readutil.o save.o scanner.o sort.o stdpreds.o \ | 	parser.o readutil.o save.o scanner.o sort.o stdpreds.o \ | ||||||
| 	sysbits.o threads.o tracer.o \ | 	sysbits.o threads.o tracer.o \ | ||||||
|  | 	udi.o \ | ||||||
| 	unify.o userpreds.o utilpreds.o \ | 	unify.o userpreds.o utilpreds.o \ | ||||||
| 	write.o \ | 	write.o \ | ||||||
| 	yap2swi.o ypsocks.o ypstdio.o @MPI_OBJS@ | 	yap2swi.o ypsocks.o ypstdio.o @MPI_OBJS@ | ||||||
| @@ -446,6 +449,9 @@ threads.o: $(srcdir)/C/threads.c | |||||||
| tracer.o: $(srcdir)/C/tracer.c | tracer.o: $(srcdir)/C/tracer.c | ||||||
| 	$(CC) -c $(CFLAGS) $(srcdir)/C/tracer.c -o $@ | 	$(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 | unify.o: $(srcdir)/C/unify.c | ||||||
| 	$(CC) -c $(CFLAGS) $(srcdir)/C/unify.c -o $@ | 	$(CC) -c $(CFLAGS) $(srcdir)/C/unify.c -o $@ | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								include/udi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								include/udi.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
|  |  | ||||||
| @@ -221,6 +221,7 @@ A	Resize			N	"resize" | |||||||
| A	ResourceError		N	"resource_error" | A	ResourceError		N	"resource_error" | ||||||
| A	RestoreRegs		F	"$restore_regs" | A	RestoreRegs		F	"$restore_regs" | ||||||
| A	RetryCounter		N	"retry_counter" | A	RetryCounter		N	"retry_counter" | ||||||
|  | A	RTree			N	"rtree" | ||||||
| A	Same			N	"==" | A	Same			N	"==" | ||||||
| A	Semic			N	";" | A	Semic			N	";" | ||||||
| A	ShiftCountOverflow	N	"shift_count_overflow" | A	ShiftCountOverflow	N	"shift_count_overflow" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user