Evaluating Prolog Expressions from Tcl

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.)