The Tcl interpreters created through the SICStus Prolog Tcl/Tk library have been extended to allow calls to the underlying Prolog system.
To evaluate a Prolog expression in the Prolog system from a Tcl
interpreter, the new prolog
Tcl command is invoked. It has the
following form:
prolog PrologGoal
where PrologGoal is the printed form of a Prolog goal. This
causes the goal to be executed in Prolog. It will be executed in
the user
module unless it is prefixed by a module
name. Execution is always determinate.
The return value of the command either of the following:
"1", if execution succeeded,
"0", if execution failed,
If succeeded (and "1" was returned) then any variable in
PrologGoal that has become bound to a Prolog term will
be returned to Tcl in the Tcl array named prolog_variables
with
the variable name as index. The term is converted to Tcl using the
same conversion as used for Tcl commands (see Command Format). As a
special case the values of unbound variables and variables with
names starting with _
, are not recorded and need not conform to
the special command format, this is similar to the threatment of such
variables by the Prolog top-level.
An example:
test_callback(Result) :- tcl_new(Interp), tcl_eval(Interp, 'if {[prolog "foo(X,Y,Z)"] == 1} \\ {list $prolog_variables(X) \\ $prolog_variables(Y) \\ $prolog_variables(Z)}', Result), tcl_delete(Interp). foo(1, bar, [a, b, c]).
When called with the query:
| ?- test_callback(Result).
will succeed, binding the variable Result
to:
"1 bar {a b c}"
This is because execution of the tcl_eval/3
predicate
causes the execution of the prolog
command in Tcl, which executes
foo(X, Y, Z)
in Prolog making the following bindings:
X = 1
, Y = bar
, Z = [a, b, c]
. The bindings
are returned to Tcl in the associative array prolog_variables
where prolog_variables(X)
is "1", prolog_variables(Y)
is
"bar", and prolog_variables(Z)
is "a b c". Then Tcl goes on to
execute the list
command as
list "1" "bar" "a b c"
which returns the result
"1 bar {a b c}"
(remember: nested lists magically get represented with curly brackets)
which is the string returned in the Result part of the Tcl call,
and is ultimately returned in the Result
variable of the
top-level call to test_callback(Result)
.
If an error occurs during execution of the prolog
Tcl command, a
tcl_error/2
exception will be raised. The message part of the
exception will be formed from the string Exception during Prolog
execution:
appended to the Prolog exception message. An example is
the following:
| ?- tcl_new(T), tcl_eval(T, 'prolog wilbert', R).
which will print
{TCL ERROR: tcl_eval/3 - Exception during Prolog execution: wilbert existence_error(wilbert,0,procedure,user:wilbert/0,0)}
at the Prolog top-level, assuming that the predicate
wilbert/0
is not defined on the Prolog side of the system. (This
is a tcl_error
exception containing information about the
underlying exception, an existence_error
exception, which was
caused by trying to execute the non-existent predicate
wilbert
.)