Here is a relatively cheap compare for cyclic terms that satisfies the
laws, except lexical order. It is based on the idea to define:
S @<' T :<=> rep(S) @< rep(T)
The only requirement to the function rep is that it is injective,
then the laws, except for lexical order, are automatically satisfied.
BTW: By lexical order we mean the requirement:
(X1,Y1) @< (X2,Y2) <=> X1 @< X2 \/ (X1 == X2 /\ Y1 @< Y2)
Appeal to the above makes Mats Carlson pair appear leading
to an inconsistency. But the the law is not part of total order.
BTW: Example representation that can be used is naish/2
:
naish(X, Y) :-
naish([], X, Y).
naish(S, X, Y) :- compound(X),
member(Z-Y, S), X == Z, !.
naish(S, X, Y) :- compound(X), !,
length(S, N),
X =.. [F|L],
maplist(naish([X-'$IDX'(N)|S]), L, R),
Y =.. [F|R].
naish(_, X, X).
This gives a total ordering and is also conservative.