Merge branch 'master' of git.dcc.fc.up.pt:yap-6.3

Conflicts:
	library/listing.yap
This commit is contained in:
Vitor Santos Costa 2014-05-05 13:59:58 +01:00
commit f1b88583e4
17 changed files with 1252 additions and 1030 deletions

View File

@ -1146,8 +1146,15 @@ X_API int PL_unify_int64__LD(term_t t, int64_t n ARG_LD)
#else #else
if ((long)n == n) if ((long)n == n)
return PL_unify_integer(t, n); return PL_unify_integer(t, n);
fprintf(stderr,"Error in PL_unify_int64: please install GMP\n"); // use a double, but will mess up writing.
return FALSE; else {
union {
int64_t i;
double d;
} udi_;
udi_.i = n;
return PL_unify_float(t, udi_.d);
}
#endif #endif
} }

View File

@ -408,7 +408,7 @@ int YAPPredicate::call(YAPTerm t[])
return ret; return ret;
} }
YAP::YAP(YAPParams const& params) YAPEngine::YAPEngine(YAPParams const& params)
{ YAP_Init( (YAP_init_args *)&params.init_args ); } { YAP_Init( (YAP_init_args *)&params.init_args ); }

View File

@ -1,9 +1,26 @@
#define YAP_CPP_INTERFACE 1 #define YAP_CPP_INTERFACE 1
/**
*
* @defgroup yap-cplus-interface An object oriented interface for YAP.
*
*
* @tableofcontents
*
*
* C++ interface to YAP. Designed to be object oriented and to fit naturally
* with the swig interface language generator. It uses ideas from the old YAP
* interface and from the SWI foreign language interface.
*
*/
#include <stdlib.h> #include <stdlib.h>
#include <config.h>
#if USE_GMP
#include <gmp.h> #include <gmp.h>
#endif
extern "C" { extern "C" {
@ -43,18 +60,24 @@ extern "C" {
#include <windows.h> #include <windows.h>
#endif #endif
// taken from yap_structs.h // taken from yap_structs.h
#include "iopreds.h" #include "iopreds.h"
// we cannot consult YapInterface.h, that conflicts with what we declare, though // we cannot consult YapInterface.h, that conflicts with what we declare, though
// it shouldn't // it shouldn't
} }
//#include <vector>
class YAPEngine;
class YAPTermHandle; class YAPTermHandle;
class YAPAtom; class YAPAtom;
class YAPFunctor; class YAPFunctor;
class YAPQuery; class YAPQuery;
/**
* @brief Generic Prolog Term
*/
class YAPTerm { class YAPTerm {
friend class YAPPredicate; friend class YAPPredicate;
friend class YAPTermHandle; friend class YAPTermHandle;
@ -63,8 +86,7 @@ class YAPTerm {
protected: protected:
Term t; Term t;
public: public:
YAPTerm() {} // do nothing constructor YAPTerm() { t = TermNil; } // do nothing constructor
YAPTerm(int i) { CACHE_REGS t = MkIntegerTerm( i ); }
YAPTerm(void *ptr) { CACHE_REGS t = MkIntegerTerm( (Int)ptr ); } YAPTerm(void *ptr) { CACHE_REGS t = MkIntegerTerm( (Int)ptr ); }
YAPTerm(Term tn) { t = tn; } YAPTerm(Term tn) { t = tn; }
YAPTerm(char *s) { Term tp ; t = YAP_ReadBuffer(s,&tp); } YAPTerm(char *s) { Term tp ; t = YAP_ReadBuffer(s,&tp); }
@ -88,6 +110,9 @@ public:
bool isString() { return IsStringTerm(t); } bool isString() { return IsStringTerm(t); }
}; };
/**
* @brief Variable Term
*/
class YAPVarTerm: private YAPTerm { class YAPVarTerm: private YAPTerm {
public: public:
YAPVarTerm(): YAPTerm() { CACHE_REGS t = MkVarTerm(); } YAPVarTerm(): YAPTerm() { CACHE_REGS t = MkVarTerm(); }
@ -95,6 +120,9 @@ public:
bool unbound() { return IsUnboundVar(VarOfTerm(t)); } bool unbound() { return IsUnboundVar(VarOfTerm(t)); }
}; };
/**
* @brief Compound Term
*/
class YAPApplTerm: private YAPTerm { class YAPApplTerm: private YAPTerm {
public: public:
YAPApplTerm(YAPFunctor f, YAPTerm ts[]); YAPApplTerm(YAPFunctor f, YAPTerm ts[]);
@ -103,6 +131,9 @@ public:
YAPTerm getArg(unsigned int i); YAPTerm getArg(unsigned int i);
}; };
/**
* @brief List Constructor Term
*/
class YAPPairTerm: private YAPTerm { class YAPPairTerm: private YAPTerm {
public: public:
YAPPairTerm(YAPTerm hd, YAPTerm tl); YAPPairTerm(YAPTerm hd, YAPTerm tl);
@ -111,6 +142,31 @@ public:
YAPTerm getTail() { return YAPTerm(TailOfTerm(t)); } YAPTerm getTail() { return YAPTerm(TailOfTerm(t)); }
}; };
/**
* @brief Integer Term
*/
class YAPIntegerTerm: private YAPTerm {
public:
YAPIntegerTerm(intptr_t i) { CACHE_REGS t = MkIntegerTerm( i ); }
intptr_t getInteger(YAPIntegerTerm t) { return IntegerOfTerm(t.t); }
bool isTagged(YAPIntegerTerm i) { return IsIntTerm( t ); }
};
/*
class YAPListTerm: private YAPPairTerm {
public:
YAPListTerm(YAPTerm ts[], size_t n);
YAPListTerm(Term ts[], size_t n);
YAPListTerm( vector<YAPTerm> v );
size_t length() { Term *tailp; return Yap_SkipList(&t, &tailp); }
vector<YAPTerm> toVector();
};
*/
/**
* @brief Atom
*/
class YAPAtom { class YAPAtom {
friend class YAPPredicate; friend class YAPPredicate;
friend class YAPFunctor; friend class YAPFunctor;
@ -125,6 +181,9 @@ public:
char *name(void); char *name(void);
}; };
/**
* @brief String Term
*/
class YAPStringTerm: private YAPTerm { class YAPStringTerm: private YAPTerm {
public: public:
YAPStringTerm(char *s) ; YAPStringTerm(char *s) ;
@ -134,6 +193,9 @@ public:
const char *getString() { return StringOfTerm(t); } const char *getString() { return StringOfTerm(t); }
}; };
/**
* @brief Atom Term
*/
class YAPAtomTerm: private YAPTerm { class YAPAtomTerm: private YAPTerm {
public: public:
YAPAtomTerm(YAPAtom a): YAPTerm() { t = MkAtomTerm(a.a); } YAPAtomTerm(YAPAtom a): YAPTerm() { t = MkAtomTerm(a.a); }
@ -145,6 +207,9 @@ public:
YAPAtom getAtom() { return YAPAtom(AtomOfTerm(t)); } YAPAtom getAtom() { return YAPAtom(AtomOfTerm(t)); }
}; };
/**
* @brief Functor
*/
class YAPFunctor { class YAPFunctor {
friend class YAPApplTerm; friend class YAPApplTerm;
friend class YAPPredicate; friend class YAPPredicate;
@ -164,6 +229,9 @@ public:
} }
}; };
/**
* @brief Term Handle
*/
class YAPTermHandle { class YAPTermHandle {
long int handle; long int handle;
public: public:
@ -187,6 +255,9 @@ public:
} }
}; };
/**
* @brief Predicate
*/
class YAPPredicate { class YAPPredicate {
friend class YAPQuery; friend class YAPQuery;
PredEntry *ap; PredEntry *ap;
@ -259,8 +330,12 @@ public:
int call(YAPTerm ts[]); int call(YAPTerm ts[]);
}; };
/// interface to a YAP Query /**
/// uses an SWI-like status info internally * @brief Term Handle
*
* interface to a YAP Query;
* uses an SWI-like status info internally.
*/
class YAPQuery: private YAPPredicate { class YAPQuery: private YAPPredicate {
int q_open; int q_open;
int q_state; int q_state;
@ -286,13 +361,21 @@ public:
class YAPParams; class YAPParams;
class YAP { /**
* @brief YAP Constructor
*
*/
class YAPEngine {
public: public:
YAP(YAPParams const& params); YAPEngine(YAPParams const& params);
}; };
/**
* @brief Parameters for YAP Constructor
*
*/
class YAPParams { class YAPParams {
friend YAP; friend class YAPEngine;
YAP_init_args init_args; YAP_init_args init_args;
public: public:
YAPParams(); YAPParams();

View File

@ -373,21 +373,21 @@ Yap_unify_constant(register Term a, register Term cons)
return(FALSE); return(FALSE);
if (IsExtensionFunctor(f)) { if (IsExtensionFunctor(f)) {
switch((CELL)f) { switch((CELL)f) {
case (CELL)FunctorDBRef: case db_ref_e:
return(a == cons); return(a == cons);
case (CELL)FunctorLongInt: case long_int_e:
{ {
CELL d0 = RepAppl(a)[1]; CELL d0 = RepAppl(a)[1];
CELL d1 = RepAppl(cons)[1]; CELL d1 = RepAppl(cons)[1];
return d0 == d1; return d0 == d1;
} }
case (CELL)FunctorDouble: case double_e:
{ {
Float d0 = FloatOfTerm(a); Float d0 = FloatOfTerm(a);
Float d1 = FloatOfTerm(cons); Float d1 = FloatOfTerm(cons);
return d0 == d1; return d0 == d1;
} }
case (CELL)FunctorBigInt: case big_int_e:
#ifdef USE_GMP #ifdef USE_GMP
return (Yap_gmp_tcmp_big_big(a, cons) == 0); return (Yap_gmp_tcmp_big_big(a, cons) == 0);
#endif /* USE_GMP */ #endif /* USE_GMP */

View File

@ -59,6 +59,7 @@ YAPSTARTUP=startup.yss
# for c_interface.c # for c_interface.c
# #
CC=@CC@ CC=@CC@
CXX=@CXX@
MPI_CC=@MPI_CC@ MPI_CC=@MPI_CC@
CPPFLAGS=@CPPFLAGS@ -I. -I$(srcdir)/H -I$(srcdir)/include -I$(srcdir)/os -I$(srcdir)/OPTYap -I$(srcdir)/BEAM -I$(srcdir)/CXX CPPFLAGS=@CPPFLAGS@ -I. -I$(srcdir)/H -I$(srcdir)/include -I$(srcdir)/os -I$(srcdir)/OPTYap -I$(srcdir)/BEAM -I$(srcdir)/CXX
EXECUTABLE_CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) $(CPPFLAGS) EXECUTABLE_CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) $(CPPFLAGS)

20
configure vendored
View File

@ -651,7 +651,7 @@ LTLIBOBJS
LIBOBJS LIBOBJS
RAPTOR_CPPFLAGS RAPTOR_CPPFLAGS
RAPTOR_LDFLAGS RAPTOR_LDFLAGS
ENABLE_RAPTOR PKG_RAPTOR
LTX_PL LTX_PL
_ACJNI_JAVAC _ACJNI_JAVAC
JAVADOC JAVADOC
@ -13426,9 +13426,9 @@ fi
if test "$yap_cv_raptor" = no if test "$yap_cv_raptor" = no
then then
ENABLE_RAPTOR="@# " PKG_RAPTOR=""
else else
ENABLE_RAPTOR="" PKG_RAPTOR="packages/raptor"
fi fi
if test "$yap_cv_raptor" != no; then if test "$yap_cv_raptor" != no; then
@ -13536,7 +13536,7 @@ RAPTOR_LDFLAGS="$LIBS"
if test "$raptor_available" = no if test "$raptor_available" = no
then then
ENABLE_RAPTOR="@# " PKG_RAPTOR=""
cat << EOF cat << EOF
################################################################## ##################################################################
# ERROR: Could not find raptor library. Either I don't have the # ERROR: Could not find raptor library. Either I don't have the
@ -13544,7 +13544,7 @@ then
################################################################## ##################################################################
EOF EOF
else else
ENABLE_RAPTOR="" PKG_RAPTOR="packages/raptor"
fi fi
@ -15361,11 +15361,17 @@ fi
if test "$PKG_SWIG" != ""; then if test "$PKG_SWIG" != ""; then
mkdir -p packages/swig/python
mkdir -p packages/swig/R
mkdir -p packages/swig/java
mkdir -p packages/swig/src
mkdir -p packages/swig/jni
ac_config_files="$ac_config_files packages/swig/Makefile packages/swig/setup.py"
ac_config_files="$ac_config_files packages/swig/Makefile packages/swig/jni/Android.mk"
fi fi
@ -16701,7 +16707,7 @@ do
"library/matlab/Makefile") CONFIG_FILES="$CONFIG_FILES library/matlab/Makefile" ;; "library/matlab/Makefile") CONFIG_FILES="$CONFIG_FILES library/matlab/Makefile" ;;
"packages/python/Makefile") CONFIG_FILES="$CONFIG_FILES packages/python/Makefile" ;; "packages/python/Makefile") CONFIG_FILES="$CONFIG_FILES packages/python/Makefile" ;;
"packages/swig/Makefile") CONFIG_FILES="$CONFIG_FILES packages/swig/Makefile" ;; "packages/swig/Makefile") CONFIG_FILES="$CONFIG_FILES packages/swig/Makefile" ;;
"packages/swig/setup.py") CONFIG_FILES="$CONFIG_FILES packages/swig/setup.py" ;; "packages/swig/jni/Android.mk") CONFIG_FILES="$CONFIG_FILES packages/swig/jni/Android.mk" ;;
"packages/cuda/Makefile") CONFIG_FILES="$CONFIG_FILES packages/cuda/Makefile" ;; "packages/cuda/Makefile") CONFIG_FILES="$CONFIG_FILES packages/cuda/Makefile" ;;
"packages/gecode/Makefile") CONFIG_FILES="$CONFIG_FILES packages/gecode/Makefile" ;; "packages/gecode/Makefile") CONFIG_FILES="$CONFIG_FILES packages/gecode/Makefile" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;

