diff --git a/docs/md/builtins.md b/docs/md/builtins.md new file mode 100644 index 000000000..5625441b5 --- /dev/null +++ b/docs/md/builtins.md @@ -0,0 +1,31 @@ +YAP Built-ins {#builtins} +================= + +This chapter describes the core predicates that control the execution of +Prolog programs, provide fundamental functionality such as termm manipulation or arithmetic, and support interaction with external +resources, Many of the predicates described here have been standardised by the ISO. The standartised subset of Proloh also known as ISO-Prolog. + +In the description of the arguments of functors the following notation +will be used: + ++ a preceding plus sign will denote an argument as an "input +argument" - it cannot be a free variable at the time of the call; ++ a preceding minus sign will denote an "output argument"; ++ an argument with no preceding symbol can be used in both ways. ++ @ref YAPControl + ++ @ref Arithmetic + ++ @ref YAPChars + ++ @ref YAP_Terms + ++ @ref InputOutput + ++ @ref AbsoluteFileName + ++ @ref YAPOS + ++ @ref Internal_Database + ++ @ref Sets diff --git a/docs/md/download.md b/docs/md/download.md new file mode 100644 index 000000000..f87e232ca --- /dev/null +++ b/docs/md/download.md @@ -0,0 +1,18 @@ + +Downloading YAP {#download} +============== + +The latest development version of Yap-6 is yap-6.3.4 and can be +obtained from the repositories + + + +and + + + +YAP-6.3.4 does not use modules. Please just use `git clone` to obtain the distribution. + +Most of these repositories are basically copies of the original +repositories at the SWI-Prolog site. YAP-6 will work either with or +without these packages. diff --git a/docs/md/extensions.md b/docs/md/extensions.md new file mode 100644 index 000000000..844c2e302 --- /dev/null +++ b/docs/md/extensions.md @@ -0,0 +1,21 @@ +Extensions to core Prolog. {#extensions} +========================= + +YAP includes a number of extensions over the original Prolog +language. Next, we discuss how to use the most important ones. + + + @ref Rational_Trees + + + @ref AttributedVariables + + + @ref DepthLimited + + + @ref Tabling + + + @ref Threads + + + @ref Profiling + + + @ref YAPArrays + + + @ref Parallelism diff --git a/docs/md/fli.md b/docs/md/fli.md new file mode 100644 index 000000000..f45c1b53d --- /dev/null +++ b/docs/md/fli.md @@ -0,0 +1,1542 @@ +The Foreign Code Interface {#fli_c_cxx} +=========================== + +YAP provides the user with three facilities for writing +predicates in a language other than Prolog. Under Unix systems, +most language implementations were linkable to `C`, and the first interface exported the YAP machinery to the C language. YAP also implements most of the SWI-Prolog foreign language interface. +This gives portability with a number of SWI-Prolog packages and avoids garnage collection by using @ref slotInterface. Last, a new C++ based interface is +being designed to work with the swig (www.swig.orgv) interface compiler. + ++ The @subpage c-interface + ++ The @ref swi-c-interface emulates Jan Wielemaker's SWI foreign language interface. + ++ The @ref yap-cplus-interface is desiged to interface with the SWIG package by using Object-Oriented concepts + ++ The @ref LoadInterface handles the setup of foreign files + + + +@page c-interface YAP original C-interface + +Before describing in full detail how to interface to C code, we will examine +a brief example. + +Assume the user requires a predicate `my_process_id(Id)` which succeeds +when _Id_ unifies with the number of the process under which YAP is running. + +In this case we will create a `my_process.c` file containing the +C-code described below. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} +#include "YAP/YapInterface.h" + +static int my_process_id(void) +{ + YAP_Term pid = YAP_MkIntTerm(getpid()); + YAP_Term out = YAP_ARG1; + return(YAP_Unify(out,pid)); +} + +void init_my_predicates() +{ + YAP_UserCPredicate("my_process_id",my_process_id,1); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The commands to compile the above file depend on the operating +system. + +@{ + +*/ + +/** + * + * Using the compiler: + +Under Linux you should use: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gcc -c -shared -fPIC my_process.c + ld -shared -o my_process.so my_process.o +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Under WIN32 in a MINGW/CYGWIN environment, using the standard +installation path you should use: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gcc -mno-cygwin -I "c:/Yap/include" -c my_process.c + gcc -mno-cygwin "c:/Yap/bin/yap.dll" --shared -o my_process.dll +my_process.o +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Under WIN32 in a pure CYGWIN environment, using the standard +installation path, you should use: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gcc -I/usr/local -c my_process.c + gcc -shared -o my_process.dll my_process.o /usr/local/bin/yap.dll +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +And could be loaded, under YAP, by executing the following Prolog goal + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + load_foreign_files(['my_process'],[],init_my_predicates). +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note that since YAP4.3.3 you should not give the suffix for object +files. YAP will deduce the correct suffix from the operating system it +is running under. + +After loading that file the following Prolog goal + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + my_process_id(N) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +would unify N with the number of the process under which YAP is running. + +Having presented a full example, we will now examine in more detail the +contents of the C source code file presented above. + +The include statement is used to make available to the C source code the +macros for the handling of Prolog terms and also some YAP public +definitions. + +The function `my_process_id` is the implementation, in C, of the +desired predicate. Note that it returns an integer denoting the success +of failure of the goal and also that it has no arguments even though the +predicate being defined has one. +In fact the arguments of a Prolog predicate written in C are accessed +through macros, defined in the include file, with names _YAP_ARG1_, + _YAP_ARG2_, ..., _YAP_ARG16_ or with _YAP_A_( _N_) + + +where _N_ is the argument number (starting with 1). In the present +case the function uses just one local variable of type `YAP_Term`, the +type used for holding YAP terms, where the integer returned by the +standard unix function `getpid()` is stored as an integer term (the +conversion is done by `YAP_MkIntTerm(Int))`. Then it calls the +pre-defined routine `YAP_Unify(YAP_Term, YAP_Term)` which in turn returns an +integer denoting success or failure of the unification. + +The role of the procedure `init_my_predicates` is to make known to +YAP, by calling YAP_UserCPredicate(), the predicates being +defined in the file. This is in fact why, in the example above, +init_my_predicates() was passed as the third argument to +load_foreign_files/3. + +The rest of this appendix describes exhaustively how to interface C to YAP. + +@section Manipulating_Terms Terms + +This section provides information about the primitives available to the C +programmer for manipulating Prolog terms. + +Several C typedefs are included in the header file `yap/YAPInterface.h` to +describe, in a portable way, the C representation of Prolog terms. +The user should write is programs using this macros to ensure portability of +code across different versions of YAP. + +The more important typedef is _YAP_Term_ which is used to denote the +type of a Prolog term. + +Terms, from a point of view of the C-programmer, can be classified as +follows + + + uninstantiated variables + + instantiated variables + + integers + + floating-point numbers + + database references + + atoms + + pairs (lists) + + compound terms + +The primitive + +YAP_Bool YAP_IsVarTerm(YAP_Term _t_) + +returns true iff its argument is an uninstantiated variable. Conversely the +primitive + + + +The user can create a new uninstantiated variable using the primitive + + + +The following primitives can be used to discriminate among the different types +of non-variable terms: + + + +The next primitive gives the type of a Prolog term: + + +The set of possible values is an enumerated type, with the following values: + + + +Next, we mention the primitives that allow one to destruct and construct +terms. All the above primitives ensure that their result is +a dereferenced, i.e. that it is not a pointer to another term. + +The following primitives are provided for creating an integer term from an +integer and to access the value of an integer term. + + +where `YAP_Int` is a typedef for the C integer type appropriate for +the machine or compiler in question (normally a long integer). The size +of the allowed integers is implementation dependent but is always +greater or equal to 24 bits: usually 32 bits on 32 bit machines, and 64 +on 64 bit machines. + +The two following primitives play a similar role for floating-point terms + + +where `flt` is a typedef for the appropriate C floating point type, +nowadays a `double` + +The following primitives are provided for verifying whether a term is +a big int, creating a term from a big integer and to access the value +of a big int from a term. + + +YAP must support bignum for the configuration you are using (check the +YAP configuration and setup). For now, YAP only supports the GNU GMP +library, and `void \*` will be a cast for `mpz_t`. Notice +that [YAP_BigNumOfTerm](@ref YAP_BigNumOfTerm) requires the number to be already +initialized. As an example, we show how to print a bignum: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +static int +p_print_bignum(void) +{ + mpz_t mz; + if (!YAP_IsBigNumTerm(YAP_ARG1)) + return FALSE; + + mpz_init(mz); + YAP_BigNumOfTerm(YAP_ARG1, mz); + gmp_printf("Shows up as %Zd\n", mz); + mpz_clear(mz); + return TRUE; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently, no primitives are supplied to users for manipulating data base +references. + +A special typedef `YAP_Atom` is provided to describe Prolog +\a atoms (symbolic constants). The two following primitives can be used +to manipulate atom terms + + + +The following primitives are available for associating atoms with their +names + + +The function [YAP_LookupAtom](@ref YAP_LookupAtom) looks up an atom in the +standard hash +table. The function [YAP_FullLookupAtom](@ref YAP_FullLookupAtom) will also +search if the +atom had been "hidden": this is useful for system maintenance from C +code. The functor [YAP_AtomName](@ref YAP_AtomName) returns a pointer to the +string +for the atom. + +The following primitives handle constructing atoms from strings with +wide characters, and vice-versa: + + + +The following primitive tells whether an atom needs wide atoms in its +representation: + + + +The following primitive can be used to obtain the size of an atom in a +representation-independent way: + + + +The next routines give users some control over the atom +garbage collector. They allow the user to guarantee that an atom is not +to be garbage collected (this is important if the atom is hold +externally to the Prolog engine, allow it to be collected, and call a +hook on garbage collection: + + + +A \a pair is a Prolog term which consists of a tuple of two Prolog +terms designated as the \a head and the \a tail of the term. Pairs are +most often used to build lists. The following primitives can be +used to manipulate pairs: + + +One can construct a new pair from two terms, or one can just build a +pair whose head and tail are new unbound variables. Finally, one can +fetch the head or the tail. + +The last function supports the common operation of constructing a list from an +array of terms of size _sz_ in a simple sweep. + +Notice that the list constructors can call the garbage collector if +there is not enough space in the global stack. + +A \a compound term consists of a \a functor and a sequence of terms with +length equal to the \a arity of the functor. A functor, described in C by +the typedef `Functor`, consists of an atom and of an integer. +The following primitives were designed to manipulate compound terms and +functors + + +The [YAP_MkApplTerm() function constructs a new term, with functor + _f_ (of arity _n_), and using an array _args_ of _n_ +terms with _n_ equal to the arity of the +functor. YAP_MkNewApplTerm() builds up a compound term whose +arguments are unbound variables. [YAP_ArgOfTerm](@ref YAP_ArgOfTerm) gives an +argument +to a compound term. `argno` should be greater or equal to 1 and +less or equal to the arity of the functor. [YAP_ArgsOfTerm](@ref +YAP_ArgsOfTerm) +returns a pointer to an array of arguments. + +Notice that the compound term constructors can call the garbage +collector if there is not enough space in the global stack. + +YAP allows one to manipulate the functors of compound term. The function +[YAP_FunctorOfTerm](@ref YAP_FunctorOfTerm) allows one to obtain a variable of +type +`YAP_Functor` with the functor to a term. The following functions +then allow one to construct functors, and to obtain their name and arity. + + + +Note that the functor is essentially a pair formed by an atom, and +arity. + +Constructing terms in the stack may lead to overflow. The routine + + +verifies whether you have at least _min_ cells free in the stack, +and it returns true if it has to ensure enough memory by calling the +garbage collector and or stack shifter. The routine returns false if no +memory is needed, and a negative number if it cannot provide enough +memory. + +You can set _min_ to zero if you do not know how much room you need +but you do know you do not need a big chunk at a single go. Usually, the routine +would usually be called together with a long-jump to restart the +code. Slots can also be used if there is small state. + +@section Unifying_Terms Unification + +YAP provides a single routine to attempt the unification of two Prolog +terms. The routine may succeed or fail: + + +The routine attempts to unify the terms _a_ and + _b_ returning `TRUE` if the unification succeeds and `FALSE` +otherwise. + +@section Manipulating_Strings Strings + +The YAP C-interface now includes an utility routine to copy a string +represented as a list of a character codes to a previously allocated buffer + + +The routine copies the list of character codes _String_ to a +previously allocated buffer _buf_. The string including a +terminating null character must fit in _bufsize_ characters, +otherwise the routine will simply fail. The _StringToBuffer_ routine +fails and generates an exception if _String_ is not a valid string. + +The C-interface also includes utility routines to do the reverse, that +is, to copy a from a buffer to a list of character codes, to a +difference list, or to a list of +character atoms. The routines work either on strings of characters or +strings of wide characters: + + +Users are advised to use the _N_ version of the routines. Otherwise, +the user-provided string must include a terminating null character. + +The C-interface function calls the parser on a sequence of characters +stored at _buf_ and returns the resulting term. + + +The user-provided string must include a terminating null +character. Syntax errors will cause returning `FALSE` and binding + _error_ to a Prolog term. + +These C-interface functions are useful when converting chunks of data to Prolog: + + +Notice that they are unsafe, and may call the garbage collector. They +return 0 on error. + +These C-interface functions are useful when converting Prolog lists to arrays: + + +They return the number of integers scanned, up to a maximum of sz, +and -1 on error. + +@section Memory_Allocation Memory Allocation + +The next routine can be used to ask space from the Prolog data-base: + + +The routine returns a pointer to a buffer allocated from the code area, +or `NULL` if sufficient space was not available. + +The space allocated with [YAP_AllocSpaceFromYAP](@ref YAP_AllocSpaceFromYAP) can +be released +back to YAP by using: + + +The routine releases a buffer allocated from the code area. The system +may crash if `buf` is not a valid pointer to a buffer in the code +area. + +@section Controlling_Streams Controlling YAP Streams from `C` + +The C-Interface also provides the C-application with a measure of +control over the YAP Input/Output system. The first routine allows one +to find a file number given a current stream: + + +This function gives the file descriptor for a currently available +stream. Note that null streams and in memory streams do not have +corresponding open streams, so the routine will return a +negative. Moreover, YAP will not be aware of any direct operations on +this stream, so information on, say, current stream position, may become +stale. + +A second routine that is sometimes useful is: + + +This routine closes the YAP Input/Output system except for the first +three streams, that are always associated with the three standard Unix +streams. It is most useful if you are doing `fork()`. + +Last, one may sometimes need to flush all streams: + + +It is also useful before you do a `fork()`, or otherwise you may +have trouble with unflushed output. + +The next routine allows a currently open file to become a stream. The +routine receives as arguments a file descriptor, the true file name as a +string, an atom with the user name, and a set of flags: + + +The available flags are `YAP_INPUT_STREAM`, +`YAP_OUTPUT_STREAM`, `YAP_APPEND_STREAM`, +`YAP_PIPE_STREAM`, `YAP_TTY_STREAM`, `YAP_POPEN_STREAM`, +`YAP_BINARY_STREAM`, and `YAP_SEEKABLE_STREAM`. By default, the +stream is supposed to be at position 0. The argument _name_ gives +the name by which YAP should know the new stream. + +@section Utility_Functions Utility Functions in `C` + +The C-Interface provides the C-application with a a number of utility +functions that are useful. + +The first provides a way to insert a term into the data-base + + +This function returns a pointer to a copy of the term in the database +(or to NULL if the operation fails. + +The next functions provides a way to recover the term from the data-base: + + +Notice that the semantics are the same as for recorded/3: this +function creates a new copy of the term in the stack, with fresh +variables. The function returns 0L if it cannot create a new term. + +Last, the next function allows one to recover space: + + +Notice that any accesses using _handle_ after this operation may +lead to a crash. + +The following functions are often required to compare terms. + +Succeed if two terms are actually the same term, as in +==/2: + + + +The next function succeeds if two terms are variant terms, and returns +0 otherwise, as +=@=/2: + + + +The next functions deal with numbering variables in terms: + + + +The next one returns the length of a well-formed list _t_, or +`-1` otherwise: + + + +Last, this function succeeds if two terms are unifiable: +=@=/2: + + + +The second function computes a hash function for a term, as in +`term_hash/4`. + + +The first three arguments follow `term_has/4`. The last argument +indicates what to do if we find a variable: if `0` fail, otherwise +ignore the variable. + +@section Calling_YAP_From_C From `C` back to Prolog + +There are several ways to call Prolog code from C-code. By default, the +`YAP_RunGoal()` should be used for this task. It assumes the engine +has been initialized before: + + +Execute query _Goal_ and return 1 if the query succeeds, and 0 +otherwise. The predicate returns 0 if failure, otherwise it will return +an _YAP_Term_. + +Quite often, one wants to run a query once. In this case you should use + _Goal_: + + +The `YAP_RunGoal()` function makes sure to recover stack space at +the end of execution. + +Prolog terms are pointers: a problem users often find is that the term + _Goal_ may actually be moved around during the execution of +`YAP_RunGoal()`, due to garbage collection or stack shifting. If +this is possible, _Goal_ will become invalid after executing +`YAP_RunGoal()`. In this case, it is a good idea to save _Goal_ +slots, as shown next: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + long sl = YAP_InitSlot(scoreTerm); + + out = YAP_RunGoal(t); + t = YAP_GetFromSlot(sl); + YAP_RecoverSlots(1); + if (out == 0) return FALSE; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@copydoc real + +The following functions complement _YAP_RunGoal_: + + + +The YAP_RunGoal() interface is designed to be very robust, but may +not be the most efficient when repeated calls to the same goal are made +and when there is no interest in processing exception. The + YAP_EnterGoal() interface should have lower-overhead: + + +Next, follows an example of how to use [YAP_EnterGoal](@ref YAP_EnterGoal): + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +void +runall(YAP_Term g) +{ + YAP_dogoalinfo goalInfo; + YAP_Term *goalArgs = YAP_ArraysOfTerm(g); + YAP_Functor *goalFunctor = YAP_FunctorOfTerm(g); + YAP_PredEntryPtr goalPred = YAP_FunctorToPred(goalFunctor); + + result = YAP_EnterGoal( goalPred, goalArgs, &goalInfo ); + while (result) + result = YAP_RetryGoal( &goalInfo ); + YAP_LeaveGoal(TRUE, &goalInfo); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +YAP allows calling a *new* Prolog interpreter from `C`. One +way is to first construct a goal `G`, and then it is sufficient to +perform: + + +the result will be `FALSE`, if the goal failed, or `TRUE`, if +the goal succeeded. In this case, the variables in _G_ will store +the values they have been unified with. Execution only proceeds until +finding the first solution to the goal, but you can call +[findall/3](@ref findall) or friends if you need all the solutions. + +Notice that during execution, garbage collection or stack shifting may +have moved the terms + +@section Module_Manipulation_in_C Module Manipulation in C + +YAP allows one to create a new module from C-code. To create the new +code it is sufficient to call: + + +Notice that the new module does not have any predicates associated and +that it is not the current module. To find the current module, you can call: + + + +Given a module, you may want to obtain the corresponding name. This is +possible by using: + + +Notice that this function returns a term, and not an atom. You can +[YAP_AtomOfTerm](@ref YAP_AtomOfTerm) to extract the corresponding Prolog atom. + +@section Miscellaneous_ChYFunctions Miscellaneous C Functions + + + +@section Writing_C Writing predicates in C + +We will distinguish two kinds of predicates: + + + +The first kind of predicates should be implemented as a C function with +no arguments which should return zero if the predicate fails and a +non-zero value otherwise. The predicate should be declared to +YAP, in the initialization routine, with a call to + +