%      Production system KORE/IE (version 12.48)
%
%          (C)1992 Institute for New Generation Computer Technology
%                          (Read COPYRIGHT for detailed information)
%
%      1992.7 Check and refine every programs 
%                             for IFS (ICOT Free Software) release.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% SPEEDY SORT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
 # speedy_sort --- sort elements in list into specyfied order, ascending
		   standard order or descending standard order in PROLOG.
		   This sort is quicker than C_PROLOG system's sort.
	USAGE: speedy_sort(Flag,List,Result).
		* Flag   ::= When sorting is done in ascending standard
			     order, this argument is "a". When descending
			     standard order, select "d".
		* List   ::= List of Elements to be sorted
		* Result ::= List of Elements to have sorted
*/

%%%%% SPEEDY_SORT
speedy_sort(a,L,R) :-
	LENGTH =.. [f|L],
	functor(LENGTH,_,N),
%	length(L,N),
	speedy_sorting_ascending_order(N,L,_,R),
	!.
speedy_sort(d,L,R) :-
	LENGTH =.. [f|L],
	functor(LENGTH,_,N),
%	length(L,N),
	speedy_sorting_descending_order(N,L,_,R),
	!.

%%%%% speedy_sorting_ascending_order
speedy_sorting_ascending_order(2,[X1,X2|L],L,R) :-
	!,
	compare(Delta,X1,X2),
	s_s_m_a_o(Delta,X1,X2,R).
speedy_sorting_ascending_order(1,[X|L],L,[X]) :-
	!.
speedy_sorting_ascending_order(0,L,L,[]) :-
	!.
speedy_sorting_ascending_order(N,L1,L3,R) :-
	N1 is N // 2,
	N2 is N - N1,
	speedy_sorting_ascending_order(N1,L1,L2,R1),
	speedy_sorting_ascending_order(N2,L2,L3,R2),
	speedy_sort_merge_ascending_order(R1,R2,R).

%%%%% speedy_sort_merge_ascending_order
speedy_sort_merge_ascending_order([X1|R1a],[X2|R2a],[X|R]) :-
	compare(Delta,X1,X2),
	s_s_m_a_o(Delta,X,X1,X2,R1a,R2a,R).
speedy_sort_merge_ascending_order([],R,R) :-
	!.
speedy_sort_merge_ascending_order(R,[],R) :-
	!.

%%%%% s_s_m_a_o/4
s_s_m_a_o(<,X1,X2,[X1,X2]) :-
	!.
s_s_m_a_o(_,X1,X2,[X2,X1]) :-
	!.

%%%%% s_s_m_a_o/7
s_s_m_a_o(<,X1,X1,X2,R1a,R2a,R) :-
	speedy_sort_merge_ascending_order(R1a,[X2|R2a],R).
s_s_m_a_o(_,X2,X1,X2,R1a,R2a,R) :-
	speedy_sort_merge_ascending_order([X1|R1a],R2a,R).

%%%%% speedy_sorting_descending_order
speedy_sorting_descending_order(2,[X1,X2|L],L,R) :-
	!,
	compare(Delta,X1,X2),
	s_s_m_d_o(Delta,X1,X2,R).
speedy_sorting_descending_order(1,[X|L],L,[X]) :-
	!.
speedy_sorting_descending_order(0,L,L,[]) :-
	!.
speedy_sorting_descending_order(N,L1,L3,R) :-
	N1 is N // 2,
	N2 is N - N1,
	speedy_sorting_descending_order(N1,L1,L2,R1),
	speedy_sorting_descending_order(N2,L2,L3,R2),
	speedy_sort_merge_descending_order(R1,R2,R).

%%%%% speedy_sort_merge_descending_order
speedy_sort_merge_descending_order([X1|R1a],[X2|R2a],[X|R]) :-
	compare(Delta,X1,X2),
	s_s_m_d_o(Delta,X,X1,X2,R1a,R2a,R).
speedy_sort_merge_descending_order([],R,R) :-
	!.
speedy_sort_merge_descending_order(R,[],R) :-
	!.

%%%%% s_s_m_d_o/4
s_s_m_d_o(>,X1,X2,[X1,X2]) :-
	!.
s_s_m_d_o(_,X1,X2,[X2,X1]) :-
	!.

%%%%% s_s_m_d_o/7
s_s_m_d_o(>,X1,X1,X2,R1a,R2a,R) :-
	speedy_sort_merge_descending_order(R1a,[X2|R2a],R).
s_s_m_d_o(_,X2,X1,X2,R1a,R2a,R) :-
	speedy_sort_merge_descending_order([X1|R1a],R2a,R).