View File

@ -110,17 +110,7 @@ REPEAT_BRIEF = YES
# the entity):The $name class, The $name widget, The $name file, is, provides, # the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the. # specifies, contains, represents, a, an and the.
ABBREVIATE_BRIEF = "The $name class" \ ABBREVIATE_BRIEF = "The $name class" "The $name widget" "The $name file" is provides specifies contains represents a an the
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief # doxygen will generate a detailed section even if there is only a brief
@ -230,11 +220,7 @@ TAB_SIZE = 4
# "Side Effects:". You can put \n's in the value part of an alias to insert # "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines. # newlines.
ALIASES ="predicate=@brief" \ ALIASES = "predicate=@brief" "doxygen=\if english" "endenglish=\endif" "dutch=\if dutch" "enddutch=\endif"
"doxygen=\if english" \
"endenglish=\endif" \
"dutch=\if dutch" \
"enddutch=\endif"
# This tag can be used to specify a number of word-keyword mappings (TCL only). # This tag can be used to specify a number of word-keyword mappings (TCL only).
@ -617,7 +603,7 @@ GENERATE_BUGLIST = YES
# the documentation. # the documentation.
# The default value is: YES. # The default value is: YES.
GENERATE_DEPRECATEDLIST= YES GENERATE_DEPRECATEDLIST = YES
# The ENABLED_SECTIONS tag can be used to enable conditional documentation # The ENABLED_SECTIONS tag can be used to enable conditional documentation
# sections, marked by \if <section_label> ... \endif and \cond <section_label> # sections, marked by \if <section_label> ... \endif and \cond <section_label>
@ -760,7 +746,7 @@ WARN_LOGFILE =
# spaces. # spaces.
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = docs/yap.md pl/absf.yap C/cmppreds.c C/eval.c H/eval.h C/arith0.c C/arith1.c C/arith2.c pl/arithpreds.yap INPUT = docs/yap.md pl/absf.yap C/cmppreds.c C/eval.c H/eval.h C/arith0.c C/arith1.c C/arith2.c pl/arithpreds.yap CXX library/dialect/swi/fli
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -780,51 +766,7 @@ INPUT_ENCODING = UTF-8
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# *.qsf, *.as and *.js. # *.qsf, *.as and *.js.
FILE_PATTERNS = *.c \ FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.idl *.ddl *.odl *.h *.h.in *.hh *.hxx *.hpp *.h++ *.cs *.d *.php *.php4 *.php5 *.phtml *.inc *.m *.markdown *.md *.mm *.dox *.py *.f90 *.f *.for *.tcl *.vhd *.vhdl *.ucf *.qsf *.as *.js *.pl *.yap
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.idl \
*.ddl \
*.odl \
*.h \
*.h.in \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.cs \
*.d \
*.php \
*.php4 \
*.php5 \
*.phtml \
*.inc \
*.m \
*.markdown \
*.md \
*.mm \
*.dox \
*.py \
*.f90 \
*.f \
*.for \
*.tcl \
*.vhd \
*.vhdl \
*.ucf \
*.qsf \
*.as \
*.js \
*.pl \
*.yap
# The RECURSIVE tag can be used to specify whether or not subdirectories should # The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well. # be searched for input files as well.
@ -2098,7 +2040,7 @@ PERL_PATH = /usr/bin/perl
# powerful graphs. # powerful graphs.
# The default value is: YES. # The default value is: YES.
CLASS_DIAGRAMS = YES CLASS_DIAGRAMS = NO
# You can define message sequence charts within doxygen comments using the \msc # You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see: # command. Doxygen will then run the mscgen tool (see:
@ -2129,7 +2071,7 @@ HIDE_UNDOC_RELATIONS = YES
# set to NO # set to NO
# The default value is: NO. # The default value is: NO.
HAVE_DOT = NO HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of # to run in parallel. When set to 0 doxygen will base this on the number of
@ -2245,7 +2187,7 @@ INCLUDED_BY_GRAPH = YES
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = NO CALL_GRAPH = YES
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method. # dependency graph for every global function or class method.

