| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "clause.h"
 | 
					
						
							|  |  |  | #include "udi.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-20 15:52:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-20 11:42:48 +00:00
										 |  |  | #include "rtree_udi.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | /* we can have this stactic because it is written once */ | 
					
						
							|  |  |  | static struct udi_control_block RtreeCmd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  | /******
 | 
					
						
							|  |  |  |        All the info we need to enter user indexed code: | 
					
						
							|  |  |  |         predicate | 
					
						
							|  |  |  | 	the user control block | 
					
						
							|  |  |  | 	functions used, in case we have different schema (maybe should part of previous) | 
					
						
							|  |  |  | 	right now, this is just a linked list.... | 
					
						
							|  |  |  | ******/ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | typedef struct udi_info | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PredEntry *p; | 
					
						
							|  |  |  |   void *cb; | 
					
						
							|  |  |  |   UdiControlBlock functions; | 
					
						
							|  |  |  |   struct udi_info *next; | 
					
						
							|  |  |  | } *UdiInfo; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  | /******
 | 
					
						
							|  |  |  |       we now have one extra user indexed predicate. We assume these | 
					
						
							|  |  |  |       are few, so we can do with a linked list. | 
					
						
							|  |  |  | ******/ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  | /******
 | 
					
						
							|  |  |  |       new user indexed predicate; | 
					
						
							|  |  |  |       the type right now is just rtrees, but in the future we'll have more. | 
					
						
							|  |  |  |       the second argument is the term. | 
					
						
							|  |  |  | ******/ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_new_udi( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Term spec = Deref(ARG2), udi_type = Deref(ARG1); | 
					
						
							|  |  |  |   PredEntry *p; | 
					
						
							|  |  |  |   UdiControlBlock cmd; | 
					
						
							|  |  |  |   Atom udi_t; | 
					
						
							|  |  |  |   void *info; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-02 17:34:42 +01:00
										 |  |  | /*  fprintf(stderr,"new pred babe\n");*/ | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  |   /* get the predicate from the spec, copied from cdmgr.c */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  |   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); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-02-20 11:42:48 +00:00
										 |  |  |     p = RepPredProp(PredPropByFunc(fun, tmod)); | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-02-20 11:42:48 +00:00
										 |  |  |   if (!p) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  |   /* boring, boring, boring! */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  |   /* just make sure we're looking at the right user type! */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  |   /* this is the real work */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  |   info = cmd->init(spec, (void *)p, p->ArityOfPE); | 
					
						
							|  |  |  |   if (!info) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  |   /* add to table */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  |   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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  | /* just pass info to user, called from cdmgr.c */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 21:45:41 +00:00
										 |  |  | /* index, called from absmi.c */ | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | 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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-21 16:47:19 +01:00
										 |  |  | /* index, called from absmi.c */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | Yap_udi_abolish(PredEntry *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* tell the predicate destroy */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | void | 
					
						
							|  |  |  | Yap_udi_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   UdiControlBlocks = NULL; | 
					
						
							|  |  |  |   /* to be filled in by David */ | 
					
						
							| 
									
										
										
										
											2009-02-20 11:42:48 +00:00
										 |  |  |   RtreeCmd.init = RtreeUdiInit; | 
					
						
							|  |  |  |   RtreeCmd.insert = RtreeUdiInsert; | 
					
						
							|  |  |  |   RtreeCmd.search = RtreeUdiSearch; | 
					
						
							|  |  |  |   RtreeCmd.destroy = RtreeUdiDestroy; | 
					
						
							|  |  |  |   Yap_InitCPred("$udi_init", 2, p_new_udi, 0); | 
					
						
							| 
									
										
										
										
											2009-02-12 16:39:20 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-20 15:52:17 +00:00
										 |  |  | 
 |