Jan Wielemaker schrieb:
> ?- leq(X,Y), leq(Y,Z), leq(Z,X).
>
> This is a pretty normal query. How confused will the users be if they
> find out that print(VAR) prints the name of the toplevel variable, while
> the clauses also give the variables names that are in the same X,Y,Z
> domain, but the toplevel Y is the called X in the clause, etc.?
>
> I think this is a dead end. I agree that _G232 is difficult to interpret.
> The grahical tracer shows calls in their context using the variable names
> from the context. That helps a little. What you're asking here is to
> show variable names from a different context. That can't be right.
>
> Cheers --- Jan
Yes, it is kind of confusing. And it takes some time to get
it right, respectively one needs to take some decision when
to display which name.
I am not sure how exactly gtrace works. Currently working on
a Mac, cannot verify. But there is a general problem with the
traditional Prolog loop in newer Prolog systems:
- You enter variables names in the top-level.
- They are not available as long as no
top solution is reached.
- Magically the top-level shows variable names
when a top solution is reached.
So in the old times we basically had:
?- X = Y.
X = _C,
Y = _C
Now some Prolog systems magically do the following:
?- X = Y.
X = Y
Maybe we can push some of this magic to other places. One
such place is the debugger. The ports are simple to do.
Just use the same routine as when writing answers. Here
is an example with recursion where new contexts are
created:
?- [user]
append([],X,X).
append([X|Y],Z,[X|T]) :- append(Y,Z,T).
^D
?- trace.
Yes
?- append([A,B],[C],R).
0 Call append([A, B], [C], R) ?
1 Call append([B], [C], _K) ?
2 Call append([], [C], _R) ?
2 Exit append([], [C], [C]) ?
1 Exit append([B], [C], [B, C]) ?
0 Exit append([A, B], [C], [A, B, C]) ?
R = [A, B, C]
In the above the variable names of the append/3 rules
do not appear. The _K and the _R are different versions
of the variable T in the second rule of append/3. But
T itself does not appear. This is how rule variables
appear via fresh variables only. Here fresh variables
have the format _@. One could also use the _G# format,
this is not that relevant.
In the curse of the execution of a top-level query
it can happen that goal invocations appear that have
fewer and fewer variables in common with the top-level
query. They will be all shown as fresh, and less magic
will be involved.
For the variable bindings inside a rule application,
something can be done that partially takes the rule
variables into account. It is tempting to write out
the bindings viewed from the variable names of the rule.
But the more simpler approach is to use the top-level
query variable names only on the right hand side of
the (=)/2 operator. And on the left hand side the rule
names. So that something as follows results:
?- append([A,B],[C],R).
0 Call append([A, B], [C], R) ?b
A = A
B = B
C = C
R = R
0 Call append([A, B], [C], R) ?
1 Call append([B], [C], _K) ?b
X = A
Y = [B]
Z = [C]
T = _K
1 Call append([B], [C], _K) ?
2 Call append([], [C], _R) ?b
X = B
Y = []
Z = [C]
T = _R
2 Call append([], [C], _R) ?
2 Exit append([], [C], [C]) ?b
X = B
Y = []
Z = [C]
T = [C]
2 Exit append([], [C], [C]) ?
1 Exit append([B], [C], [B, C]) ?b
X = A
Y = [B]
Z = [C]
T = [B, C]
1 Exit append([B], [C], [B, C]) ?
0 Exit append([A, B], [C], [A, B, C]) ?b
A = A
B = B
C = C
R = [A, B, C]
0 Exit append([A, B], [C], [A, B, C]) ?
R = [A, B, C]
In the above we see for example that _K
and _R where indeed versions of T. _R then
became [C] and _K then became [B, C]. The
binding display approach used above will
not shorten:
X = _C
Y = _C
To:
X = Y
Because this would violate our simple rule
to use the variable names from top-level query
on the right hand side of (=)/2. So for the
bindings of a clause when displayed during debugging
the end-user would need the old answer substitution
reasoning, to find out how the variables are actually
interconnected.
I was already thinking of an enhanced magic, that
would also use the variables names of the clauses
on the right hand side of (=)/2 when displaying
bindings during debugging. We could for example
use:
T' : first version of T
T'' : second version of T
Etc..
But not sure what the implications would be. And
not yet found an economic naming scheme. Don't want
to look at the 100-th version of T which would
be T'''''''''''''''''''''...... 100 times.
Bye