Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void PL_retry_address(void *)
As PL_retry(), but ensures an address as returned by malloc() is correctly recovered by PL_foreign_context_address().

int PL_foreign_control(control_t)
Extracts the type of call from the control argument. The return values are described above. Note that the function should be prepared to handle the PL_CUTTED case and should be aware that the other arguments are not valid in this case.

long PL_foreign_context(control_t)
Extracts the context from the context argument. In the call type is PL_FIRST_CALL the context value is 0L. Otherwise it is the value returned by the last PL_retry() associated with this goal (both if the call type is PL_REDO as PL_CUTTED).

void * PL_foreign_context_address(control_t)
Extracts an address as passed in by PL_retry_address().

Note: If a non-deterministic foreign function returns using PL_succeed or PL_fail, Prolog assumes the foreign function has cleaned its environment. No call with control argument PL_CUTTED will follow.

The code of figure 6 shows a skeleton for a non-deterministic foreign predicate definition.


typedef struct                  /* define a context structure */
{ ...
} context;ninclude.html#PL_open_foreign_frame()">PL_open_foreign_frame()/PL_close_foreign_frame().
module_t
A module is a unique handle to a Prolog module. Modules are used only to call predicates in a specific module.
foreign_t
Return type for a C-function implementing a Prolog predicate.
control_t
Passed as additional argument to non-deterministic foreign functions. See PL_retry*() and PL_foreign_context*().
install_t
Type for the install() and uninstall() functions of shared or dynamic link libraries. See secrefshlib.

./usr/share/doc/swi-prolog-doc/Manual/foreigninclude.html0100644000000000000000000033137107664706344022367 0ustar rootroot SWI-Prolog 5.2.0 Reference Manual: Section 7.6


Home Contents Index Summary Previous Next

7.6 The Foreign Include File

7.6.1 Argument Passing and Control

If Prolog encounters a foreign predicate at run time it will call a function specified in the predicate definition of the foreign predicate. The arguments 1, ... , <arity> pass the Prolog arguments to the goal as Prolog terms. Foreign functions should be declared of type foreign_t. Deterministic foreign functions have two alternatives to return control back to Prolog:

void PL_succeed()
Succeed deterministically. PL_succeed is defined as return TRUE.

void PL_fail()
Fail and start Prolog backtracking. PL_fail is defined as return FALSE.

7.6.1.1 Non-deterministic Foreign Predicates

By default foreign predicates are deterministic. Using the PL_FA_NONDETERMINISTIC attribute (see PL_register_foreign()) it is possible to register a predicate as a non-deterministic predicate. Writing non-deterministic foreign predicates is slightly more complicated as the foreign function needs context information for generating the next solution. Note that the same foreign function should be prepared to be simultaneously active in more than one goal. Suppose the natural_number_below_n/2 is a non-deterministic foreign predicate, backtracking over all natural numbers lower than the first argument. Now consider the following predicate:


quotient_below_n(Q, N) :-
        natural_number_below_n(N, N1),
        natural_number_below_n(N, N2),
        Q =:= N1 / N2, !.

In this predicate the function natural_number_below_n/2 simultaneously generates solutions for both its invocations.

Non-deterministic foreign functions should be prepared to handle three different calls from Prolog:

  • Initial call (PL_FIRST_CALL)
    Prolog has just created a frame for the foreign function and asks it to produce the first answer.
  • Redo call (PL_REDO)
    The previous invocation of the foreign function associated with the current goal indicated it was possible to backtrack. The foreign function should produce the next solution.
  • Terminate call (PL_CUTTED)
    The choice point left by the foreign function has been destroyed by a cut. The foreign function is given the opportunity to clean the environment.

Both the context information and the type of call is provided by an argument of type control_t appended to the argument list for deterministic foreign functions. The macro PL_foreign_control() extracts the type of call from the control argument. The foreign function can pass a context handle using the PL_retry*() macros and extract the handle from the extra argument using the PL_foreign_context*() macro.

void PL_retry(long)
The foreign function succeeds while leaving a choice point. On backtracking over this goal the foreign function will be called again, but the control argument now indicates it is a `Redo' call and the macro PL_foreign_context() will return the handle passed via PL_retry(). This handle is a 30 bits signed value (two bits are used for status indication).

void