View File

@ -8804,8 +8804,7 @@ show the debugger commands.
@item ! Query @item ! Query
execute a query. YAP will not show the result of the query. execute a query. YAP will not show the result of the query.
@item b - break @item b - break
break active execution and launch a break level. This is the same as @code{! break active execution and launch a break level. This is the same as @code{!break}.
break}.
@item + - spy this goal @item + - spy this goal
start spying the active goal. The same as @code{! spy G} where @var{G} start spying the active goal. The same as @code{! spy G} where @var{G}
is the active goal. is the active goal.
@ -8997,10 +8996,22 @@ type_of_verb(rest,passive).
@node C-Interface,YAPLibrary,Efficiency,Top @node C-Interface,YAPLibrary,Efficiency,Top
@chapter C Language interface to YAP @chapter C Language interface to YAP
YAP provides the user with the necessary facilities for writing YAP provides the user with three facilities for writing
predicates in a language other than Prolog. Since, under Unix systems, predicates in a language other than Prolog. Under Unix systems,
most language implementations are link-able to C, we will describe here most language implementations were linkable to @code{C}, and the first interface exported the YAP machinery to the C language. YAP also implements most of the SWI-Prolog foreign language interface.
only the YAP interface to the C language. This gives portability with a number of SWI-Prolog packages. Last, a new C++ based interface is
being designed to work with the swig (@url(www.swig.org}) interface compiler.
@ifplaintext
<ul>
<li> The original YAP C-interface exports the YAP engine.
</li>
<li>The @subpage swi-c-interface emulates Jan Wielemaker's SWI foreign language interface.
</li>
<li>The @subpage yap-cplus-interface is desiged to interface with Object-Oriented systems.
</li>
</ul>
@end ifplaintext
Before describing in full detail how to interface to C code, we will examine Before describing in full detail how to interface to C code, we will examine
a brief example. a brief example.
@ -10110,8 +10121,8 @@ such references.
If the argument of the predicate is a variable, the routine initializes the If the argument of the predicate is a variable, the routine initializes the
structure to be preserved across backtracking with the information structure to be preserved across backtracking with the information
required to provide the next solution, and exits by calling @code{ required to provide the next solution, and exits by calling
continue_n100} to provide that solution. @code{continue_n100} to provide that solution.
If the argument was not a variable, the routine then checks if it was an If the argument was not a variable, the routine then checks if it was an
integer, and if so, if its value is positive and less than 100. In that integer, and if so, if its value is positive and less than 100. In that
@ -10785,8 +10796,9 @@ succeed. On backtracking, the system will retry
generating integers for ever. Immediate semantics were used in C-Prolog. generating integers for ever. Immediate semantics were used in C-Prolog.
With logical update semantics, any additions or deletions of clauses With logical update semantics, any additions or deletions of clauses
for a goal @emph{will not affect previous activations of the for a goal
goal}. In the example, the call to @code{assertz/1} will not see the @emph{will not affect previous activations of the goal}. In the example,
the call to @code{assertz/1} will not see the
update performed by the @code{assertz/1}, and the query will have a update performed by the @code{assertz/1}, and the query will have a
single solution. single solution.
@ -10858,9 +10870,10 @@ database, and not "logical update semantics", as per the standard,
Calling @code{set_prolog_flag(update_semantics,logical)} will switch Calling @code{set_prolog_flag(update_semantics,logical)} will switch
YAP to use logical update semantics. YAP to use logical update semantics.
@item By default, YAP implements the @code{atom_chars/2} @item By default, YAP implements the
(@pxref{Testing Terms}), and @code{number_chars/2}, (@pxref{Testing @code{atom_chars/2}(@pxref{Testing Terms}), and
Terms}), built-ins as per the original Quintus Prolog definition, and @code{number_chars/2}, (@pxref{Testing Terms}),
built-ins as per the original Quintus Prolog definition, and
not as per the ISO definition. not as per the ISO definition.
Calling @code{set_prolog_flag(to_chars_mode,iso)} will switch Calling @code{set_prolog_flag(to_chars_mode,iso)} will switch

