I have changed codes of compare_roughly/3
. The new codes compare_with_stack/3
,
which can be used instead of compare/3
for predsort
for a list of ground possiby cyclic terms.
It is still experimental, but for now I am seeing high possiblity that it could give one of final solutions to what disscussed in this thread.
I appreciate for any comment. The codes is short and hopefully clear.
compare_with_stack/3
is actually 4 value version of compare, <, =, >, and unstable.
% ?- compare_with_stack(C, a, a).
%@ C = (=).
% ?- A=f(A), compare_with_stack(C, A, A).
%@ A = f(A),
%@ C = (=).
% ?- A=f(A), B=f(B), compare_with_stack(C, A, B).
%@ A = B, B = f(B),
%@ C = (=).
% ?- A=f(A,0), B=f(B,1), compare_with_stack(C, A, B).
%@ A = f(A, 0),
%@ B = f(B, 1),
%@ C = (<).
% ?- A=f(B,0), B=f(A,1), compare_with_stack(C, A, B).
%@ A = f(f(A, 1), 0),
%@ B = f(A, 1),
%@ C = (>).
% ?- A=f(B,0), B=f(A,1), compare_with_stack(C, B, A).
%@ A = f(f(A, 1), 0),
%@ B = f(A, 1),
%@ C = (<).
% ?- A=f(A, 0), B=f(B, 1), C=f(C, 2), predsort(compare_with_stack, [A, B, C], R).
%@ A = f(A, 0),
%@ B = f(B, 1),
%@ C = f(C, 2),
%@ R = [f(A, 0), f(B, 1), f(C, 2)].
% ?- A=f(A, 0), B=f(B, 1), C=f(C, 2), predsort(compare_with_stack, [A, B, A, B, C, A], R).
%@ A = f(A, 0),
%@ B = f(B, 1),
%@ C = f(C, 2),
%@ R = [f(A, 0), f(B, 1), f(C, 2)].
% ?- A = _{bar:B,baz:0}, B = _{bar:A,baz:1}, compare_with_stack(X, A, B).
%@ A = _S1, % where
%@ _S1 = _S1{bar:_S2, baz:0},
%@ _S2 = _S2{bar:_S1, baz:1},
%@ B = _S2{bar:_S1, baz:1},
%@ X = (>).
% ?- H = H-9-7-6-5-4-3-2-1-0, Z = H-9-7-6-5-4-3-2-1,
% Y = Y-7-5-8-2-4-1, compare_with_stack(<, Z, Y).
%@ H = H-9-7-6-5-4-3-2-1-0,
%@ Z = H-9-7-6-5-4-3-2-1,
%@ Y = Y-7-5-8-2-4-1.
% ?- X = X-0-9-7-6-5-4-3-2-1, Y = Y-7-5-8-2-4-1, compare_with_stack(<, X, Y).
%@ X = X-0-9-7-6-5-4-3-2-1,
%@ Y = Y-7-5-8-2-4-1.
% ?- H = H-9-7-6-5-4-3-2-1-0, Z = H-9-7-6-5-4-3-2-1,
% Y = Y-7-5-8-2-4-1, compare_with_stack(<, Z, Y).
%@ H = H-9-7-6-5-4-3-2-1-0,
%@ Z = H-9-7-6-5-4-3-2-1,
%@ Y = Y-7-5-8-2-4-1.
compare_with_stack(C, X, Y):- compare_with_stack(C, X, Y, []).
%
compare_with_stack(C, X, Y, P):-
( X == Y -> C = (=)
; (atomic(X); atomic(Y)) -> compare(C, X, Y)
; memberchk(X-Y, P) -> C=(=)
; functor(X, F, N),
functor(Y, G, M),
compare(D, N, M),
( D == (=) ->
compare(E, F, G),
( E == (=) ->
X=..[_|Xs],
Y=..[_|Ys],
compare_with_stack_list(C, Xs, Ys, [X-Y|P])
; C = E
)
; C = D
)
).
%
compare_with_stack_list(C, [], [], _):-!, C = (=).
compare_with_stack_list(C, [X|Xs], [Y|Ys], P):-
compare_with_stack(D, X, Y, P),
( D = (=) -> compare_with_stack_list(C, Xs, Ys, P)
; C = D
).