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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.