<div class="notebook">
<div class="nb-cell program">
'slow quick and dirty'(S0, S) :-
setof(C, R^(select(C,S0,R),member(C,R)), S).
'better quick and dirty'(S0, S) :-
setof(C, R^(select(C,S0,R),memberchk(C,R)), S).
'still better quick and dirty'(S0, S) :-
setof(H, Done^H^R^(append(Done,[H|R],S0),memberchk(H,R)), S).
test(N) :-
H is N/2,
findall(R, (between(1,N,_), random_between(1,H,R)), S),
%time('slow quick and dirty'(S, Sa)),
time('better quick and dirty'(S, Sb)),
time('still better quick and dirty'(S, Sc)),
Sa = Sb, Sb = Sc,
time(remove_uniq1(S, Sd)),
time(remove_uniq2(S, Se)),
maplist(length, [Sa, Sb, Sc, Sd, Se], Ls),
writeln(Ls).
% same_length(S, Sc). % ( Sort -> sort(Sc, Sa) ; true ).
remove_uniq1([], []).
remove_uniq1([E|Es], Xs0) :-
tpartition1(=(E), Es, Ts, Fs),
if_(Ts = [], Xs0 = Xs, Xs0 = [E|Xs]),
remove_uniq1(Fs, Xs).
tpartition1(P_2,List,Ts,Fs) :-
tpartition1_ts_fs_(List,Ts,Fs,P_2).
tpartition1_ts_fs_([],[],[],_).
tpartition1_ts_fs_([X|Xs0],Ts,Fs,P_2) :-
if_(call(P_2,X), (Ts = [X|Ts0], Fs = Fs0),
(Ts = Ts0, Fs = [X|Fs0])),
tpartition1_ts_fs_(Xs0,Ts0,Fs0,P_2).
%%%
remove_uniq2([], []).
remove_uniq2([E|Es], Xs0) :-
tpartition2(=(E), Es, Ts, Fs),
if_(Ts = [], Xs0 = Xs, Xs0 = [E|Xs]),
remove_uniq2(Fs, Xs).
tpartition2(P_2,List,Ts,Fs) :-
tpartition2_ts_fs_(List,Ts,Fs,P_2).
tpartition2_ts_fs_([],[],[],_).
tpartition2_ts_fs_([X|Xs0],Ts,Fs,P_2) :-
call(P_2,X,Truth),
( Truth == true -> Ts = [X|Ts0], Fs = Fs0
; Ts = Ts0, Fs = [X|Fs0]
),
tpartition2_ts_fs_(Xs0,Ts0,Fs0,P_2).
%%%
if_(If_1, Then_0, Else_0) :-
call(If_1, T),
( T == true -> call(Then_0)
; T == false -> call(Else_0)
; nonvar(T) -> throw(error(type_error(boolean,T),_))
; /* var(T) */ throw(error(instantiation_error,_))
).
=(X, Y, T) :-
( X == Y -> T = true
; X \= Y -> T = false
; T = true, X = Y
; T = false,
dif(X, Y) % ISO extension
% throw(error(instantiation_error,_)) % ISO strict
).
</div>
<div class="nb-cell query">
remove_uniq2([c,b,a,a,b,c,a,b,c],Xs).
</div>
<div class="nb-cell query" data-tabled="true">
test(10000).
</div>
</div>