REBOL3 tracker
  0.9.12 beta
Ticket #0001152 User: anonymous

Project:



rss
TypeBug Statusbuilt Date26-Jul-2009 20:47
Versionalpha 76 CategoryNative Submitted byBrianH
PlatformAll Severityminor Prioritynormal

Summary SORT not stable (order not preserved)
Description In this case, I am not referring to the stability of the function itself, but to whether the sorting algorithm is stable. When SORT finds two values that it considers equal, it reverses them in the results. Somewhere in SORT a < should be a <=, or something like that.
Example code
; Case-insensitive comparison - values are considered equal
>> sort ["A" "a"]
== ["a" "A"]  ; should be ["A" "a"]
>> sort ["a" "A"]
== ["A" "a"]  ; should be ["a" "A"]

; Case-sensitive comparison - values are considered different
>> sort/case ["a" "A"]
== ["A" "a"]  ; good
>> sort/case ["A" "a"]
== ["A" "a"]  ; good

; Verification using SAME?
>> set [c d] sort reduce [a: "a" b: "a"]
== ["a" "a"]
>> same? c a
== false  ; should be true
>> same? c b
== true  ; should be false
>> same? d a
== true  ; should be false
>> same? d b
== false  ; should be true

Assigned ton/a Fixed inr3 master Last Update18-Feb-2014 00:02


Comments
(0002967)
Ladislav
10-Dec-2010 21:39

Using /compare we may come to a conclusion, that SORT probably would be stable, if using an appropriate comparison operator:

; this example behaves like the version not using /compare, being unstable
>> sort/compare ["A" "a"] func [a b] [a < b]
== ["a" "A"]

; this example behaves like the version not using /compare, being unstable
>> sort/compare ["a" "A"] func [a b] [a < b]
== ["A" "a"]

; this example is stable
>> sort/compare ["A" "a"] func [a b] [a <= b]
== ["A" "a"]

; this exaple is stable
>> sort/compare ["a" "A"] func [a b] [a <= b]
== ["a" "A"]
(0002968)
abolka
10-Dec-2010 22:31

On A110 Linux, all test cases given in the example code succeed. Unfortunately, that result does not necessarily make this issue platform-specific. A quick trace shows that, at least on Linux, R3's SORT is using the C library's qsort() function. qsort() is, by definition, not stable. Quoting the C99 standard (7.22.5.2p4):

"If two elements compare as equal, their order in the resulting sorted array is unspecified."

This means (assuming that qsort() is used in Win32 R3 as well) that all effects we observed above are most likely purely coincidental, resulting from the underlying C library's implementation of qsort().

If we want SORT to be stable per default, there is a well-known hack for achieving that even with C's qsort():

"If you want the effect of a stable sort, you can get this result by writing the comparison function so that, lacking other reason distinguish between two elements, it compares them by their addresses. Note that doing this may make the sorting algorithm less efficient, so do it only if necessary."

(Quoted from the glibc documentation: http://www.gnu.org/s/libc/manual/html_node/Array-Sort-Function.html)

Alternatively, the implementation of SORT will have to forego qsort() and use a stable sort instead. Of course, maybe R3 is already employing that hack, and then this issue most likely really is a platform-specific bug.

For reference:

; RT R3 A110 Linux
>> sort/skip/compare [1 9 1 5 1 7] 2 1
== [1 9 1 5 1 7]

; RT R3 A110 Win32
>> sort/skip/compare [1 9 1 5 1 7] 2 1
== [1 7 1 9 1 5]
(0002969)
abolka
11-Dec-2010 20:39

in the core-tests suite
(0002971)
BrianH
12-Dec-2010 06:56

Gabriele pointed out in AltME that R2's SORT is stable, even on Windows, and testing bears that out.
(0004018)
Ladislav
26-Sep-2013 19:43

Fixed by https://github.com/rebol/rebol/pull/152

Date User Field Action Change
18-Feb-2014 00:02 BrianH Status Modified pending => built
18-Feb-2014 00:02 BrianH Fixedin Modified => r3 master
26-Sep-2013 19:56 Ladislav Status Modified reviewed => pending
26-Sep-2013 19:43 Ladislav Comment : 0004018 Added -
12-Dec-2010 06:56 BrianH Comment : 0002971 Added -
11-Dec-2010 20:39 abolka Comment : 0002969 Added -
11-Dec-2010 13:27 abolka Comment : 0002968 Modified -
11-Dec-2010 13:14 abolka Comment : 0002968 Modified -
10-Dec-2010 22:52 abolka Comment : 0002968 Modified -
10-Dec-2010 22:43 abolka Comment : 0002968 Modified -
10-Dec-2010 22:32 abolka Comment : 0002968 Modified -
10-Dec-2010 22:32 abolka Comment : 0002968 Modified -
10-Dec-2010 22:31 abolka Comment : 0002968 Modified -
10-Dec-2010 22:31 abolka Comment : 0002968 Modified -
10-Dec-2010 22:31 abolka Comment : 0002968 Added -
10-Dec-2010 21:50 BrianH Code Modified -
10-Dec-2010 21:39 Ladislav Comment : 0002967 Added -
3-Aug-2009 19:45 carl Status Modified submitted => reviewed
3-Aug-2009 19:45 carl Code Modified -
3-Aug-2009 19:45 carl Summary Modified SORT not stable => SORT not stable (order not preserved)
26-Jul-2009 20:47 BrianH Ticket Added -