Re: Multiple instances for embedded prolog interpreter
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 07/24/2013 01:37 PM, Stefan Radomski wrote: > Thank you again for the quick response, > > On Jul 23, 2013, at 9:43 PM, Jan Wielemaker <[email protected]> > wrote: > >> 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. > > Let me give you some context here: We are using Prolog as an > ECMAScript replacement for scripting in XML documents (with good reasons > :). Our XML interpreter will take a set of such documents and interpret > them (in fact even a single document might nest others). As such, it is > imperative that the different Prolog scripting environments from the > different documents do not interfere with each other. > > I can't see thread_local working in our situation as our > interpreters > are already multi-threaded and multiple threads are serialized via > mutexes to linearize access to all of the Prolog interpreter > (performance is a distant second atm). In the optimal solution, the > different documents' Prolog environments would behave as if there were > no others. It *is* working flawlessly if there is only one such document. Using Prolog from multiple C++ threads is pretty trivial using the C Prolog engine API. In any case, if you want to use the thread-local approach, you must use multiple Prolog engines. It is a quite ok approach, provided you can enumerate the predicates that you will be using for storing an XML document beforehand, so you can declare all of them as thread_local. Possibly a nice benefit is that the clauses die with the engine (as they are not accessible outside the engine it makes no sense to keep them). > I could imagine using the modules approach, but it is important that Mapping each XML document to a module seems a more natural mapping to me. > something like the following remains possible and is scoped to the > current document's environment: > > <script>assert(event(foo)).</script> > > I am perfectly free to do whatever I want with the Prolog runtime > before interpreting the contained prolog expression, but the author of > the XML must not be required to handle the module scoping aspect. I > tried to prefix every invocation of user supplied prolog with a > module/1, but did not get it to work: > > C++ ---: > PlCall(("module(ns1)")); > PlCall("assert(sessionId(a1))"); > PlCall("listing."); > > PlCall(("module(ns2)")); > PlCall("assert(sessionId(a2))"); > PlCall("listing."); > --- > > It seems like asserted facts cannot be scoped in modules as the second listing/0 > will show two sessionId facts: module/1 sets the module for the toplevel query loop. You are not talking to an interactive toplevel, so that is meaningless. To insert in a module, use e.g., PlCall("assert(ns1:sessionId(a2))"); Which is the same as this, which might be a bit handier if you do not want to look into the term. PlCall("ns1:assert(sessionId(a2))"); Note that the C interface allows more explicit interaction with modules. Most of this is easily added to the C++ interface as well. If you want to know what is possible, check out the C API documentation.