projog

3.32. predsort(X,Y,Z) - sorts a list using the specified predicate.

Sorts the list represented by Y using the predicate represented by X - and attempts to unify the result with Z. The predicate represented by X must indicate whether the second argument is equal, less than or greater than the third argument - by unifying the first argument with an atom which has the value =, < or >.

Examples

?- predsort(compare, [s,d,f,a,a,a,z], X).
X = [a,a,a,d,f,s,z]

yes

?- predsort(compare, [s,d,f,a,a,a,z], [a,a,a,d,f,s,z]).

yes

?- predsort(compare, [s,d,f,a,a,a,z], [s,d,f,a,a,a,z]).

no

?- predsort(compare, [], []).

yes

compare_desc(X,Y,Z) :- Y@<Z, X='>'.
compare_desc(X,Y,Z) :- Y@>Z, X='<'.
compare_desc(X,Y,Z) :- Y==Z, X='='.

compare_desc(asc,X,Y,Z) :- Y@<Z, X='>'.
compare_desc(asc,X,Y,Z) :- Y@>Z, X='<'.
compare_desc(asc,X,Y,Z) :- Y==Z, X='='.
compare_desc(desc,X,Y,Z) :- Y@<Z, X='<'.
compare_desc(desc,X,Y,Z) :- Y@>Z, X='>'.
compare_desc(desc,X,Y,Z) :- Y==Z, X='='.

?- predsort(compare_desc, [s,d,f,a,a,a,z], X).
X = [z,s,f,d,a,a,a]

yes

Note: This behaviour is different than the SWI version. SWI version removes duplicates.

?- predsort(compare_desc(asc), [s,d,f,a,a,a,z], X).
X = [z,s,f,d,a,a,a]

yes

compare_retryable('>',_,_).
compare_retryable('<',_,_).
compare_retryable('=',_,_).

Note: This behaviour is different than the SWI version. SWI version backtracks to find alternative solutions.

?- predsort(compare_retryable, [s,z], X).
X = [s,z]

yes