On Tuesday, 12 November 2013 at 21:07:48 UTC, Andrei Alexandrescu wrote:
On 11/12/13 1:03 PM, tn wrote:
On Tuesday, 12 November 2013 at 20:03:37 UTC, Andrei Alexandrescu wrote:
Consider we define equiv(a, b) as (a, b) => !less(a, b) && !less(b, a).

If at least one of the numbers is NaN, all comparisons return false.
That puts NaN in the same equivalence class with all numbers,
including numbers that are deemed in distinct equivalence classes. That's where NaNs mess things up, and that's what we need to assert. Consider three numbers a, b, and c. Then the following must pass:

assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c));

("<=" on Booleans is actually implication.)

Shouldn't the implication be to the other direction? Then it becomes

assert((equiv(a, b) && equiv(b, c)) => equiv(a, c));

It is in the other direction, but the latter doesn't compile :o). Again, it just turns out "a <= b" has the meaning of "a implies b". It's not a particularly intuitive way to express it.

That test will fail with NaNs and should be part of isSorted, sort etc.

But it requires that the input contains at least three elements. And it has to test a lot of possible triples (a,b,c), which I think requires at least O(n^2) time. And it does not fail consistently whenever the input contains at least one NaN (consider an input that contains only NaNs).

I agree. Ideas?

If you want the isSorted function to always fail if the input contains NaNs, then I have no other ideas than what I have already mentioned. It is just not possible by using only "<" comparison. Something more is needed.

The other way would be to define isSorted to return true if and only if the _comparable_ elements in the input are sorted (thus ignoring possible NaNs in between). This is actually implementable with only "<" comparison, but probably requires O(n^2) time in the worst case.

Reply via email to