Re: simultaneous open queries
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
Hi Ed,
On 03/18/2014 02:48 PM, Edd Barrett wrote:
> Hi,
>
> I am currently trying to get by head around the restrictions relating to
> simultaneous queries in a single threaded program that uses the SWI Prolog C
> API.
>
> We are told in the docs [0] that "a foreign context can have at most one
> active query" and that "we are "not allowed to open multiple queries and
> start generating solutions for each".
>
> So it seems that we are limited (at least without threading?) to one
> simultaneous query per calling context. Now, a calling context is an
> instance of module_t; the type used to refer to a Prolog module.
First of all, the module argument defines the module context of the
call. That is, the module used to resolve unqualified arguments to
meta-predicates. It refers to the predicate @/2. For example, the code
below will assert `t' in the module 'data':
predicate_t pred = PL_predicate("assertz", 1, "system");
term_t t = PL_new_term_refs(1);
module_t datam = PL_new_module(PL_new_atom("data"));
<create term in t>
PL_call_predicate(datam, PL_Q_NORMAL, pred, t);
This module context has nothing to do with single or multiple queries
being active.
> I am having difficulty understanding what exactly this means in the
> sense of a calling context. Does it mean that in order for simultaneous
> queries to be open, the "callers" must be defined in different modules?
> I can't seem to find any documentation describing the role of a calling
> context (other than it is a module).
So, no.
One thread can not have multiple open queries, period ... Well, almost.
You *can* call Prolog, Prolog calls back C and then the C can open
another query. I.e., you can have C/Prolog mutually recursive functions.
You CAN NOT do
q1 = PL_open_query(...);
q2 = PL_open_query(...);
for(;;)
if ( PL_next_solution(q1) && PL_next_solution(q2) )
...
This would be coroutining, which is not provided by SWI-Prolog (dunno
whether there are systems that can do this). What you can do is create
an additional *engine* using PL_create_engine(). Now, you can switch
engines using PL_set_engine() and from a single C thread you can create
queries in both engines and ask both engines for solutions. I never
tried it ...
> Asked differently, is it possible to have simultaneous queries open in a
> single threaded C application at all?
So, yes, but engines do use the threading library. In fact, the code
running in the second engine claims to run in a thread. Anyway,
SWI-Prolog can not be built without threading support since quite a few
versions.
So, an engine is a set of Prolog stacks and a state that is able to
run Prolog queries. An engine is normally connected to a unique
(native) thread, but it can be disconnected from the thread and
re-connected to another thread.
Hope this is clear ...
Cheers --- Jan
> Perhaps we can use the outcomes of this discussion to improve the
> documentation.
>
> [0] http://www.swi-prolog.org/pldoc/man?section=foreign-create-query
Feel free to update. Preferably as git patches by editing man/foreign.doc
(no, these are not Word files; Word didn't exist when I started the docs.
They are LaTeX that is pre-processed a little).
Cheers --- Jan