View File

@ -217,7 +217,9 @@ typedef struct yap_boot_params {
char *ErrorCause; char *ErrorCause;
} YAP_init_args; } YAP_init_args;
#ifdef YAP_H
Int Yap_InitDefaults( YAP_init_args *init_args, char saved_state[] ); Int Yap_InitDefaults( YAP_init_args *init_args, char saved_state[] );
#endif
/* from thread.h */ /* from thread.h */
typedef struct { typedef struct {

View File

@ -9,6 +9,27 @@
*/ */
/**
*
* @defgroup swi-c-interface SWI-Prolog Foreign Language Interface.
*
*
* @tableofcontents
*
* A reimplementation of Jan Wielemaker's SWI-Prolog C-language interface, it supports
* most of the functionality in the original implementation. It allows for:
*
* - Term Construction, Access, and Unification
* - Manipulation of Atoms, Strings, Lists of Codes and Lists of Atoms
* - Query evaluation
* - Thread and Prolog engine management
* - Data-Base Access
*
* In this interface, all Prolog data known by C is referenced through term references (term_t), hence
* Prolog has all the information necessary to perform its memory management without special precautions
* from the C programmer.
*/
#define PL_KERNEL 1 #define PL_KERNEL 1
//=== includes =============================================================== //=== includes ===============================================================
@ -34,6 +55,10 @@
#include <signal.h> #include <signal.h>
#endif #endif
#if !HAVE_SNPRINTF
#define snprintf(X,Y,Z,A) sprintf(X,Z,A)
#endif
#define PL_KERNEL 1 #define PL_KERNEL 1
#include <pl-shared.h> #include <pl-shared.h>
@ -127,16 +152,25 @@ UserCPredicate(char *a, CPredicate def, unsigned long int arity, Term mod, int f
CurrentModule = cm; CurrentModule = cm;
} }
/* SWI: void PL_agc_hook(void) */ /** @defgroup swi-ATOMS Atom Construction
* @ingroup swi-c-interface
* @{
* */
/* SWI: void PL_agc_hook(void) */
/** @brief Atom garbage collection hook
*
*/
X_API PL_agc_hook_t X_API PL_agc_hook_t
PL_agc_hook(PL_agc_hook_t entry) PL_agc_hook(PL_agc_hook_t entry)
{ {
return (PL_agc_hook_t)YAP_AGCRegisterHook((YAP_agc_hook)entry); return (PL_agc_hook_t)YAP_AGCRegisterHook((YAP_agc_hook)entry);
} }
/* SWI: char* PL_atom_chars(atom_t atom) /** @brief extract the text representation from atom
YAP: char* AtomName(Atom) */ *
*/
X_API char* PL_atom_chars(atom_t a) /* SAM check type */ X_API char* PL_atom_chars(atom_t a) /* SAM check type */
{ {
Atom at = SWIAtomToAtom(a); Atom at = SWIAtomToAtom(a);
@ -145,8 +179,9 @@ X_API char* PL_atom_chars(atom_t a) /* SAM check type */
return RepAtom(at)->StrOfAE; return RepAtom(at)->StrOfAE;
} }
/* SWI: char* PL_atom_chars(atom_t atom) /** @brief extract the text representation from atom, including its length
YAP: char* AtomName(Atom) */ *
*/
X_API char* PL_atom_nchars(atom_t a, size_t *len) /* SAM check type */ X_API char* PL_atom_nchars(atom_t a, size_t *len) /* SAM check type */
{ {
char *s = RepAtom(SWIAtomToAtom(a))->StrOfAE; char *s = RepAtom(SWIAtomToAtom(a))->StrOfAE;
@ -154,15 +189,25 @@ X_API char* PL_atom_nchars(atom_t a, size_t *len) /* SAM check type */
return s; return s;
} }
/* SWI: term_t PL_copy_term_ref(term_t from) /** @}
YAP: NO EQUIVALENT */ *
/* SAM TO DO */ * @defgroup swi-term_references Term References
* @ingroup swi-c-interface
* @{
* */
/** @brief duplicate a term reference
*
*/
X_API term_t PL_copy_term_ref(term_t from) X_API term_t PL_copy_term_ref(term_t from)
{ {
CACHE_REGS CACHE_REGS
return Yap_InitSlot(Yap_GetFromSlot(from PASS_REGS) PASS_REGS); return Yap_InitSlot(Yap_GetFromSlot(from PASS_REGS) PASS_REGS);
} }
/** @brief create a new term reference
*
*/
X_API term_t PL_new_term_ref(void) X_API term_t PL_new_term_ref(void)
{ {
@ -171,6 +216,10 @@ X_API term_t PL_new_term_ref(void)
return to; return to;
} }
/** @brief create several new term references
*
* @par n is the number of references
*/
X_API term_t PL_new_term_refs(int n) X_API term_t PL_new_term_refs(int n)
{ {
CACHE_REGS CACHE_REGS
@ -178,6 +227,9 @@ X_API term_t PL_new_term_refs(int n)
return to; return to;
} }
/** @brief dispose of all term references created since after
*
*/
X_API void PL_reset_term_refs(term_t after) X_API void PL_reset_term_refs(term_t after)
{ {
CACHE_REGS CACHE_REGS
@ -185,10 +237,50 @@ X_API void PL_reset_term_refs(term_t after)
Yap_RecoverSlots(after-new PASS_REGS); Yap_RecoverSlots(after-new PASS_REGS);
} }
/* begin PL_get_* functions =============================*/ /** @}
* @defgroup swi-term_manipulation Term Manipulation
* @ingroup swi-c-interface
* */
/* SWI: int PL_get_arg(int index, term_t t, term_t a) /**
YAP: YAP_Term YAP_ArgOfTerm(int argno, YAP_Term t)*/ * @defgroup swi-get-operations Reading Terms
* @ingroup swi-term_manipulation
* @{
* */
/** @brief *name is assigned the name and *arity the arity if term ts, or the operaton fails.
*
*/
X_API int PL_get_name_arity(term_t ts, atom_t *name, int *arity)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (IsAtomTerm(t)) {
*name = AtomToSWIAtom(AtomOfTerm(t));
*arity = 0;
return 1;
}
if (YAP_IsApplTerm(t)) {
Functor f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) {
return 0;
}
*name = AtomToSWIAtom(NameOfFunctor(f));
*arity = ArityOfFunctor(f);
return 1;
}
if (YAP_IsPairTerm(t)) {
*name = AtomToSWIAtom(AtomDot);
*arity = 2;
return 1;
}
return 0;
}
/** @brief a is assigned the argument index from term ts
*
*/
X_API int PL_get_arg(int index, term_t ts, term_t a) X_API int PL_get_arg(int index, term_t ts, term_t a)
{ {
CACHE_REGS CACHE_REGS
@ -211,8 +303,9 @@ X_API int PL_get_arg(int index, term_t ts, term_t a)
return 1; return 1;
} }
/* SWI: int PL_get_arg(int index, term_t t, term_t a) /** @brief *ap is assigned the name and *ip the arity from term ts
YAP: YAP_Term YAP_ArgOfTerm(int argno, YAP_Term t)*/ *
*/
X_API int PL_get_compound_name_arity(term_t ts, atom_t *ap, int *ip) X_API int PL_get_compound_name_arity(term_t ts, atom_t *ap, int *ip)
{ {
CACHE_REGS CACHE_REGS
@ -237,30 +330,11 @@ X_API int PL_get_compound_name_arity(term_t ts, atom_t *ap, int *ip)
} }
} }
X_API int _PL_get_arg(int index, term_t ts, term_t a)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( !YAP_IsApplTerm(t) ) {
if (YAP_IsPairTerm(t)) {
if (index == 1){
Yap_PutInSlot(a,HeadOfTerm(t) PASS_REGS);
return 1;
} else if (index == 2) {
Yap_PutInSlot(a,TailOfTerm(t) PASS_REGS);
return 1;
}
}
return 0;
}
Yap_PutInSlot(a,ArgOfTerm(index, t) PASS_REGS);
return 1;
}
/** @brief *a is assigned the atom in term ts, or the operation fails
/* SWI: int PL_get_atom(term_t t, YAP_Atom *a) *
YAP: YAP_Atom YAP_AtomOfTerm(Term) */ */
X_API int PL_get_atom(term_t ts, atom_t *a) X_API int PL_get_atom(term_t ts, atom_t *a)
{ {
CACHE_REGS CACHE_REGS
@ -271,148 +345,9 @@ X_API int PL_get_atom(term_t ts, atom_t *a)
return 1; return 1;
} }
/* SWI: int PL_get_atom(term_t t, YAP_Atom *a) /** @brief *i is assigned the int in term ts, or the operation fails
YAP: YAP_Atom YAP_AtomOfTerm(Term) */ *
X_API int PL_get_intptr(term_t ts, intptr_t *a) */
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( !IsIntegerTerm(t) )
return 0;
*a = (intptr_t)(IntegerOfTerm(t));
return 1;
}
/* SWI: int PL_get_atom(term_t t, YAP_Atom *a)
YAP: YAP_Atom YAP_AtomOfTerm(Term) */
X_API int PL_get_uintptr(term_t ts, uintptr_t *a)
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( !IsIntegerTerm(t) )
return 0;
*a = (uintptr_t)(IntegerOfTerm(t));
return 1;
}
/* SWI: int PL_get_atom_chars(term_t t, char **s)
YAP: char* AtomName(Atom) */
X_API int PL_get_atom_chars(term_t ts, char **a) /* SAM check type */
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!IsAtomTerm(t) || IsWideAtom(AtomOfTerm(t)))
return 0;
*a = RepAtom(AtomOfTerm(t))->StrOfAE;
return 1;
}
/* SWI: int PL_get_atom_chars(term_t t, char **s)
YAP: char* AtomName(Atom) */
X_API int PL_get_atom_nchars(term_t ts, size_t *len, char **s) /* SAM check type */
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!IsAtomTerm(t))
return 0;
*s = RepAtom(AtomOfTerm(t))->StrOfAE;
*len = strlen(*s);
return 1;
}
/*
int PL_get_chars(term_t +t, char **s, unsigned flags) Convert the
argument term t to a 0-terminated C-string. flags is a bitwise
disjunction from two groups of constants. The first specifies which
term-types should converted and the second how the argument is
stored. Below is a specification of these constants. BUF_RING
implies, if the data is not static (as from an atom), the data is
copied to the next buffer from a ring of sixteen (16) buffers. This is a
convenient way of converting multiple arguments passed to a foreign
predicate to C-strings. If BUF_MALLOC is used, the data must be
freed using free() when not needed any longer.
CVT_ATOM Convert if term is an atom
CVT_STRING Convert if term is a string
CVT_LIST Convert if term is a list of integers between 1 and 255
CVT_INTEGER Convert if term is an integer (using %d)
CVT_FLOAT Convert if term is a float (using %f)
CVT_NUMBER Convert if term is a integer or float
CVT_ATOMIC Convert if term is atomic
CVT_VARIABLE Convert variable to print-name
CVT_ALL Convert if term is any of the above, except for variables
BUF_DISCARDABLE Data must copied immediately
BUF_RING Data is stored in a ring of buffers
BUF_MALLOC Data is copied to a new buffer returned by malloc(3)
*/
#if !HAVE_SNPRINTF
#define snprintf(X,Y,Z,A) sprintf(X,Z,A)
#endif
/* SWI: int PL_get_functor(term_t t, functor_t *f)
YAP: YAP_Functor YAP_FunctorOfTerm(Term) */
X_API int PL_get_functor(term_t ts, functor_t *f)
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( IsAtomTerm(t)) {
*f = t;
} else {
*f = FunctorToSWIFunctor(FunctorOfTerm(t));
}
return 1;
}
/* SWI: int PL_get_float(term_t t, double *f)
YAP: double YAP_FloatOfTerm(Term) */
X_API int PL_get_float(term_t ts, double *f) /* SAM type check*/
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( IsFloatTerm(t)) {
*f = FloatOfTerm(t);
} else if ( IsIntegerTerm(t)) {
*f = IntegerOfTerm(t);
#if USE_GMP
} else if (IsBigIntTerm(t)) {
*f = Yap_gmp_to_float( t );
#endif
} else {
return 0;
}
return 1;
}
X_API int PL_get_string_chars(term_t t, char **s, size_t *len)
{
CACHE_REGS
Term tt = Yap_GetFromSlot(t PASS_REGS);
if (!IsStringTerm(tt)) {
return 0;
}
*s = (char *)StringOfTerm(tt);
*len = utf8_strlen(*s, strlen(*s));
return TRUE;
}
X_API int PL_get_head(term_t ts, term_t h)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!YAP_IsPairTerm(t) ) {
return 0;
}
Yap_PutInSlot(h,YAP_HeadOfTerm(t) PASS_REGS);
return 1;
}
X_API int PL_get_string(term_t t, char **s, size_t *len)
{
return PL_get_string_chars(t, s, len);
}
/* SWI: int PL_get_integer(term_t t, int *i) /* SWI: int PL_get_integer(term_t t, int *i)
YAP: long int YAP_IntOfTerm(Term) */ YAP: long int YAP_IntOfTerm(Term) */
X_API int PL_get_integer(term_t ts, int *i) X_API int PL_get_integer(term_t ts, int *i)
@ -425,6 +360,27 @@ X_API int PL_get_integer(term_t ts, int *i)
return 1; return 1;
} }
/** @brief *i is assigned the boolean atom `true` or `false` in term ts, or the operation fails
*
*/
X_API int PL_get_long(term_t ts, long *i)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!YAP_IsIntTerm(t) ) {
if (YAP_IsFloatTerm(t)) {
double dbl = YAP_FloatOfTerm(t);
if (dbl - (long)dbl == 0.0) {
*i = (long)dbl;
return 1;
}
}
return 0;
}
*i = YAP_IntOfTerm(t);
return 1;
}
/* SWI: int PL_get_bool(term_t t, int *i) /* SWI: int PL_get_bool(term_t t, int *i)
YAP: long int YAP_AtomOfTerm(Term) */ YAP: long int YAP_AtomOfTerm(Term) */
X_API int PL_get_bool(term_t ts, int *i) X_API int PL_get_bool(term_t ts, int *i)
@ -447,30 +403,11 @@ X_API int PL_get_bool(term_t ts, int *i)
return 0; return 0;
} }
X_API int PL_get_long(term_t ts, long *i) /** @brief *a is assigned the int64 in term ts, or the operation fails
{ *
CACHE_REGS */
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!YAP_IsIntTerm(t) ) {
if (YAP_IsFloatTerm(t)) {
double dbl = YAP_FloatOfTerm(t);
if (dbl - (long)dbl == 0.0) {
*i = (long)dbl;
return 1;
}
}
return 0;
}
*i = YAP_IntOfTerm(t);
return 1;
}
X_API int PL_get_int64(term_t ts, int64_t *i) X_API int PL_get_int64(term_t ts, int64_t *i)
{ {
#if SIZE_OF_INT_P==8
return PL_get_long(ts, (long *)i);
#else
CACHE_REGS CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS); YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!YAP_IsIntTerm(t) ) { if (!YAP_IsIntTerm(t) ) {
@ -480,8 +417,21 @@ X_API int PL_get_int64(term_t ts, int64_t *i)
*i = (int64_t)dbl; *i = (int64_t)dbl;
return 1; return 1;
} }
#if SIZEOF_INT_P==4 && !USE_GMP
{
union {
double d;
int64_t i;
} udbi_;
udbi_.d = YAP_FloatOfTerm(t);
*i = udbi_.i;
return 1;
}
#endif
return 0;
}
#if USE_GMP #if USE_GMP
} else if (YAP_IsBigNumTerm(t)) { else if (YAP_IsBigNumTerm(t)) {
MP_INT g; MP_INT g;
char s[64]; char s[64];
YAP_BigNumOfTerm(t, (void *)&g); YAP_BigNumOfTerm(t, (void *)&g);
@ -495,15 +445,224 @@ X_API int PL_get_int64(term_t ts, int64_t *i)
sscanf(s, "%lld", (long long int *)i); sscanf(s, "%lld", (long long int *)i);
#endif #endif
return 1; return 1;
#endif
} }
#endif
return 0; return 0;
} }
*i = YAP_IntOfTerm(t); *i = YAP_IntOfTerm(t);
return 1; return 1;
#endif
} }
/** @brief *a is assigned the intptr_t in term ts, or the operation fails
*
*/
X_API int PL_get_intptr(term_t ts, intptr_t *a)
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( !IsIntegerTerm(t) )
return 0;
*a = (intptr_t)(IntegerOfTerm(t));
return 1;
}
/** @brief *a is assigned the uintptr_t in term ts, or the operation fails
*
*/
X_API int PL_get_uintptr(term_t ts, uintptr_t *a)
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( !IsIntegerTerm(t) )
return 0;
*a = (uintptr_t)(IntegerOfTerm(t));
return 1;
}
/** @brief a is assigned the argument index from term ts
*
*/
X_API int _PL_get_arg(int index, term_t ts, term_t a)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( !YAP_IsApplTerm(t) ) {
if (YAP_IsPairTerm(t)) {
if (index == 1){
Yap_PutInSlot(a,HeadOfTerm(t) PASS_REGS);
return 1;
} else if (index == 2) {
Yap_PutInSlot(a,TailOfTerm(t) PASS_REGS);
return 1;
}
}
return 0;
}
Yap_PutInSlot(a,ArgOfTerm(index, t) PASS_REGS);
return 1;
}
/** @brief *a is assigned the string representation of the atom in term ts, or the operation fails
*
*/
X_API int PL_get_atom_chars(term_t ts, char **a) /* SAM check type */
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!IsAtomTerm(t) || IsWideAtom(AtomOfTerm(t)))
return 0;
*a = RepAtom(AtomOfTerm(t))->StrOfAE;
return 1;
}
/** @brief *a is assigned the string representation of the atom in term ts, and *len its size, or the operation fails
*
*/
X_API int PL_get_atom_nchars(term_t ts, size_t *len, char **s) /* SAM check type */
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!IsAtomTerm(t))
return 0;
*s = RepAtom(AtomOfTerm(t))->StrOfAE;
*len = strlen(*s);
return 1;
}
/** PL_get_chars converts a term t to a string.
*
* From the SWI manual:
*
* int PL_get_chars(term_t +t, char **s, unsigned flags) Convert the
* argument term t to a 0-terminated C-string. flags is a bitwise
* disjunction from two groups of constants. The first specifies which
* term-types should converted and the second how the argument is
* stored. Below is a specification of these constants. BUF_RING
* implies, if the data is not static (as from an atom), the data is
* copied to the next buffer from a ring of sixteen (16) buffers. This is a
* convenient way of converting multiple arguments passed to a foreign
* predicate to C-strings. If BUF_MALLOC is used, the data must be
* freed using free() when not needed any longer.
- CVT_ATOM Convert if term is an atom
- CVT_STRING Convert if term is a string
- CVT_LIST Convert if term is a list of integers between 1 and 255
- CVT_INTEGER Convert if term is an integer (using %d)
- CVT_FLOAT Convert if term is a float (using %f)
- CVT_NUMBER Convert if term is a integer or float
- CVT_ATOMIC Convert if term is atomic
- CVT_VARIABLE Convert variable to print-name
- CVT_ALL Convert if term is any of the above, except for variables
- BUF_DISCARDABLE Data must copied immediately
- BUF_RING Data is stored in a ring of buffers
- BUF_MALLOC Data is copied to a new buffer returned by malloc(3)
*/
/** @brief *f is assigned the functor of term ts, or the operation fails
*
*/
X_API int PL_get_functor(term_t ts, functor_t *f)
{
CACHE_REGS
Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( IsAtomTerm(t)) {
*f = t;
} else {
*f = FunctorToSWIFunctor(FunctorOfTerm(t));
}
return 1;
}
/** @brief *f is assigned the floating point number of term ts, or the operation fails
*
*/
X_API int PL_get_float(term_t ts, double *f) /* SAM type check*/
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if ( IsFloatTerm(t)) {
*f = FloatOfTerm(t);
} else if ( IsIntegerTerm(t)) {
*f = IntegerOfTerm(t);
#if USE_GMP
} else if (IsBigIntTerm(t)) {
*f = Yap_gmp_to_float( t );
#endif
} else {
return 0;
}
return 1;
}
/** @brief *s is assigned the string representation of the string in term ts, and *len its size, or the operation fails
*
*/
X_API int PL_get_string_chars(term_t t, char **s, size_t *len)
{
CACHE_REGS
Term tt = Yap_GetFromSlot(t PASS_REGS);
if (!IsStringTerm(tt)) {
return 0;
}
*s = (char *)StringOfTerm(tt);
*len = utf8_strlen(*s, strlen(*s));
return TRUE;
}
/** @brief h is assigned the head of the pair term ts, and tl its tail, or the operation fails
*
*/
X_API int PL_get_list(term_t ts, term_t h, term_t tl)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (IsVarTerm(t) || !IsPairTerm(t) ) {
return 0;
}
Yap_PutInSlot(h,HeadOfTerm(t) PASS_REGS);
Yap_PutInSlot(tl,TailOfTerm(t) PASS_REGS);
return 1;
}
/** @brief h is assigned the head of the pair term ts, or the operation fails
*
*/
X_API int PL_get_head(term_t ts, term_t h)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (!YAP_IsPairTerm(t) ) {
return 0;
}
Yap_PutInSlot(h,YAP_HeadOfTerm(t) PASS_REGS);
return 1;
}
/** @brief *s is assigned the string representation of the term ts, and *len its size, or the operation fails
*
*/
X_API int PL_get_string(term_t t, char **s, size_t *len)
{
return PL_get_string_chars(t, s, len);
}
/**
* @}
* */
/**
* @defgroup swi-unify-operations Unifying Terms
* @ingroup swi-term_manipulation
* @{
* */
/** @brief t unifies with the true/false value in a.
*
*/
X_API int PL_unify_bool(term_t t, int a) X_API int PL_unify_bool(term_t t, int a)
{ {
CACHE_REGS CACHE_REGS
@ -550,18 +709,6 @@ X_API int PL_unify_mpq(term_t t, mpq_t mpq)
#endif #endif
X_API int PL_get_list(term_t ts, term_t h, term_t tl)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (IsVarTerm(t) || !IsPairTerm(t) ) {
return 0;
}
Yap_PutInSlot(h,HeadOfTerm(t) PASS_REGS);
Yap_PutInSlot(tl,TailOfTerm(t) PASS_REGS);
return 1;
}
/* SWI: int PL_get_module(term_t t, module_t *m) */ /* SWI: int PL_get_module(term_t t, module_t *m) */
X_API int PL_get_module(term_t ts, module_t *m) X_API int PL_get_module(term_t ts, module_t *m)
{ {
@ -585,34 +732,6 @@ X_API module_t PL_new_module(atom_t swiat)
return Yap_GetModuleEntry(t); return Yap_GetModuleEntry(t);
} }
/* SWI: int PL_get_atom(term_t t, YAP_Atom *a)
YAP: YAP_Atom YAP_AtomOfTerm(Term) */
X_API int PL_get_name_arity(term_t ts, atom_t *name, int *arity)
{
CACHE_REGS
YAP_Term t = Yap_GetFromSlot(ts PASS_REGS);
if (IsAtomTerm(t)) {
*name = AtomToSWIAtom(AtomOfTerm(t));
*arity = 0;
return 1;
}
if (YAP_IsApplTerm(t)) {
Functor f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) {
return 0;
}
*name = AtomToSWIAtom(NameOfFunctor(f));
*arity = ArityOfFunctor(f);
return 1;
}
if (YAP_IsPairTerm(t)) {
*name = AtomToSWIAtom(AtomDot);
*arity = 2;
return 1;
}
return 0;
}
/* SWI: int PL_get_atom(term_t t, YAP_Atom *a) /* SWI: int PL_get_atom(term_t t, YAP_Atom *a)
YAP: YAP_Atom YAP_AtomOfTerm(Term) */ YAP: YAP_Atom YAP_AtomOfTerm(Term) */
X_API int PL_get_nil(term_t ts) X_API int PL_get_nil(term_t ts)
@ -913,7 +1032,18 @@ X_API int PL_put_int64(term_t t, int64_t n)
Yap_PutInSlot(t,YAP_MkBigNumTerm((void *)&rop) PASS_REGS); Yap_PutInSlot(t,YAP_MkBigNumTerm((void *)&rop) PASS_REGS);
return TRUE; return TRUE;
#else #else
return FALSE; // use a double, but will mess up writing.
Int x = n;
if (x == n)
return PL_put_integer(t, x);
else {
union {
int64_t i;
double d;
} udi_;
udi_.i = n;
return PL_put_float(t, udi_.d);
}
#endif #endif
} }
@ -1134,8 +1264,15 @@ X_API int PL_unify_int64(term_t t, int64_t n)
#else #else
if ((long)n == n) if ((long)n == n)
return PL_unify_integer(t, n); return PL_unify_integer(t, n);
fprintf(stderr,"Error in PL_unify_int64: please install GMP\n"); // use a double, but will mess up writing.
return FALSE; else {
union {
int64_t i;
double d;
} udi_;
udi_.i = n;
return PL_unify_float(t, udi_.d);
}
#endif #endif
} }
@ -1492,8 +1629,21 @@ int PL_unify_termv(term_t l, va_list ap)
*pt++ = YAP_MkBigNumTerm((void *)&rop); *pt++ = YAP_MkBigNumTerm((void *)&rop);
} }
#else #else
fprintf(stderr, "PL_unify_term: PL_int64 not supported\n"); {
exit(1); int64_t i = (Int)va_arg(ap, int64_t);
intptr_t x = i;
if (x == i)
*pt++ = MkIntegerTerm( x );
else {
// use a double, but will mess up writing.
union {
int64_t i;
double d;
} udi_;
udi_.i = i;
*pt++ = MkFloatTerm(udi_.d);
}
}
#endif #endif
break; break;
case PL_FUNCTOR: case PL_FUNCTOR:
@ -2406,13 +2556,15 @@ X_API int PL_is_inf(term_t st)
{ {
CACHE_REGS CACHE_REGS
Term t = Deref(Yap_GetFromSlot(st PASS_REGS)); Term t = Deref(Yap_GetFromSlot(st PASS_REGS));
Float fl;
if (IsVarTerm(t)) return FALSE; if (IsVarTerm(t)) return FALSE;
if (!IsFloatTerm(t)) return FALSE; if (!IsFloatTerm(t)) return FALSE;
fl = FloatOfTerm(t);
#if HAVE_ISINF #if HAVE_ISINF
Float fl;
fl = FloatOfTerm(t);
return isinf(fl); return isinf(fl);
#elif HAVE_FPCLASS #elif HAVE_FPCLASS
Float fl;
fl = FloatOfTerm(t);
return (fpclass(fl) == FP_NINF || fpclass(fl) == FP_PINF); return (fpclass(fl) == FP_NINF || fpclass(fl) == FP_PINF);
#else #else
return FALSE; return FALSE;

View File

@ -717,12 +717,21 @@ represented.
static int static int
wctobuffer(wchar_t c, mbstate_t *mbs, Buffer buf) wctobuffer(wchar_t c, mbstate_t *mbs, Buffer buf)
{ char b[PL_MB_LEN_MAX]; {
#if __ANDROID__
// wcrtomb & friends seems broken in android, just copy
if ( c < 256 ) {
addBuffer(buf, c, char);
return TRUE;
} else {
return FALSE;
}
#else
char b[PL_MB_LEN_MAX];
size_t n; size_t n;
if ( (n=wcrtomb(b, c, mbs)) != (size_t)-1 ) if ( (n=wcrtomb(b, c, mbs)) != (size_t)-1 )
{ size_t i; { size_t i;
for(i=0; i<n; i++) for(i=0; i<n; i++)
addBuffer(buf, b[i], char); addBuffer(buf, b[i], char);
@ -730,6 +739,7 @@ wctobuffer(wchar_t c, mbstate_t *mbs, Buffer buf)
} }
return FALSE; /* cannot represent */ return FALSE; /* cannot represent */
#endif
} }

View File

@ -28,7 +28,6 @@ if test ! "$yap_cv_cplint" = "no"
SHLIB_SUFFIX="so" SHLIB_SUFFIX="so"
fi fi
PKG_CPLINT="packages/cplint packages/cplint/splipcase packages/cplint/approx/simplecuddLPADs" PKG_CPLINT="packages/cplint packages/cplint/splipcase packages/cplint/approx/simplecuddLPADs"
AC_SUBST(PKG_CPLINT)
AC_SUBST(CPLINT_LIBS) AC_SUBST(CPLINT_LIBS)
AC_SUBST(CPLINT_CFLAGS) AC_SUBST(CPLINT_CFLAGS)
AC_SUBST(CPLINT_LDFLAGS) AC_SUBST(CPLINT_LDFLAGS)
@ -38,6 +37,8 @@ else
PKG_CPLINT="" PKG_CPLINT=""
fi fi
AC_SUBST(PKG_CPLINT)
mkdir -p packages/cplint mkdir -p packages/cplint
mkdir -p packages/cplint/approx mkdir -p packages/cplint/approx
mkdir -p packages/cplint/approx/simplecuddLPADs mkdir -p packages/cplint/approx/simplecuddLPADs

View File

@ -62,7 +62,7 @@ memory.o: $(srcdir)/memory.cu $(srcdir)/pred.h
@DO_SECOND_LD@cuda.@SO@: $(OBJS) @DO_SECOND_LD@cuda.@SO@: $(OBJS)
@DO_SECOND_LD@ @CUDA_SHLIB_LD@ $(CUDA_LDFLAGS) -o cuda.@SO@ $(OBJS) @DO_SECOND_LD@ @CUDA_SHLIB_LD@ $(CUDA_LDFLAGS) -o cuda.@SO@ $(OBJS)
install: all install-exampleS install: all install-examples
mkdir -p $(DESTDIR)$(SHAREDIR) mkdir -p $(DESTDIR)$(SHAREDIR)
for h in $(BDD_PROLOG); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR); done for h in $(BDD_PROLOG); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR); done
$(INSTALL_PROGRAM) $(SOBJS) $(DESTDIR)$(YAPLIBDIR) $(INSTALL_PROGRAM) $(SOBJS) $(DESTDIR)$(YAPLIBDIR)

