Hi folks,
I’m considering making use of the engines functionality in Prolog but am having trouble getting basic stuff to work. Probably I’m just misunderstanding the documentation and examples, but I figured I’d ask for help rather than floundering.
SWI-Prolog version 9.0.4
engines_scratch.pl
create_simulator(Handle) :-
engine_create(_, process_commands() ,Handle).
process_commands() :-
engine_fetch(Command),
Command,
engine_yield(Command),
process_commands().
:- create_simulator(alice_sim).
:- engine_post(alice_sim, assertz( f(a) ), _ ).
:- engine_post(alice_sim, assertz( f(b) ), _ ).
REPL
1 ?- ['c:\\Users\\Elean\\Perforce\\mainline\\BoH\\test_engines.pl'].
true.
2 ?- engine_post(alice_sim, f(X)).
true.
3 ?- engine_next(alice_sim, Term1).
Term1 = f(a).
4 ?- engine_next(alice_sim, Term2).
ERROR: term `delivery' does not exist in alice_sim (Use engine_post/2,3)
ERROR: In:
ERROR: [10] engine_next(alice_sim,_23322)
ERROR: [9] toplevel_call(user:user: ...) at c:/program files/swipl/boot/toplevel.pl:1173
I expected the fourth call to generate Term2 = f(b). via backtracking, but clearly it’s not, and I don’t get why. Any thoughts?
In case folks are curious about the background:
I’m building an agent based simulation in Prolog for a game I’m working on. Central to the game is that each agent has its own perspective on the world, including both facts about the world, the ontology over which those facts are defined. I’ve implemented that as fully separated knowledge bases, with actions and responses passing between as messages. However, currently these knowledge bases are stored in different modules, which significantly complicates code that needs to be common across these agents.
It seems like switching to using engines will allow me to cleanly run each of the agents separately, and remove the need to thread Module:Predicate variables throughout a bunch of my code!
Edit 1: Added code blocks for easier reading
Edit 2: After experimenting with this more, it seems as though the above behavior may actually be a bug, possibly related to #1021
Edit 3: Although I think the above issue is still valid, it seems I misunderstood how engines handle dynamic and global data; unlike threads they don’t keep their own. Is that only achievable with threads, or is there a way of configuring engines to do that?