As a taster, we will show you two simple examples programs that use SICStus Prolog with the Tcl/Tk extensions: the ubiquitous “hello world” example; and a very simple telephone book look up example.
You are not expected to understand how these examples work at this stage. They are something for you to quickly type in to see how easy it is to add GUIs to Prolog programs through Tcl/Tk. After reading through the rest of this tutorial you will fully understand these examples and be able to write your own GUIs.
Here is the “Hello World” program; also in
library('tcltk/examples/ex1.pl')
:
:- use_module(library(tcltk)). go :- tk_new([name('Example 1')], Interp), tcl_eval(Interp, 'button .fred -text "hello world" -command { puts "hello world"}', _), tcl_eval(Interp, 'pack .fred', _), tk_main_loop.
To run it just start up SICStus (under Windows use sicstus
, not
spwin
), load the program, and evaluate the Prolog
goal go
. The first line of the go
clause calls
tk_new/2
, which creates a Tcl/Tk interpreter and returns a handle
Interp
through which Prolog will interact with the interpreter.
Next a call to tcl_eval/3
is made, which creates a button
displaying the ‘hello world’ text. Next a call is made to
tcl_eval/3
that causes the button to be displayed in the main
application window. Finally, a call is make to tk_main_loop/0
that passes control to Tcl/Tk, making sure that window events are
serviced.
See how simple it is with just a three line Prolog program to create an application window and display a button in it. Click on the button and see what it does.
The reason you should use sicstus
under Windows instead of
spwin
is that the latter does not have the C standard
streams (stdin
,stdout
,stderr
) and the Tcl
command puts
will give an error if there is no stdout
.
The previous example showed us how to create a button and display some text in it. It was basically pure Tcl/Tk generated from within Prolog but did not have any interaction with Prolog. The following example demonstrates a simple callback mechanism. A name is typed into a text entry box, a button is pressed, which looks up the telephone number corresponding to the name in a Prolog database, and the telephone number is then displayed.
Here is the code; also in library('tcltk/examples/ex2.pl')
:
:- use_module(library(tcltk)). telephone(fred, '123-456'). telephone(wilbert, '222-2222'). telephone(taxi, '200-0000'). telephone(mary, '00-36-1-666-6666'). go :- tk_new([name('Example 2')], T), tcl_eval(T, 'entry .name -textvariable name',_), tcl_eval(T, 'button .search -text search -command { prolog telephone($name,X); set result $prolog_variables(X) }', _), tcl_eval(T, 'label .result -relief raised -textvariable result', _), tcl_eval(T, 'pack .name .search .result -side top -fill x', _), tk_main_loop.
Again, to run the example, start up SICStus Prolog, load the code,
and run the goal go
.
You will notice that three widgets will appear in a window: one is for entering the name of the person or thing that you want to find the telephone number for, the button is for initiating the search, and the text box at the bottom is for displaying the result.
Type fred into the entry box, hit the search button and you should see the phone number displayed. You can then try the same thing but with wilbert, taxi or mary typed into the text entry box.
What is happening is that when the button is pressed, the value in the
entry box is retrieved, then the telephone/2
predicate is
called in Prolog with the entry box value as first argument, then
the second argument of telephone is retrieved (by this time
bound to the number) and is displayed below the button.
This is a very crude example of what can be done with the Tcl/Tk module in Prolog. For example, this program does not handle cases where there is no corresponding phone number or where there is more than one corresponding phone number. The example is just supposed to wet your appetite, but all these problems can be handled by Prolog + Tcl/Tk, although with a more sophisticated program. You will learn how to do this in the subsequent chapters.