expand C-interface to allow access to common term operations (request from Ingo Molnar).

This commit is contained in:
Vítor Santos Costa 2010-08-02 19:48:17 +01:00
parent 1e737747bf
commit 388f4fb782
6 changed files with 211 additions and 28 deletions

View File

@ -509,9 +509,14 @@ X_API Term STD_PROTO(YAP_ExtendList,(Term, Term));
X_API int STD_PROTO(YAP_CloseList,(Term, Term));
X_API int STD_PROTO(YAP_IsAttVar,(Term));
X_API Term STD_PROTO(YAP_AttsOfVar,(Term));
X_API Term STD_PROTO(YAP_TermHash,(Term));
X_API int STD_PROTO(YAP_FileNoFromStream,(Term));
X_API void *STD_PROTO(YAP_FileDescriptorFromStream,(Term));
X_API void *STD_PROTO(YAP_Record,(Term));
X_API Term STD_PROTO(YAP_Recorded,(void *));
X_API int STD_PROTO(YAP_Erase,(void *));
X_API int STD_PROTO(YAP_Variant,(Term, Term));
X_API int STD_PROTO(YAP_ExactlyEqual,(Term, Term));
X_API Int STD_PROTO(YAP_TermHash,(Term, Int, Int, int));
static int (*do_getf)(void);
@ -1050,6 +1055,46 @@ YAP_Unify(Term t1, Term t2)
return out;
}
/* == */
X_API int
YAP_ExactlyEqual(Term t1, Term t2)
{
int out;
BACKUP_MACHINE_REGS();
out = Yap_eq(t1, t2);
RECOVER_MACHINE_REGS();
return out;
}
/* =@= */
X_API int
YAP_Variant(Term t1, Term t2)
{
int out;
BACKUP_MACHINE_REGS();
out = Yap_Variant(Deref(t1), Deref(t2));
RECOVER_MACHINE_REGS();
return out;
}
/* =@= */
X_API Int
YAP_TermHash(Term t, Int sz, Int depth, int variant)
{
Int out;
BACKUP_MACHINE_REGS();
out = Yap_TermHash(t, sz, depth, variant);
RECOVER_MACHINE_REGS();
return out;
}
X_API Int
YAP_CurrentSlot(void)
{
@ -2992,20 +3037,6 @@ YAP_AttsOfVar(Term t)
return attv->Atts;
}
X_API Term
YAP_TermHash(Term t)
{
attvar_record *attv;
t = Deref(t);
if (!IsVarTerm(t))
return TermNil;
if (IsAttVar(VarOfTerm(t)))
return TermNil;
attv = (attvar_record *)VarOfTerm(t);
return attv->Atts;
}
X_API int
YAP_FileNoFromStream(Term t)
{
@ -3026,3 +3057,24 @@ YAP_FileDescriptorFromStream(Term t)
return Yap_FileDescriptorFromStream(t);
}
X_API void *
YAP_Record(Term t)
{
return (void *)Yap_StoreTermInDB(Deref(t), 0);
}
X_API Term
YAP_Recorded(void *handle)
{
return Yap_FetchTermFromDB((DBTerm *)handle);
}
X_API int
YAP_Erase(void *handle)
{
Yap_ReleaseTermFromDB((DBTerm *)handle);
return 1;
}

View File

