Since @kuniaki.mukai is working on:
The normal expectation would be that
variant terms (=@=)/2 have identical (==)/2
numbervars/3 outcomes.
Doesn’t work for numbervars/3 in SWI-Prolog:
test1(X) :- X = f(g(X,_B),_A).
test2(X) :- Y = g(f(Y,A),_B), X = f(Y,A).
The two X
are variants of each other:
/* SWI-Prolog 9.3.26 */
?- test1(X1), test2(X2), X1 =@= X2.
true
Now try this:
/* SWI-Prolog 9.3.26 */
?- test1(X), numbervars(X,0,_).
X = f(g(X, A), B).
?- test2(X), numbervars(X,0,_).
X = f(_S1, A), % where
_S1 = g(f(_S1, A), B).
In one instance the 2nd argument of X is '$VAR'(1)
, i.e. B,
in another instance the 2nd argument of X is '$VAR'(0)
, i.e A.
So numbervars/3 cannot be used to create variant keys.
Edit 26.07.2025:
Trealla Prolog isn’t better off:
/* Trealla Prolog 2.79.0 */
?- test1(X), numbervars(X,0,_).
X = f(g(X,'$VAR'(0)),'$VAR'(1)).
?- test2(X), numbervars(X,0,_).
X = f(g(f(X,'$VAR'(0)),'$VAR'(1)),'$VAR'(0)).
And Scryer Prolog has even a printing error:
/* Scryer Prolog 0.9.4-417 */
?- test1(X), numbervars(X,0,_).
X = f(g(X,'$VAR'(0)),'$VAR'(1)).
?- test2(X), numbervars(X,0,_).
X = f(g(f('$VAR'(0),'$VAR'(1)),g(f(g('$VAR'(1),'$VAR'(0)),
f(g(f('$VAR'(0),'$VAR'(1)),g(f(g('$VAR'(1),'$VAR'(0)),
f(g(f('$VAR'(0),'$VAR'(1)),g(f(g('$VAR'(1),'$VAR'(0)),
f(g(f('$VAR'(0),'$VAR'(1)),g(f(g('$VAR'(1),'$VAR'(0)),
f(g(f('$VAR'(...),'$VAR'(...)),g(f(g(...),'$VAR'(...)),
'$VAR'(...))),'$VAR'(0))),'$VAR'(1))),'$VAR'(0))),
'$VAR'(1))),'$VAR'(0))),'$VAR'(1))),'$VAR'(0))),
'$VAR'(1))),'$VAR'(0)).
What the heck is the '$VAR'(0)
after the f(g(f(
?