Interactive programming with pengines

Torbjörn Lager <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <CA+Y3JZhC1DvuH-aMUqV1wDMz2_8pY5hgu+XRnN3PXPKoYrPKsw@mail.gmail.com>
One thing I like about Prolog is that most things can be explored
interactively, at the ?- prompt. It's a good way to explore a new
library for example. Having the name(<name>) option in
pengine_create/1 is one way of making this more convenient. Already at
this point, we can do:

?- pengine_create([name(a)]).
true.

?- pengine_create([name(b)]).
true.

?- pengine_ask(a, member(A, [a,b,c])).
true.

?- pengine_ask(b, append(Xs, Ys, [a,b,c]), [template(Xs-Ys)]).
true.

?- pengine_next(b).
true.

?- pengine_next(a).
true.

?- pengine_event_loop(writeln).
create(eddcb314-9192-11e3-a036-3c075453f481,true)
create(f1d773aa-9192-11e3-b8e0-3c075453f481,true)
success(eddcb314-9192-11e3-a036-3c075453f481,[member(a,[a,b,c])],true)
success(f1d773aa-9192-11e3-b8e0-3c075453f481,[[]-[a,b,c]],true)
success(f1d773aa-9192-11e3-b8e0-3c075453f481,[[a]-[b,c]],true)
success(eddcb314-9192-11e3-a036-3c075453f481,[member(b,[a,b,c])],true)


The problem is that you don't get any responses until you call
pengine_event_loop/1, and then you'll get all of them at the same
time. Also, once you have called pengine_event_loop/1, you won't be
able to send more commands to your pengines. :-(

Fortunately, I think this can be fixed by adding an option
'asynch(Boolean)' to pengine_event_loop/1. (Boolean should most likely
be false by default, since using asynch(true) uses an extra thread.)
Now, we would be able to START the interaction by starting the event
loop:

?- pengine_event_loop(writeln, [asynch(true)]).
true.

?- pengine_create([name(a)]).
create(eddcb314-9192-11e3-a036-3c075453f481,true)
true.

?- pengine_create([name(b)]).
create(f1d773aa-9192-11e3-b8e0-3c075453f481,true)
true.

?- pengine_ask(a, member(A, [a,b,c])).
success(eddcb314-9192-11e3-a036-3c075453f481,[member(a,[a,b,c])],true)
true.

?- pengine_ask(b, append(Xs, Ys, [a,b,c]), [template(Xs-Ys)]).
success(f1d773aa-9192-11e3-b8e0-3c075453f481,[[]-[a,b,c]],true)
true.

?- pengine_next(b).
success(f1d773aa-9192-11e3-b8e0-3c075453f481,[[a]-[b,c]],true)
true.

?- pengine_next(a).
success(eddcb314-9192-11e3-a036-3c075453f481,[member(b,[a,b,c])],true)
true.

?-

Instead of using writeln/1 as the handler, we could probably use a
predicate (maybe pengine_write_event/1) that replaced IDs with names,
like so:

?- pengine_event_loop(pengine_write_event, [asynch(true)]).
true.

?- pengine_create([name(a)]).
create(a,true)
true.

?- pengine_create([name(b)]).
create(b,true)
true.

?- pengine_ask(a, member(A, [a,b,c])).
success(a,[member(a,[a,b,c])],true)
true.

?- pengine_ask(b, append(Xs, Ys, [a,b,c]), [template(Xs-Ys)]).
success(b,[[]-[a,b,c]],true)
true.

?- pengine_next(b).
success(b,[[a]-[b,c]],true)
true.

?- pengine_next(a).
success(a,[member(b,[a,b,c])],true)
true.

?- pengine_create([name(c)]).
create(c,true)
true.

?- pengine_ask(c, (between(1, 3, X), pengine_output(X), fail).
output(c,1)
output(c,2)
output(c,3)
success(c,[(between(1, 3, X), pengine_output(X), fail)],true)
true.

Adding the asynch option to pengine_create/1 might be a good idea. Thoughts?

- Torbjörn

-- 
Torbjörn Lager
Professor of General and Computational Linguistics
Department of Philosophy, Linguistics and Theory of Science
University of Gothenburg
Box 200, SE-405 30 Gothenburg, Sweden
Phone: +46317864962
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.