@ -282,15 +282,15 @@ p_equal(void)
}
static Int
p_eq(void)
eq(Term t1, Term t2)
{ /* ? == ? */
BEGD(d0);
d0 = ARG1;
d0 = t1;
deref_head(d0, p_eq_unk1);
p_eq_nvar1:
/* first argument is bound */
BEGD(d1);
d1 = ARG2;
d1 = t2;
deref_head(d1, p_eq_nvar1_unk2);
p_eq_nvar1_nvar2:
/* both arguments are bound */
@ -365,6 +365,18 @@ p_eq(void)
ENDD(d0);
}
static Int
p_eq(void)
{ /* ? == ? */
return eq(ARG1,ARG2);
}
int
Yap_eq(Term t1, Term t2)
{ /* ? == ? */
return eq(t1,t2);
}
static Int
p_dif(void)
{ /* ? \= ? */

View File

@ -2936,6 +2936,37 @@ hash_complex_term(register CELL *pt0,
return (CELL *) -2;
}
Int
Yap_TermHash(Term t, Int size, Int depth, int variant)
{
unsigned int i1;
Term t1 = Deref(t);
while (TRUE) {
CELL *ar = hash_complex_term(&t1-1, &t1, depth, H, FALSE);
if (ar == (CELL *)-1) {
if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE)) {
Yap_Error(OUT_OF_AUXSPACE_ERROR, ARG1, "overflow in term_hash");
return FALSE;
}
t1 = Deref(ARG1);
} else if(ar == (CELL *)-2) {
if (!Yap_gcl((ASP-H)*sizeof(CELL), 0, ENV, gc_P(P,CP))) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, "in term_hash");
return FALSE;
}
t1 = Deref(ARG1);
} else if (ar == NULL) {
return FALSE;
} else {
i1 = MurmurHashNeutral2((const void *)H, CellSize*(ar-H),0x1a3be34a);
break;
}
}
/* got the seed and hash from SWI-Prolog */
return i1 % size;
}
static Int
p_term_hash(void)
{
@ -3239,11 +3270,9 @@ static int variant_complex(register CELL *pt0, register CELL *pt0_end, register
return FALSE;
}
static Int
p_variant(void) /* variant terms t1 and t2 */
static int
is_variant(Term t1, Term t2, int parity)
{
Term t1 = Deref(ARG1);
Term t2 = Deref(ARG2);
int out;
if (t1 == t2)
@ -3284,15 +3313,27 @@ p_variant(void) /* variant terms t1 and t2 */
}
error:
if (out == -1) {
if (!Yap_gcl((ASP-H)*sizeof(CELL), 2, ENV, gc_P(P,CP))) {
if (!Yap_gcl((ASP-H)*sizeof(CELL), parity, ENV, gc_P(P,CP))) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, "in variant");
return FALSE;
}
return p_variant();
return is_variant(t1, t2, parity);
}
return FALSE;
}
int
Yap_Variant(Term t1, Term t2)
{
return is_variant(t1, t2, 0);
}
static Int
p_variant(void) /* variant terms t1 and t2 */
{
return is_variant(Deref(ARG1), Deref(ARG2), 2);
}
static int subsumes_complex(register CELL *pt0, register CELL *pt0_end, register
CELL *pt1)

View File

@ -247,7 +247,8 @@ int STD_PROTO(Yap_OpDec,(int,char *,Atom,Term));
void STD_PROTO(Yap_CloseScratchPad,(void));
/* inlines.c */
void STD_PROTO(Yap_InitInlines,(void));
void STD_PROTO(Yap_InitInlines,(void));
int STD_PROTO(Yap_eq,(Term, Term));
/* iopreds.c */
void STD_PROTO(Yap_InitPlIO,(void));
@ -372,6 +373,7 @@ void STD_PROTO(Yap_InitUserBacks,(void));
/* utilpreds.c */
Term STD_PROTO(Yap_CopyTerm,(Term));
int STD_PROTO(Yap_Variant,(Term, Term));
int STD_PROTO(Yap_ExportTerm,(Term, char *, size_t));
Term STD_PROTO(Yap_ImportTerm,(char *));
int STD_PROTO(Yap_IsListTerm,(Term));
@ -379,7 +381,7 @@ Term STD_PROTO(Yap_CopyTermNoShare,(Term));
int STD_PROTO(Yap_SizeGroundTerm,(Term, int));
int STD_PROTO(Yap_IsGroundTerm,(Term));
void STD_PROTO(Yap_InitUtilCPreds,(void));
Int STD_PROTO(Yap_TermHash,(Term, Int, Int, int));
/* yap.c */
/* MYDDAS */

View File

