Bei der Gruppe, für die Sie eine Mitteilung verfassen, handelt es sich um eine Usenet-Gruppe. Wenn Sie in dieser Gruppe Nachrichten posten, ist Ihre E-Mail-Adresse für jeden im Internet sichtbar
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 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.
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...
> On 2010-02-02, Vorl <esthg...@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.
> 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 :-(
> On 2010-02-02, Vorl <esthg...@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 :-(