make predsort a system predicate.

This commit is contained in:
Vítor Santos Costa II 2010-04-20 23:49:14 +01:00
parent b0f20ea8c5
commit 2566ebcee5
3 changed files with 53 additions and 56 deletions

View File

@ -3743,6 +3743,16 @@ would return:
S = [1-b,1-a,1-b,2-c,3-a]
@end example
@item predsort(+@var{Pred}, +@var{List}, -@var{Sorted})
@findex predsort/3
@snindex predsort/3
@cnindex predsort/3
Sorts similar to sort/2, but determines the order of two terms by
calling @var{Pred}(-@var{Delta}, +@var{E1}, +@var{E2}) . This call must
unify @var{Delta} with one of @code{<}, @code{>} or @code{=}. If
built-in predicate compare/3 is used, the result is the same as
sort/2.
@item length(?@var{L},?@var{S})
@findex length/2
@syindex length/2

View File

@ -137,62 +137,6 @@ user:file_search_path(foreign, swi(ArchLib)) :-
atom_concat('lib/', Arch, ArchLib).
user:file_search_path(foreign, swi(lib)).
:- meta_predicate prolog:predsort(:,+,-).
prolog:plus(X, Y, Z) :-
integer(X),
integer(Y), !,
Z is X + Y.
prolog:plus(X, Y, Z) :-
integer(X),
integer(Z), !,
Y is Z - X.
prolog:plus(X, Y, Z) :-
integer(Y),
integer(Z), !,
X is Z - Y.
%% predsort(:Compare, +List, -Sorted) is det.
%
% Sorts similar to sort/2, but determines the order of two terms
% by calling Compare(-Delta, +E1, +E2). This call must unify
% Delta with one of <, > or =. If built-in predicate compare/3 is
% used, the result is the same as sort/2. See also keysort/2.
prolog:predsort(P, L, R) :-
length(L, N),
predsort(P, N, L, _, R1), !,
R = R1.
predsort(P, 2, [X1, X2|L], L, R) :- !,
call(P, Delta, X1, X2),
sort2(Delta, X1, X2, R).
predsort(_, 1, [X|L], L, [X]) :- !.
predsort(_, 0, L, L, []) :- !.
predsort(P, N, L1, L3, R) :-
N1 is N // 2,
plus(N1, N2, N),
predsort(P, N1, L1, L2, R1),
predsort(P, N2, L2, L3, R2),
predmerge(P, R1, R2, R).
sort2(<, X1, X2, [X1, X2]).
sort2(=, X1, _, [X1]).
sort2(>, X1, X2, [X2, X1]).
predmerge(_, [], R, R) :- !.
predmerge(_, R, [], R) :- !.
predmerge(P, [H1|T1], [H2|T2], Result) :-
call(P, Delta, H1, H2),
predmerge(Delta, P, H1, H2, T1, T2, Result).
predmerge(>, P, H1, H2, T1, T2, [H2|R]) :-
predmerge(P, [H1|T1], T2, R).
predmerge(=, P, H1, _, T1, T2, [H1|R]) :-
predmerge(P, T1, T2, R).
predmerge(<, P, H1, H2, T1, T2, [H1|R]) :-
predmerge(P, T1, [H2|T2], R).
%
% maybe a good idea to eventually support this in YAP.

View File

@ -53,3 +53,46 @@ msort(L,O) :-
keysort(L,O) :-
'$keysort'(L,O).
:- meta_predicate prolog:predsort(:,+,-).
%% predsort(:Compare, +List, -Sorted) is det.
%
% Sorts similar to sort/2, but determines the order of two terms
% by calling Compare(-Delta, +E1, +E2). This call must unify
% Delta with one of <, > or =. If built-in predicate compare/3 is
% used, the result is the same as sort/2. See also keysort/2.
predsort(P, L, R) :-
length(L, N),
predsort(P, N, L, _, R1), !,
R = R1.
predsort(P, 2, [X1, X2|L], L, R) :- !,
call(P, Delta, X1, X2),
sort2(Delta, X1, X2, R).
predsort(_, 1, [X|L], L, [X]) :- !.
predsort(_, 0, L, L, []) :- !.
predsort(P, N, L1, L3, R) :-
N1 is N // 2,
plus(N1, N2, N),
predsort(P, N1, L1, L2, R1),
predsort(P, N2, L2, L3, R2),
predmerge(P, R1, R2, R).
sort2(<, X1, X2, [X1, X2]).
sort2(=, X1, _, [X1]).
sort2(>, X1, X2, [X2, X1]).
predmerge(_, [], R, R) :- !.
predmerge(_, R, [], R) :- !.
predmerge(P, [H1|T1], [H2|T2], Result) :-
call(P, Delta, H1, H2),
predmerge(Delta, P, H1, H2, T1, T2, Result).
predmerge(>, P, H1, H2, T1, T2, [H2|R]) :-
predmerge(P, [H1|T1], T2, R).
predmerge(=, P, H1, _, T1, T2, [H1|R]) :-
predmerge(P, T1, T2, R).
predmerge(<, P, H1, H2, T1, T2, [H1|R]) :-
predmerge(P, T1, [H2|T2], R).