View File

@ -736,10 +736,14 @@ init_myddas(void)
} }
#endif #endif
#if defined MYDDAS_MYSQL || defined MYDDAS_ODBC #if defined MYDDAS_MYSQL || defined MYDDAS_ODBC
#define stringify(X) _stringify(X)
#define _stringify(X) #X
Yap_REGS.MYDDAS_GLOBAL_POINTER = NULL; Yap_REGS.MYDDAS_GLOBAL_POINTER = NULL;
Yap_PutValue(AtomMyddasVersionName, Yap_PutValue(AtomMyddasVersionName,
MkAtomTerm(Yap_LookupAtom(MYDDAS_VERSION))); MkAtomTerm(Yap_LookupAtom(stringify(MYDDAS_VERSION))));
Yap_HaltRegisterHook((HaltHookFunc)Yap_MYDDAS_delete_all_myddas_structs,NULL); Yap_HaltRegisterHook((HaltHookFunc)Yap_MYDDAS_delete_all_myddas_structs,NULL);
#undef stringify
#undef _stringify
Yap_MYDDAS_delete_all_myddas_structs(); Yap_MYDDAS_delete_all_myddas_structs();
#endif #endif
} }

@ -1 +1 @@
Subproject commit 0f77a1e1b90b36bddb1844712380f4f3858123b7 Subproject commit 2436b3e2d13d3ca20e8b3ad4db0825b413dc0ed2

