Standard term order (ISO/IEC 13211-1 7.2 Term order) is defined over all terms — including variables. While there are good uses for this — think of the implement
Next! This should do better than my previous attempt:
lt(X,Y) :-
X \== Y,
( X \= Y
-> term_variables(X,Xvars),
term_variables(Y,Yvars),
T_alpha is -(10.0^1000), % HACK!
functor(T_omega,z,255), % HACK!
copy_term(t(X,Y,Xvars,Yvars),t(X1,Y1,X1vars,Y1vars)),
copy_term(t(X,Y,Xvars,Yvars),t(X2,Y2,X2vars,Y2vars)),
copy_term(t(X,Y,Xvars,Yvars),t(X3,Y3,X3vars,Y3vars)),
copy_term(t(X,Y,Xvars,Yvars),t(X4,Y4,X4vars,Y4vars)),
maplist(=(T_alpha),X1vars), maplist(maybe_unify(T_omega),Y1vars),
maplist(=(T_omega),X2vars), maplist(maybe_unify(T_alpha),Y2vars),
maplist(=(T_omega),Y3vars), maplist(maybe_unify(T_alpha),X3vars),
maplist(=(T_alpha),Y4vars), maplist(maybe_unify(T_omega),X4vars),
% do T_alpha and T_omega have an impact on the order?
( compare(Cmp,X1,Y1),
compare(Cmp,X2,Y2),
compare(Cmp,X3,Y3),
compare(Cmp,X4,Y4),
-> Cmp = (<) % no: demand that X @< Y holds
; throw(error(instantiation_error,lt/2))
)
; throw(error(instantiation_error,lt/2))
).
The auxiliary maybe_unify/2
deals with variables occurring in both X
and Y
:
maybe_unify(K,X) :-
( var(X)
-> X = K
; true
).
Checking with GNU-Prolog 1.4.4:
?- lt(a(X,Y,c(c),Z1), a(X,Y,b(b,b),Z2)).
yes
?- lt(a(X,Y,b(b,b),Z1), a(X,Y,c(c),Z2)).
no
?- lt(a(X,Y1,c(c),Z1), a(X,Y2,b(b,b),Z2)).
uncaught exception: error(instantiation_error,lt/2)
?- lt(a(X,Y1,b(b,b),Z1), a(X,Y2,c(c),Z2)).
uncaught exception: error(instantiation_error,lt/2)
?- lt(b(b), a(a,a)).
yes
?- lt(a(X), a(Y)).
uncaught exception: error(instantiation_error,lt/2)
?- lt(X, 3).
uncaught exception: error(instantiation_error,lt/2)
?- lt(X+a, X+b).
yes
?- lt(X+a, Y+b).
uncaught exception: error(instantiation_error,lt/2)
?- lt(a(X), b(Y)).
yes
?- lt(a(X), a(Y)).
uncaught exception: error(instantiation_error,lt/2)
?- lt(a(X), a(X)).
no
?- lt(X+1,1+2).
uncaught exception: error(instantiation_error,lt/2)
?- lt(X+X+2,X+1+3). % NEW
uncaught exception: error(instantiation_error,lt/2)