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
Third try! Developed and tested with GNU Prolog 1.4.4.
Exhibit 'A': "as simple as it gets"
lt(X,Y) :-
X \== Y,
( X \= Y
-> alpha_omega(Alpha,Omega),
term_variables(X+Y,Vars), % A
\+ \+ (label_vars(Vars,Alpha,Omega), X @< Y),
( \+ (label_vars(Vars,Alpha,Omega), X @> Y)
-> true
; throw(error(instantiation_error,lt/2))
)
; throw(error(instantiation_error,lt/2))
).
Exhibit 'B': "no need to label all vars"
lt(X,Y) :-
X \== Y,
( X \= Y
-> alpha_omega(Alpha,Omega),
term_variables(X,Xvars), % B
term_variables(Y,Yvars), % B
vars_vars_needed(Xvars,Yvars,Vars), % B
\+ \+ (label_vars(Vars,Alpha,Omega), X @< Y),
( \+ (label_vars(Vars,Alpha,Omega), X @> Y)
-> true
; throw(error(instantiation_error,lt/2))
)
; throw(error(instantiation_error,lt/2))
).
vars_vars_needed([], [], []).
vars_vars_needed([A|_], [], [A]).
vars_vars_needed([], [B|_], [B]).
vars_vars_needed([A|As],[B|Bs],[A|ABs]) :-
( A \== B
-> ABs = [B]
; vars_vars_needed(As,Bs,ABs)
).
Some shared code:
alpha_omega(Alpha,Omega) :-
Alpha is -(10.0^1000), % HACK!
functor(Omega,z,255). % HACK!
label_vars([],_,_).
label_vars([Alpha|Vs],Alpha,Omega) :- label_vars(Vs,Alpha,Omega).
label_vars([Omega|Vs],Alpha,Omega) :- label_vars(Vs,Alpha,Omega).