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
What the heck! I'll give it a shot, too!
lt(X,Y) :-
X \== Y,
( X \= Y
-> term_variables(X,Xvars),
term_variables(Y,Yvars),
list_vars_excluded(Xvars,Yvars,XonlyVars),
list_vars_excluded(Yvars,Xvars,YonlyVars),
_ = s(T_alpha),
functor(T_omega,zzzzzzzz,255), % HACK!
copy_term(t(X,Y,XonlyVars,YonlyVars),t(X1,Y1,X1onlyVars,Y1onlyVars)),
copy_term(t(X,Y,XonlyVars,YonlyVars),t(X2,Y2,X2onlyVars,Y2onlyVars)),
maplist(=(T_alpha),X1onlyVars), maplist(=(T_omega),Y1onlyVars),
maplist(=(T_omega),X2onlyVars), maplist(=(T_alpha),Y2onlyVars),
% do T_alpha and T_omega have an impact on the order?
( compare(Cmp,X1,Y1),
compare(Cmp,X2,Y2)
-> Cmp = (<) % no: demand that X @< Y holds
; throw(error(instantiation_error,lt/2))
)
; throw(error(instantiation_error,lt/2))
).
Some more auxiliary stuff:
listHasMember_identicalTo([X|Xs],Y) :-
( X == Y
-> true
; listHasMember_identicalTo(Xs,Y)
).
list_vars_excluded([],_,[]).
list_vars_excluded([X|Xs],Vs,Zs) :-
( listHasMember_identicalTo(Vs,X)
-> Zs = Zs0
; Zs = [X|Zs0]
),
list_vars_excluded(Xs,Vs,Zs0).
Let's have some tests (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
Changed the implementation of lt/2 to use T_alpha and T_omega, not two fresh variables.
lt(X,Y) makes two copies of X (X1 and X2) and two copies of Y (Y1 and Y2).X and Y are also shared by X1 and Y1, and by X2 and Y2.T_alpha comes before all other terms (in X1, X2, Y1, Y2) w.r.t. the standard order.T_omega comes after all other terms in the standard order.X but not in Y (and vice versa) are unified with T_alpha / T_omega.
Now, the counterexample given by @false works:
?- lt(X+1,1+2).
uncaught exception: error(instantiation_error,lt/2)
?- X=2, lt(X+1,1+2).
no