expand C-interface to allow access to common term operations (request from Ingo Molnar).
This commit is contained in:
parent
1e737747bf
commit
388f4fb782
@ -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_CloseList,(Term, Term));
|
||||||
X_API int STD_PROTO(YAP_IsAttVar,(Term));
|
X_API int STD_PROTO(YAP_IsAttVar,(Term));
|
||||||
X_API Term STD_PROTO(YAP_AttsOfVar,(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 int STD_PROTO(YAP_FileNoFromStream,(Term));
|
||||||
X_API void *STD_PROTO(YAP_FileDescriptorFromStream,(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);
|
static int (*do_getf)(void);
|
||||||
|
|
||||||
@ -1050,6 +1055,46 @@ YAP_Unify(Term t1, Term t2)
|
|||||||
return out;
|
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
|
X_API Int
|
||||||
YAP_CurrentSlot(void)
|
YAP_CurrentSlot(void)
|
||||||
{
|
{
|
||||||
@ -2992,20 +3037,6 @@ YAP_AttsOfVar(Term t)
|
|||||||
return attv->Atts;
|
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
|
X_API int
|
||||||
YAP_FileNoFromStream(Term t)
|
YAP_FileNoFromStream(Term t)
|
||||||
{
|
{
|
||||||
@ -3026,3 +3057,24 @@ YAP_FileDescriptorFromStream(Term t)
|
|||||||
return Yap_FileDescriptorFromStream(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
18
C/inlines.c
18
C/inlines.c
@ -282,15 +282,15 @@ p_equal(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
p_eq(void)
|
eq(Term t1, Term t2)
|
||||||
{ /* ? == ? */
|
{ /* ? == ? */
|
||||||
BEGD(d0);
|
BEGD(d0);
|
||||||
d0 = ARG1;
|
d0 = t1;
|
||||||
deref_head(d0, p_eq_unk1);
|
deref_head(d0, p_eq_unk1);
|
||||||
p_eq_nvar1:
|
p_eq_nvar1:
|
||||||
/* first argument is bound */
|
/* first argument is bound */
|
||||||
BEGD(d1);
|
BEGD(d1);
|
||||||
d1 = ARG2;
|
d1 = t2;
|
||||||
deref_head(d1, p_eq_nvar1_unk2);
|
deref_head(d1, p_eq_nvar1_unk2);
|
||||||
p_eq_nvar1_nvar2:
|
p_eq_nvar1_nvar2:
|
||||||
/* both arguments are bound */
|
/* both arguments are bound */
|
||||||
@ -365,6 +365,18 @@ p_eq(void)
|
|||||||
ENDD(d0);
|
ENDD(d0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
p_eq(void)
|
||||||
|
{ /* ? == ? */
|
||||||
|
return eq(ARG1,ARG2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Yap_eq(Term t1, Term t2)
|
||||||
|
{ /* ? == ? */
|
||||||
|
return eq(t1,t2);
|
||||||
|
}
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
p_dif(void)
|
p_dif(void)
|
||||||
{ /* ? \= ? */
|
{ /* ? \= ? */
|
||||||
|
@ -2936,6 +2936,37 @@ hash_complex_term(register CELL *pt0,
|
|||||||
return (CELL *) -2;
|
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
|
static Int
|
||||||
p_term_hash(void)
|
p_term_hash(void)
|
||||||
{
|
{
|
||||||
@ -3239,11 +3270,9 @@ static int variant_complex(register CELL *pt0, register CELL *pt0_end, register
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static int
|
||||||
p_variant(void) /* variant terms t1 and t2 */
|
is_variant(Term t1, Term t2, int parity)
|
||||||
{
|
{
|
||||||
Term t1 = Deref(ARG1);
|
|
||||||
Term t2 = Deref(ARG2);
|
|
||||||
int out;
|
int out;
|
||||||
|
|
||||||
if (t1 == t2)
|
if (t1 == t2)
|
||||||
@ -3284,15 +3313,27 @@ p_variant(void) /* variant terms t1 and t2 */
|
|||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
if (out == -1) {
|
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");
|
Yap_Error(OUT_OF_STACK_ERROR, TermNil, "in variant");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return p_variant();
|
return is_variant(t1, t2, parity);
|
||||||
}
|
}
|
||||||
return FALSE;
|
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
|
static int subsumes_complex(register CELL *pt0, register CELL *pt0_end, register
|
||||||
CELL *pt1)
|
CELL *pt1)
|
||||||
|
@ -248,6 +248,7 @@ void STD_PROTO(Yap_CloseScratchPad,(void));
|
|||||||
|
|
||||||
/* inlines.c */
|
/* inlines.c */
|
||||||
void STD_PROTO(Yap_InitInlines,(void));
|
void STD_PROTO(Yap_InitInlines,(void));
|
||||||
|
int STD_PROTO(Yap_eq,(Term, Term));
|
||||||
|
|
||||||
/* iopreds.c */
|
/* iopreds.c */
|
||||||
void STD_PROTO(Yap_InitPlIO,(void));
|
void STD_PROTO(Yap_InitPlIO,(void));
|
||||||
@ -372,6 +373,7 @@ void STD_PROTO(Yap_InitUserBacks,(void));
|
|||||||
|
|
||||||
/* utilpreds.c */
|
/* utilpreds.c */
|
||||||
Term STD_PROTO(Yap_CopyTerm,(Term));
|
Term STD_PROTO(Yap_CopyTerm,(Term));
|
||||||
|
int STD_PROTO(Yap_Variant,(Term, Term));
|
||||||
int STD_PROTO(Yap_ExportTerm,(Term, char *, size_t));
|
int STD_PROTO(Yap_ExportTerm,(Term, char *, size_t));
|
||||||
Term STD_PROTO(Yap_ImportTerm,(char *));
|
Term STD_PROTO(Yap_ImportTerm,(char *));
|
||||||
int STD_PROTO(Yap_IsListTerm,(Term));
|
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_SizeGroundTerm,(Term, int));
|
||||||
int STD_PROTO(Yap_IsGroundTerm,(Term));
|
int STD_PROTO(Yap_IsGroundTerm,(Term));
|
||||||
void STD_PROTO(Yap_InitUtilCPreds,(void));
|
void STD_PROTO(Yap_InitUtilCPreds,(void));
|
||||||
|
Int STD_PROTO(Yap_TermHash,(Term, Int, Int, int));
|
||||||
/* yap.c */
|
/* yap.c */
|
||||||
|
|
||||||
/* MYDDAS */
|
/* MYDDAS */
|
||||||
|
70
docs/yap.tex
70
docs/yap.tex
@ -296,6 +296,7 @@ Subnodes of C-Interface
|
|||||||
* Manipulating Strings:: From character arrays to Lists of codes and back
|
* Manipulating Strings:: From character arrays to Lists of codes and back
|
||||||
* Memory Allocation:: Stealing Memory From YAP
|
* Memory Allocation:: Stealing Memory From YAP
|
||||||
* Controlling Streams:: Control How YAP sees Streams
|
* 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
|
* Calling YAP From C:: From C to YAP to C to YAP
|
||||||
* Module Manipulation in C:: Create and Test Modules from within C
|
* Module Manipulation in C:: Create and Test Modules from within C
|
||||||
* Writing C:: Writing Predicates in 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
|
* Manipulating Strings:: From character arrays to Lists of codes and back
|
||||||
* Memory Allocation:: Stealing Memory From YAP
|
* Memory Allocation:: Stealing Memory From YAP
|
||||||
* Controlling Streams:: Control How YAP sees Streams
|
* 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
|
* Calling YAP From C:: From C to YAP to C to YAP
|
||||||
* Module Manipulation in C:: Create and Test Modules from within C
|
* Module Manipulation in C:: Create and Test Modules from within C
|
||||||
* Writing C:: Writing Predicates in 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
|
may crash if @code{buf} is not a valid pointer to a buffer in the code
|
||||||
area.
|
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}
|
@section Controlling YAP Streams from @code{C}
|
||||||
|
|
||||||
@findex YAP_StreamToFileNo (C-Interface function)
|
@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
|
stream is supposed to be at position 0. The argument @var{name} gives
|
||||||
the name by which YAP should know the new stream.
|
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
|
@section From @code{C} back to Prolog
|
||||||
|
|
||||||
@findex YAP_RunGoal (C-Interface function)
|
@findex YAP_RunGoal (C-Interface function)
|
||||||
|
@ -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 void *PROTO(YAP_FileDescriptorFromStream,(YAP_Term));
|
||||||
extern X_API int PROTO(YAP_FileNoFromStream,(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)
|
#define YAP_InitCPred(N,A,F) YAP_UserCPredicate(N,F,A)
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
Reference in New Issue
Block a user