View File

@ -31,11 +31,11 @@ python/yap_wrap.o: python/yap_wrap.c
java: java/libyap.@SO@ java/yap.java java: java/libyap.@SO@ java/yap.java
cd java ; $(JAVAC) *.java; $(JAR) cvf yap.jar *.class cd java ; $(JAVAC) *.java; $(JAR) cvf yap.jar *.class
java/libyap.@SO@: java/yap_wrap.o java/libyap.@SO@: jni/yap_wrap.o
$(CXX) -shared $(LDSOFLAGS) -L ../.. -lYap -o java/libyap.@SO@ ../../yapi.o java/yap_wrap.o $(LIBS) @JPLLDFLAGS@ -L ../.. -lYap -lpthread $(CXX) -shared $(LDSOFLAGS) -L ../.. -lYap -o java/libyap.@SO@ ../../yapi.o java/yap_wrap.o $(LIBS) @JPLLDFLAGS@ -L ../.. -lYap -lpthread
java/yap_wrap.c: $(srcdir)/yap.i jni/yap_wrap.c: $(srcdir)/yap.i
$(SWIG) -c++ -java -outdir java -o $@ $(DEFS) $(CPPFLAGS) -Wall $< $(SWIG) -c++ -java -package pt.up.fc.dcc.yap -outdir src/pt/up/fc/dcc/yap -o $@ $(DEFS) $(CPPFLAGS) -Wall $<
java/yap_wrap.o: java/yap_wrap.c java/yap_wrap.o: java/yap_wrap.c
$(CXX) -c $(CXXFLAGS) @JPLCFLAGS@ $< -o $@ $(CXX) -c $(CXXFLAGS) @JPLCFLAGS@ $< -o $@

View File

@ -24,12 +24,13 @@ if test "$PKG_SWIG" != ""; then
mkdir -p packages/swig/python mkdir -p packages/swig/python
mkdir -p packages/swig/R mkdir -p packages/swig/R
mkdir -p packages/swig/java mkdir -p packages/swig/java
mkdir -p packages/swig/android mkdir -p packages/swig/src
mkdir -p packages/swig/jni
AC_SUBST(SWIG) AC_SUBST(SWIG)
AC_SUBST(SWIG_TARGET) AC_SUBST(SWIG_TARGET)
AC_SUBST(PKG_SWIG) AC_SUBST(PKG_SWIG)
AC_CONFIG_FILES([ packages/swig/Makefile ]) AC_CONFIG_FILES([ packages/swig/Makefile packages/swig/jni/Android.mk ])
fi fi