next up previous index
Next: Implicit Data Conversion Up: Using Tcl/Tk from Previous: Accessing Prolog Variables

Calling Prolog from Tcl Using Prolog Syntax

  The prolog command allows to call a Prolog predicate from Tcl, using Tcl syntax and arguments which have an equivalent representation in both languages. This is usually sufficient, however sometimes we might want to call Prolog using Prolog syntax. The ProTcXl command call_prolog   provides this functionality. Since it is implemented using other ProTcXl primitives, its implementation is a good example how to use ProTcXl . Let us show how a simple version of call_prolog can be implemented:

The command is

call_prolog string
and its argument is a string which contains a Prolog term.   call_prolog calls this term as Prolog goal and then it puts all its variables into the var array.   We first define a Prolog predicate call_from_tcl(String, Res) which parses the contents of String, extracts its variables, calls the Prolog term and unifies Res with a list of name-value lists. We use readvar/3   to parse the string and return variables together with their names:
[eclipse 17]: [user].
call_from_tcl(String, Res) :-
    open(String, string, s),
    readvar(s, Goal, Vars),             % parse and return variables
    close(s),
    call(Goal),
    return_vars(Vars, Res).

% convert [N|V] to [N, V] because pairs do not exist in Tcl
return_vars([], []).
return_vars([[Name|Value]|L], [[Name, Value]|LR]) :-
    return_vars(L, LR).
 user      compiled traceable 704 bytes in 0.00 seconds

Second, we define the Tcl call_prolog procedure: it calls the Prolog predicate call_from_tcl/2 and stores the returned list of variable-value lists in X. Then it sets the elements of the var array to the appropriate values:

proc call_prolog {goal} {
    global var
    prolog "tcl_call $goal X"
    set list $var(X)
    unset var(X)
    foreach pair $list {          # we do: set var(Name) Value
        set var([lindex $pair 0]) [lindex $pair 1]
    }
}

call_prolog   can call arbitrary Prolog goals:

[eclipse 18]: tclsh.
% call_prolog {append([1,2],[a,b],X),append(X,X,Y)}
success
% array get var;           # list all array elements
[X, [1, 2, a, b], Y, [1, 2, a, b, 1, 2, a, b]]
% call_prolog {get_flag(hostarch,X),setval(arch1,X)}
success
% call_prolog {getval(arch1,X)}; puts $var(X)
i386_linux
Note that although we can use arbitrary Prolog syntax in the argument of call_prolog, this string cannot contain any spaces, otherwise it would be interpreted by Tcl as a list with a space separator, because in Tcl there is no difference between a string containing spaces and a list.



next up previous index
Next: Implicit Data Conversion Up: Using Tcl/Tk from Previous: Accessing Prolog Variables



Micha Meier
Tue Jul 2 09:49:39 MET DST 1996