@ -296,6 +296,7 @@ Subnodes of C-Interface
* Manipulating Strings:: From character arrays to Lists of codes and back
* Memory Allocation:: Stealing Memory From YAP
* Controlling Streams:: Control How YAP sees Streams
* Utility Functions:: From character arrays to Lists of codes and back
* Calling YAP From C:: From C to YAP to C to YAP
* Module Manipulation in C:: Create and Test Modules from within C
* Writing C:: Writing Predicates in C
@ -15140,6 +15141,7 @@ The rest of this appendix describes exhaustively how to interface C to YAP.
* Manipulating Strings:: From character arrays to Lists of codes and back
* Memory Allocation:: Stealing Memory From YAP
* Controlling Streams:: Control How YAP sees Streams
* Utility Functions:: From character arrays to Lists of codes and back
* Calling YAP From C:: From C to YAP to C to YAP
* Module Manipulation in C:: Create and Test Modules from within C
* Writing C:: Writing Predicates in C
@ -15509,7 +15511,7 @@ The routine releases a buffer allocated from the code area. The system
may crash if @code{buf} is not a valid pointer to a buffer in the code
area.
@node Controlling Streams, Calling YAP From C, Memory Allocation, C-Interface
@node Controlling Streams, Utility Functions, Memory Allocation, C-Interface
@section Controlling YAP Streams from @code{C}
@findex YAP_StreamToFileNo (C-Interface function)
@ -15561,7 +15563,71 @@ The available flags are @code{YAP_INPUT_STREAM},
stream is supposed to be at position 0. The argument @var{name} gives
the name by which YAP should know the new stream.
@node Calling YAP From C, Module Manipulation in C, Controlling Streams, C-Interface
@node Utility Functions, Calling YAP From C, Controlling Streams, C-Interface
@section Utility Functions in @code{C}
The C-Interface provides the C-application with a a number of utility
functions that are useful.
@findex YAP_Record (C-Interface function)
The first provides a way to insert a term into the data-base
@example
void *YAP_Record(YAP_Term @var{t})
@end example
@noindent
This function returns a pointer to a copy of the term in the database
(or to @t{NULL} if the operation fails.
@findex YAP_Recorded (C-Interface function)
The next functions provides a way to recover the term from the data-base:
@example
YAP_Term YAP_Recorded(void *@var{handle})
@end example
@noindent
Notice that the semantics are the same as for @code{recorded/3}: this
function creates a new copy of the term in the stack, with fresh
variables. The function returns @t{0L} if it cannot create a new term.
@findex YAP_Erase (C-Interface function)
Last, the next function allows one to recover space:
@example
int YAP_Erase(void *@var{handle})
@end example
@noindent
Notice that any accesses using @var{handle} after this operation may
lead to a crash.
The following functions are often required to compare terms.
@findex YAP_ExactlyEqual (C-Interface function)
The first function succeeds if two terms are actually the same term, as
@code{==/2}:
@example
int YAP_ExactlyEqual(YAP_Term t1, YAP_Term t2)
@end example
@noindent
The second function succeeds if two terms are variant terms, and returns
0 otherwise, as
@code{=@=/2}:
@example
int YAP_Variant(YAP_Term t1, YAP_Term t2)
@end example
@noindent
The second function computes a hash function for a term, as in
@code{term_hash/4}.
@example
YAP_Int YAP_TermHash(YAP_Term t, YAP_Int range, YAP_Int depth, int ignore_variables));
@end example
@noindent
The first three arguments follow @code{term_has/4}. The last argument
indicates what to do if we find a variable: if @code{0} fail, otherwise
ignore the variable.
@node Calling YAP From C, Module Manipulation in C, Utility Functions, C-Interface
@section From @code{C} back to Prolog
@findex YAP_RunGoal (C-Interface function)

View File

@ -494,6 +494,16 @@ extern X_API YAP_Term PROTO(YAP_AttsOfVar,(YAP_Term));
extern X_API void *PROTO(YAP_FileDescriptorFromStream,(YAP_Term));
extern X_API int PROTO(YAP_FileNoFromStream,(YAP_Term));
/* store and recover terms */
extern X_API void *PROTO(YAP_Record,(YAP_Term));
extern X_API YAP_Term PROTO(YAP_Recorded,(void *));
extern X_API int PROTO(YAP_Erase,(void *));
/* term utilities */
extern X_API int PROTO(YAP_Variant,(YAP_Term,YAP_Term));
extern X_API int PROTO(YAP_ExactlyEqual,(YAP_Term,YAP_Term));
extern X_API YAP_Int PROTO(YAP_TermHash,(YAP_Term, YAP_Int, YAP_Int, int));
#define YAP_InitCPred(N,A,F) YAP_UserCPredicate(N,F,A)
__END_DECLS