As for the original comparable/3, it was strange for me why it didn’t work for a certain cases. I suspeted that codes using append/3
is the cause of looping. So I rewrote the comparable so that it does not extend lists arguments by append, which is suggested by the Konig lemma for termination of the comarable for cycic terms (infinite trees).
Fortunately, as far as I have tested, queries posted in this thread have been passed. Moreover, this version returns multiple outputs, which seems verifiable
with the striking comments posted by J.Burse, though
I am not familiar with order relation over cyclic terms.
Anyway, this version is at most a proto-type, which is far and far from final solution.
% ?- X=f(X,a(X)), Y=f(Y,b(Y)), Z=f(Y,c(Y)),
% lazy_compare(A,X,Y), lazy_compare(B,Y,Z), lazy_compare(C,X,Z).
%@ X = f(X, a(X)),
%@ Y = f(Y, b(Y)),
%@ Z = f(Y, c(Y)),
%@ A = B, B = C, C = (<) ;
%@ X = f(X, a(X)),
%@ Y = f(Y, b(Y)),
%@ Z = f(Y, c(Y)),
%@ A = B, B = (<),
%@ C = (>) ;
%@ X = f(X, a(X)),
%@ Y = f(Y, b(Y)),
%@ Z = f(Y, c(Y)),
%@ A = (>),
%@ B = C, C = (<) ;
%@ X = f(X, a(X)),
%@ Y = f(Y, b(Y)),
%@ Z = f(Y, c(Y)),
%@ A = C, C = (>),
%@ B = (<).
qassoc(A-B, [C-D|_]):- A == C, !, B = D.
qassoc(H, [_|R]):- qassoc(H, R).
%
lazy_compare(C, X, Y) :-
( C == = -> X = Y
; X == Y -> C = (=)
; when((ground(X), ground(Y)), compare_ground(C, X, Y, []))
).
%
compare_ground(C, X, Y, P):-
( X == Y -> C = (=)
; (atomic(X); atomic(Y)) -> compare(C, X, Y)
; memberchk(p(X, Y)-D, P) ->
C = D,
member(C, [<,>])
; functor(X, F, N),
functor(Y, G, M),
compare(D, N, M),
( D == (=) ->
compare(E, F, G),
( E == (=) ->
X=..[_|Xs],
Y=..[_|Ys],
compare_ground_list(C, Xs, Ys, [p(X, Y)-C|P])
; C = E
)
; C = D
)
).
%
compare_ground_list(C, [], [], _):-!, C = (=).
compare_ground_list(C, [X|Xs], [Y|Ys], P):-compare_ground(D, X, Y, P),
( var(D) -> member(C, [<, >])
; D = (=) -> compare_ground_list(C, Xs, Ys, P)
; C = D
).