40.4.4.3 An example

As an example of using the prolog event system supplied by the tcltk library, we will return to our 8-queens example but now approaching from the Prolog side rather than the Tcl/Tk side:

     :- use_module(library(tcltk)).
     
     setup :-
         tk_new([name('SICStus+Tcl/Tk - Queens')], Tcl),
         tcl_eval(Tcl, 'source queens.tcl', _),
         tk_next_event(Tcl, Event),
         (   Event = next -> go(Tcl),
         ;   closedown(Tcl)
         ).
     
     closedown(Tcl) :-
         tcl_delete(Tcl).
     
     go(Tcl) :-
         tcl_eval(Tcl, 'clear_board', _),
         queens(8, Qs),
         show_solution(Qs, Tcl),
         tk_next_event(Tcl, Event),
         (   Event = next -> fail
         ;   closedown(Tcl)
         ).
     go(Tcl) :-
         tcl_eval(Tcl, 'disable_next', _),
         tcl_eval(Tcl, 'clear_board', _),
         tk_next_event(Tcl, _Event),
         closedown(Tcl).

This is the top-level fragment of the Prolog side of the 8-queens example. It has three predicates: setup/0, closedown/1, and go/1. setup/0 simply creates the Tcl interpreter, loads the Tcl code into the interpreter using a call to tcl_eval/3 (which also initialises the display) but then calls tk_next_event/2 to wait for a message from the Tk side.

The Tk part that sends prolog_event-s to Prolog looks like this:

     button .next -text next -command {prolog_event  next}
     pack .next
     
     button .stop -text stop -command {prolog_event stop}
     pack .stop

that is two buttons, one that sends the atom next, the other that sends the atom stop. They are used to get the next solution and to stop the program respectively.

So if the user presses the next button in the Tk window, then the Prolog program will receive a next atom via a prolog_event/tk_next_event pair, and the program can proceed to execute go/1.

go/1 is a failure driven loop that generates 8-queens solutions and displays them. First it generates a solution in Prolog and displays it through a tcl_eval/3 call. Then it waits again for a Prolog events via tk_next_event/2. If the term received on the Prolog event queue is next, corresponding to the user pressing the “next solution” button, then fail is executed and the next solution found, thus driving the loop.

If the stop button is pressed then the program does some tidying up (clearing the display and so on) and then executes closedown/1, which deletes the Tcl interpreter and the corresponding Tk windows altoegther, and the program terminates.

This example fragment show how it is possible for a Prolog program and a Tcl/Tk program to communicate via the Prolog event queue.