View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2016, VU University Amsterdam
    7    All rights reserved.
    8
    9    Redistribution and use in source and binary forms, with or without
   10    modification, are permitted provided that the following conditions
   11    are met:
   12
   13    1. Redistributions of source code must retain the above copyright
   14       notice, this list of conditions and the following disclaimer.
   15
   16    2. Redistributions in binary form must reproduce the above copyright
   17       notice, this list of conditions and the following disclaimer in
   18       the documentation and/or other materials provided with the
   19       distribution.
   20
   21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   25    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   31    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32    POSSIBILITY OF SUCH DAMAGE.
   33*/
   34
   35:- module('$engines',
   36          [ engine_create/3,       % ?Template, :Goal, -Engine
   37            engine_create/4,       % ?Template, :Goal, -Engine, +Options
   38            engine_next_reified/2, % +Engine, -Term
   39            engine_yield/1,        % +Term
   40            engine_self/1,         % -Engine
   41            current_engine/1       % ?Engine
   42          ]).   43
   44:- meta_predicate
   45    engine_create(?, 0, -),
   46    engine_create(?, 0, -, +).

Engine (interactor) support

*/

 engine_create(?Template, :Goal, ?Engine) is det
 engine_create(?Template, :Goal, -Engine, +Options) is det
Create a new engine, prepared to run Goal and return answers as instances of Template. Goal is not started.
   59engine_create(Template, Goal, Engine) :-
   60    (   atom(Engine)
   61    ->  '$engine_create'(Engine, Template+Goal, [alias(Engine)])
   62    ;   '$engine_create'(Engine, Template+Goal, [])
   63    ).
   64engine_create(Template, Goal, Engine, Options) :-
   65    '$engine_create'(Engine, Template+Goal, Options).
 engine_next(+Engine, -Term) is semidet
Switch control to Engine and if engine produces a result, switch control back and unify the instance of Template from engine_create/3,4 with Term. Repeatedly calling engine_next/2 on Engine retrieves new instances of Template by backtracking over Goal. Fails of Goal has no more solutions. If Goal raises an exception the exception is re-raised by this predicate.
 engine_next_reified(+Engine, -Term) is det
Similar to engine_next/2 but returning answers in reified form. Answers are returned using the terms the(Answer), no, and throw(Error).
   82engine_next_reified(Engine, Answer) :-
   83    (   catch(engine_next(Engine, Answer0), Error, true)
   84    ->  (   var(Error)
   85        ->  Answer = the(Answer0)
   86        ;   Answer = throw(Error)
   87        )
   88    ;   Answer = no
   89    ).
 engine_post(+Engine, +Package) is det
Make the term Package available for engine_fetch/1 from within the engine. At most one term can be made available. Posting a package does not cause the engine to wakeup. Therefore, an engine_next/2 call must follow a call to this predicate to make the engine fetch the package. The predicate engine_post/3 combines engine_post/2 and engine_next/2.
Errors
- permission_error(post_to, engine, Package) if a package was already posted and has not yet been fetched by the engine.
 engine_post(+Engine, +Package, -Reply) is semidet
Same as engine_next/2, but transfer Term to Engine if Engine calls engine_fetch/1. Acts as:
engine_post(Engine, Package, Answer) :-
    engine_post(Engine, Package),
    engine_next(Engine, Answer).
 engine_destroy(+Engine) is det
Destroy Engine. Eventually, engine destruction will also be subject to symbol garbage collection.
 engine_yield(+Term) is det
Make engine_answer/2 return with the given term.
  123engine_yield(Term) :-
  124    '$engine_yield'(Term, 256).
 engine_self(E) is semidet
True if executed inside engine E
  130engine_self(E) :-
  131    thread_self(E),
  132    is_engine(E).
 current_engine(?E)
True if E is a currently know engine.
  138current_engine(E) :-
  139    thread_property(E, engine(true)).
 $engine_yield(?Term, +Code:integer)
Cause PL_next_solution() to return with Code, providing access to Term through PL_yielded(). Can only be called if PL_open_query() is called with PL_Q_ALLOW_YIELD. Code tells the code that controls PL_next_solution() what to do and the codes used must be agreed upon for a specific application. Code must be an integer >= 256. Other return codes are reserved by the system.
  151'$engine_yield'(_Term, _Code) :-
  152    '$yield'