Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SwiPlCs - Restarting prolog

24 views
Skip to first unread message

Vorl

unread,
Feb 2, 2010, 1:24:21 PM2/2/10
to
Hello,

I'm new with prolog and I'm studying for several days the possibility to use
it in an AI program. I've started leraning/using SWI Prolog and I'm
particulary trying out the C# interface for SWI-Porlog cause the main
program will be in C#.

I dont know if there are SwiPlCs users on the group, but there is one thing
I cannot find how to do after searching the web a couple of hours : Is it
possible to do a sequence of calls to prolog with different fact bases and
clauses each time ?

eg. :
while (not end) {
load a fact base
load a prolog program
get the result of a query
}

And is it possible to do the calls in parallel, in different threads ?
That's what I absolutely need to do.

The probleme is that the engine is represented by a static class. For the
moment, I use a combinaison of listing/0 and retractall/1 queries for the
first question but it seems to me a dirty and inefficient solution and I
have no solution for the second question.

I'm probably missing something ?

Vorl

Jan Wielemaker

unread,
Feb 2, 2010, 4:19:23 PM2/2/10
to
On 2010-02-02, Vorl <esth...@hotmail.com> wrote:
> Hello,
>
> I'm new with prolog and I'm studying for several days the possibility to use
> it in an AI program. I've started leraning/using SWI Prolog and I'm
> particulary trying out the C# interface for SWI-Porlog cause the main
> program will be in C#.
>
> I dont know if there are SwiPlCs users on the group, but there is one thing
> I cannot find how to do after searching the web a couple of hours : Is it
> possible to do a sequence of calls to prolog with different fact bases and
> clauses each time ?
>
> eg. :
> while (not end) {
> load a fact base
> load a prolog program
> get the result of a query
> }

To some extend. Considering you also want to to threading, this only
works reliable if you use completely dynamic code. That means that
you need to roll your own compililation loop that reads the clauses
and asserts them. Using static code, wiping out a module and reloading
it is `safe enough for interactive usage on a calm system'. The required
synchronization to make this fully safe would harm multi-threading too
much.

Loading code completely dynamic is not that hard. Alternatively and
much simpler, you can load the different fact-bases and programs into
different modules. Of course, the price is that all modules will be
loaded at some point.

If you want to keep life simple and `get the result of a query' can
be expressed as one query, it might be way easier to start a new
Prolog for each fact-base/program. On my system (Linux, AMD5400),
doing "time swipl -t true" (just starting and stopping the system)
takes 0.01 seconds elapsed time. I think this figure will be much
higher on Windows, but it might still be acceptable.

> And is it possible to do the calls in parallel, in different threads ?
> That's what I absolutely need to do.

With processes you can of course run concurrently. You can do the same
through the C# interface AFAIK (never tried) by managing Prolog threads
from C#.

> The probleme is that the engine is represented by a static class. For the
> moment, I use a combinaison of listing/0 and retractall/1 queries for the
> first question but it seems to me a dirty and inefficient solution and I
> have no solution for the second question.
>
> I'm probably missing something ?

listing/0 is surely a thing to avoid if performance is your target.
It isn't particularly fast. Use C# querying to enumerate the solutions
of a predicate.

It can all be done, but it is not the easiest thing to start with :-)
If you need massive concurrency on 32-bit platforms using threads, you
need the development version.

Success --- Jan

Vorl

unread,
Feb 2, 2010, 6:08:38 PM2/2/10
to
Thanks for the answer, it make things more clear.

The use of modules is probably not possible for me, as I want to do tens of
thousand of runs of the loop with potentially huge fact base.

The use of dynamic code with retarctall/1 works but I do not know for the
moment how I can use this with multithread. I have to study this deeper.

For information, starting a new Prolog in a process (and reading
fact-base/program from a generated file) is 4 times slower than previous
method in a small test I run under window. But the program was perhaps too
simple. With a more complex program, the process creation overhead may be
more negligeable (seems to be arround 60 ms). I need to do more tests...

Vorl


"Jan Wielemaker" <ja...@hppc323.few.vu.nl>wrote

Jan Wielemaker

unread,
Feb 3, 2010, 3:44:12 AM2/3/10
to
On 2010-02-02, Vorl <esth...@hotmail.com> wrote:
> Thanks for the answer, it make things more clear.
>
> The use of modules is probably not possible for me, as I want to do tens of
> thousand of runs of the loop with potentially huge fact base.

Using modules is always the most elegant way to have multiple programs and
fact-bases loaded at the same time. Of course, if this isn't necessary ...

> The use of dynamic code with retarctall/1 works but I do not know for the
> moment how I can use this with multithread. I have to study this deeper.

? If I recall well, just attach a Prolog engine to the C# thread and query.
There are some issues. If the computation uses assert/retract, you probably
want to use :- thread_local name/arity, ... for the predicates on which you
do that (better yet, do not use assert/retract).

The other disadvantage is that multi-threading on dynamic predicates involves
locking, so it doesn't scale well. That is where static code comes in. Just,
it isn't safe to ditch static code that is running. If you have a loop like
this:

forever
load program (+facts)
do multi-threaded querying
make sure all threads are done

Then you can use compile_predicates/1 to turn the dynamic code into static.
Next, run abolish on the predicates before starting the next iteration. Just,
you need to be sure that no other threads are playing with the predicates.

Note that 5.8.x leaks memory in this scenario. 5.9.7 should be fine.

> For information, starting a new Prolog in a process (and reading
> fact-base/program from a generated file) is 4 times slower than previous
> method in a small test I run under window. But the program was perhaps too
> simple. With a more complex program, the process creation overhead may be
> more negligeable (seems to be arround 60 ms). I need to do more tests...

My design in Unix would be a Prolog process to which you communicate using
sockets. Then you make it to a fork() for each new one you need. That would
probably get the overhead far below the 1ms, while most of the memory will be
shared between the different Prolog instances. Alas, that won't work on Windows;
fork() emulations are very slow :-(

Cheers --- Jan


Vorl

unread,
Feb 3, 2010, 12:54:49 PM2/3/10
to
ok, thanks a lot !


"Jan Wielemaker" <ja...@hppc323.few.vu.nl> a �crit dans le message de groupe
de discussion : slrnhmidl...@hppc323.few.vu.nl...

0 new messages