1:- module(
2 sort_ext,
3 [
4 order_by2/2, 5 predmsort/3, 6 sort_stream/2, 7 sort_stream/3 8 ]
9).
15:- use_module(library(apply)). 16:- use_module(library(error)). 17:- use_module(library(process)). 18
19:- use_module(library(dict)). 20:- use_module(library(thread_ext)). 21
22:- meta_predicate
23 order_by2(+, 0),
24 predmerge(3, +, +, -),
25 predmerge(+, 3, +, +, -, -, -),
26 predmsort(3, +, -),
27 predmsort(3, ?, +, ?, -).
33order_by2([], Goal_0) :- !,
34 Goal_0.
35order_by2(Order, Goal_0) :-
36 order_by(Order, Goal_0).
44predmsort(P, L, R) :-
45 '$skip_list'(N, L, Tail),
46 (Tail == [] -> predmsort(P, N, L, _, R1), R = R1 ; must_be(L, list)).
47
48predmsort(P, 2, [X1,X2|L], L, R) :- !,
49 call(P, Delta, X1, X2),
50 msort_(Delta, X1, X2, R).
51predmsort(_, 1, [X|L], L, [X]) :- !.
52predmsort(_, 0, L, L, []) :- !.
53predmsort(P, N, L1, L3, R) :-
54 N1 is N // 2,
55 plus(N1, N2, N),
56 predmsort(P, N1, L1, L2, R1),
57 predmsort(P, N2, L2, L3, R2),
58 predmerge(P, R1, R2, R).
59
60msort_(<, X1, X2, [X1,X2]).
61msort_(=, X1, X2, [X1,X2]).
62msort_(>, X1, X2, [X2,X1]).
63
64predmerge(_, [], R, R) :- !.
65predmerge(_, R, [], R) :- !.
66predmerge(P, [H1|T1], [H2|T2], Result) :-
67 call(P, Delta, H1, H2), !,
68 predmerge(Delta, P, H1, H2, T1, T2, Result).
69
70predmerge(>, P, H1, H2, T1, T2, [H2|R]) :-
71 predmerge(P, [H1|T1], T2, R).
72predmerge(=, P, H1, H2, T1, T2, [H1,H2|R]) :-
73 predmerge(P, T1, T2, R).
74predmerge(<, P, H1, H2, T1, T2, [H1|R]) :-
75 predmerge(P, T1, [H2|T2], R).
120sort_stream(In, Out) :-
121 sort_stream(In, Out, []).
122
123
124sort_stream(In, Out, Options1) :-
125 dict_select(env, Options1, [], Options2, EnvT),
126 dict_select(utf8, Options2, false, Options3, Utf8),
127 (Utf8 == true -> Env = EnvT ; Env = ['LC_ALL'='C'|EnvT]),
128 maplist(sort_flag, Options3, Flags),
129 process_create(
130 path(sort),
131 Flags,
132 [env(Env),stdin(pipe(ProcIn)),stdout(pipe(Out))]
133 ),
134 create_detached_thread(
135 call_cleanup(
136 copy_stream_data(In, ProcIn),
137 close(ProcIn)
138 )
139 ).
140
142sort_flag(buffer_size(Size), Flag) :-
143 must_be(nonneg, Size),
144 format(atom(Flag), '--buffer-size=~d', [Size]).
146sort_flag(numeric(IsNumeric), '--numeric-sort') :-
147 must_be(boolean, IsNumeric),
148 IsNumeric == true.
150sort_flag(output(OutFileSpec), Flag) :-
151 absolute_file_name(OutFileSpec, OutFile, [access(write)]),
152 format(atom(Flag), '--output=~a', [OutFile]).
154sort_flag(threads(NumberOfThreads), Flag) :-
155 must_be(positive_integer, NumberOfThreads),
156 NumberOfThreads > 0,
157 format(atom(Flag), '--parallel=~d', [NumberOfThreads]).
159sort_flag(temporary_directory(Dir), Flag) :-
160 must_be(directory, Dir),
161 format(atom(Flag), '--temporary-directory=~a', [Dir]).
163sort_flag(duplicates(KeepDuplicates), '--unique') :-
164 must_be(boolean, KeepDuplicates),
165 KeepDuplicates == false
Supoort for sorting
*/