30static void simple_mergesort(CELL *, Int,
int);
31static Int compact_mergesort(CELL *, Int,
int);
32static int key_mergesort(CELL *, Int,
int,
Functor);
33static void adjust_vector(CELL *, Int);
34static Int p_sort( USES_REGS1 );
35static Int p_msort( USES_REGS1 );
36static Int p_ksort( USES_REGS1 );
41void simple_mergesort(CELL *pt, Int size,
int my_p)
45 Int half_size = size / 2;
46 CELL *pt_left, *pt_right, *end_pt, *end_pt_left;
49 pt_right = pt + half_size*2;
52 simple_mergesort(pt, half_size, left_p);
53 simple_mergesort(pt_right, size-half_size, right_p);
59 end_pt_left = pt+half_size*2;
67 while (pt_left < end_pt_left && pt_right < end_pt) {
69 if (Yap_compare_terms(pt_left[0], pt_right[0]) <= 0) {
83 while (pt_left < end_pt_left) {
90 if (my_p != right_p) {
91 while(pt_right < end_pt) {
98 if (size > 1 && (Yap_compare_terms(pt[0],pt[2]) > 0)) {
112int key_mergesort(CELL *pt, Int size,
int my_p,
Functor FuncDMinus)
116 Int half_size = size / 2;
117 CELL *pt_left, *pt_right, *end_pt, *end_pt_left;
120 pt_right = pt + half_size*2;
123 if (!key_mergesort(pt, half_size, left_p, FuncDMinus))
125 if (!key_mergesort(pt_right, size-half_size, right_p, FuncDMinus))
130 end_pt = pt + 2*size;
132 end_pt_left = pt+half_size*2;
140 while (pt_left < end_pt_left && pt_right < end_pt) {
142 Term t0 = pt_left[0] , t1 = pt_right[0];
143 if (IsVarTerm(t0) || !IsApplTerm(t0) || FunctorOfTerm(t0) != FuncDMinus)
145 t0 = ArgOfTerm(1,t0);
146 if (IsVarTerm(t1) || !IsApplTerm(t1) || FunctorOfTerm(t1) != FuncDMinus)
148 t1 = ArgOfTerm(1,t1);
149 if (Yap_compare_terms(t0, t1) <= 0) {
163 while (pt_left < end_pt_left) {
170 if (my_p != right_p) {
171 while(pt_right < end_pt) {
179 Term t0 = pt[0], t1 = pt[2];
180 if (IsVarTerm(t0) || !IsApplTerm(t0) || FunctorOfTerm(t0) != FuncDMinus)
182 t0 = ArgOfTerm(1,t0);
183 if (IsVarTerm(t1) || !IsApplTerm(t1) || FunctorOfTerm(t1) != FuncDMinus)
185 t1 = ArgOfTerm(1,t1);
186 if (Yap_compare_terms(t0,t1) > 0) {
204Int compact_mergesort(CELL *pt, Int size,
int my_p)
208 Int half_size = size / 2;
209 CELL *pt_left, *pt_right, *end_pt_right, *end_pt_left;
213 pt_right = pt + half_size*2;
216 lsize = compact_mergesort(pt, half_size, left_p);
217 rsize = compact_mergesort(pt_right, size-half_size, right_p);
223 end_pt_left = pt+2*lsize;
227 end_pt_right = pt_right + 2*rsize;
232 while (pt_left < end_pt_left && pt_right < end_pt_right) {
234 Int cmp = Yap_compare_terms(pt_left[0], pt_right[0]);
242 }
else if (cmp == (Int)0) {
254 while (pt_left < end_pt_left) {
262 while(pt_right < end_pt_right) {
269 }
else if (size == 2) {
270 Int cmp = Yap_compare_terms(pt[0],pt[2]);
277 }
else if (cmp == 0) {
297adjust_vector(CELL *pt, Int size)
299 CELL *ptf = pt + 2*(size-1);
302 pt[0] = AbsPair(pt+1);
311static ssize_t prepare(Term t)
318 Yap_ThrowError( INSTANTIATION_ERROR, t,
"sort");
322 ssize_t size = Yap_SkipList(&t,&r);
323 if (size < 0 || r[0] != TermNil) {
324 if (IsVarTerm(r[0])) {
325 Yap_ThrowError( INSTANTIATION_ERROR, r[0],
"sort");
328 if (r[0] != TermNil) {
329 Yap_ThrowError( TYPE_ERROR_LIST, t0,
"sort");
333 while (ASP-HR < 2*size+4096) {
334 yhandle_t yt = Yap_InitHandle(t);
335 if (!Yap_dogcl(3*size*
sizeof(CELL))) {
336 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, NULL);
339 t = Yap_GetFromHandle(yt);
343 for (i=0;i<size;i++) {
344 *HR++ = HeadOfTerm(t);
352Term Yap_MergeSort(Term l USES_REGS)
355 ssize_t size = prepare(l);
363 simple_mergesort(pt, size, M_EVEN);
364 adjust_vector(pt, size);
370Term Yap_SortList(Term l USES_REGS)
373 ssize_t size = prepare(l);
382 compact_mergesort(pt, size, M_EVEN);
383 adjust_vector(pt, size);
393 ssize_t size = prepare(Deref(ARG1));
396 return(Yap_unify(ARG1, ARG2));
398 CELL *pt = HR-2*size;
401 size = compact_mergesort(pt, size, M_EVEN);
402 adjust_vector(pt, size);
404 return(Yap_unify(out, ARG2));
411 ssize_t size = prepare(Deref(ARG1));
414 return(Yap_unify(ARG1, ARG2));
416 CELL *pt = HR-2*size;
419 simple_mergesort(pt, size, M_EVEN);
420 adjust_vector(pt, size);
422 return(Yap_unify(out, ARG2));
430 ssize_t size = prepare(Deref(ARG1));
433 return(Yap_unify(ARG1, ARG2));
435 CELL *pt = HR-2*size;
436 if (!key_mergesort(pt, size, M_EVEN, FunctorMinus))
438 adjust_vector(pt, size);
440 return(Yap_unify(out, ARG2));
444Yap_InitSortPreds(
void)
446 Yap_InitCPred(
"$sort", 2, p_sort, 0);
447 Yap_InitCPred(
"$msort", 2, p_msort, 0);
448 Yap_InitCPred(
"$keysort", 2, p_ksort, 0);