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_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;
|
||||
}
|
||||
|
||||
|
||||
|
18
C/inlines.c
18
C/inlines.c
@ -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)
|
||||
{ /* ? \= ? */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
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
|
||||
* 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)
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user