Re: Multiple instances for embedded prolog interpreter

Jan Wielemaker <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
Well, there is a lot of state around.  Different engines have their own
stacks, but indeed
share predicates.  If that is the `state' for which you want multiple
instances you have
two options: create thread_local declared predicates, which are
predicates what have their
own set of clauses in each thread (which is the same as each engine), or
use modules.  In
each module you can have different sets of predicates that otherwise do
not interact as
long as you do not tell them to do so.

Just about any level of sharing and separation is typically pretty easy
to realise.  Just,
you must understand the separation provided by modules and threads and
decide what you
want.  The good news of sharing is that creating and destroying engines
is fast (about
100,000 per second on modern Linux systems and hardware).

	Cheers --- Jan


On 07/23/2013 09:20 PM, Stefan Radomski wrote:
> Hey again,
> 
> thank you for the quick response.
> 
> I implemented the approach, following the enginepool.c sample code written by Jan in 2003. Unfortunately, my second (and every subsequent) engine will just show the facts and predicates defined for the initial one. Which leads me to believe that there was some misunderstanding? It is not so much the concurrency I care about, but the fact that I have N instances of an embedded prolog interpreter that are unrelated with regard to their facts and predicates.
> 
> Currently I instantiate as follows (somewhat simplified to get rid of boost in code). This code will be called multiple times as part of the init function of a datamodel class, and I was hoping to get a new prolog "context" every time:
> 
> PL_engine_t engine;
> if (!PL_is_initialised(NULL, NULL)) {
> 	// this is called only once
> 	if(!PL_initialise(argc,av)) {
> 		LOG(ERROR) << "Error intializing prolog engine";
> 		PL_halt(1);
> 		return EXIT_FAILURE;
> 	}
> 	PL_set_engine(PL_ENGINE_CURRENT, &engine);
> } else {
> 	// this is called for every other instance
> 	engine = PL_create_engine(NULL);
> }
> 
> assert(engine);
> int rc = PL_set_engine(engine, NULL);
> assert(rc == PL_ENGINE_SET);
> 
> PlCall("listing");
> ----
> :- thread_local thread_message_hook/3.
> :- dynamic thread_message_hook/3.
> :- volatile thread_message_hook/3.
> 
> 
> Now, when I establish some fact, e.g.:
> PlCall("assert", PlCompound("sessionid", PlTerm(PlString("foo"))));
> 
> It will show up in the second engines initial listing. Is it not possible to have multiple prolog interpreters within the same runtime that will not share their facts and predicates?
> 
> Best regards
> Stefan
> 
> 
> On Jul 23, 2013, at 2:44 PM, Jan Wielemaker <[email protected]>
>  wrote:
> 
>> On 07/23/2013 02:22 PM, Stefan Radomski wrote:
>>> Hey there,
>>>
>>> we embedded SWI prolog as a logic engine via its C++ interface and
>>> it's working great. But we do need more than one instance of the
>>> PLEngine or at least distinct states. Seeing that PL_initialise will
>>> just initialize a global prolog interpreter, and the foreign
>>> predicates will not receive any kind of callbacks, we figured that
>>> there can only ever be one instance per runtime.
>>
>> Yes.  There is no plan to change that either, although it wouldn't
>> be terribly complicated because there are only a few global variables
>> that contain structures holding the whole lot together.
>>
>>> If that's the case, can we "simulate" multiple instances i.e. by
>>> swapping the interpreters state before calling any of the PL*
>>> functions? We do not necessarily need concurrency, just distinct
>>> states. We pondered about using several PLFrames to achieve something
>>> like that but it seems that they will just "rollback" any term
>>> references when closing.
>>
>> Frames merely control the scope of term_t (PlTerm) handles.  What
>> you need are engines.  Actually, the terminology is a bit misleading
>> because the one and only Prolog instance in the C++ interface is
>> called engine.  It predates the introduction of multiple engines in
>> SWI-Prolog ...
>>
>> I think what you want is what is described in
>>
>> 	http://www.swi-prolog.org/pldoc/man?section=threadmanymany
>>
>> Don't be misguided by the threading; you can use this stuff just as
>> well in a single thread.  Be careful that you do not pass term_t
>> (PlTerm) handles created on one engine to another one.  It will
>> crash.  Note that the engines have the same sharing behavior as
>> multiple Prolog threads, so while writing your Prolog code you
>> must program as if you are running in a thread.  This mainly
>> refers to dynamic code: :- dynamic is shared, :- thread_local
>> is not.
>>
>> 	Enjoy --- Jan
>>
>>>
>>> If this issue has been discussed previously, please be so kind as to
>>> provide a link.
>>>
>>> Best regards Stefan Radomski
>>>
>>>
>>> --- FB20 Telecooperation | Darmstadt University of Technology
>>> Hochschulstr. 10 | D-64289 Darmstadt Germany | Room S2|02 / A108 Tel
>>> +49 (6151) 16-6670 | Fax +49 (6151) 16-3052
>>>
>>> _______________________________________________ SWI-Prolog mailing
>>> list [email protected]
>>> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>>>
>>
>
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.