Bug 5894 – [patch] std.algorithm.isSorted doesn't handle monotonicity (i.e. "<=")

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2011-04-26T13:24:00Z
Last change time
2015-06-09T05:13:48Z
Assigned to
nobody
Creator
sandford

Comments

Comment #0 by sandford — 2011-04-26T13:24:14Z
I was trying to use isSorted to check for monotonicity. For example, [1,2,2,3] is monotonically increasing, but not strictly increasing. I was therefore trying to use isSorted!"a <= b"( [1,2,2,3] ), which failed. Looking at the implementation of isSorted: bool isSorted(alias less = "a < b", Range)(Range r) if (isForwardRange!(Range)) { // @@@BUG@@@ Should work with inlined predicate bool pred(ElementType!Range a, ElementType!Range b) { return binaryFun!less(b, a); } return findAdjacent!pred(r).empty; } which would attempts to validate that all pairs in r conform to "a <= b" by not finding any "b <= a" pairs, which isn't logically correct. I've written a one-line patch below to fix this error. It changes the test from not finding "b <= a" pairs to not finding !"a <= b" pairs (i.e. any pairs ! conforming to the predicate). bool isSorted(alias less = "a < b", Range)(Range r) if (isForwardRange!(Range)) { // @@@BUG@@@ Should work with inlined predicate bool pred(ElementType!Range a, ElementType!Range b) { + return !binaryFun!less(a, b); - return binaryFun!less(b, a); } return findAdjacent!pred(r).empty; }
Comment #1 by andrei — 2011-04-26T15:06:14Z
isSorted!pred assesses whether the range has been sorted by using pred. So what you want is isSorted!"a < b", which will pass [1, 2, 2, 3]. The bug would stand if adjancentFind!"a <= b" would fail.
Comment #2 by sandford — 2011-04-26T18:59:03Z
Thank you for the clarification. I was definitely confused by the docs on this. What I read was, isSorted tested to see if all element pairs obeyed the predicate, whereas what it actually tests in whether the range conforms to what a range sorted by the predicate would be like.