mndrix / list_util

Prolog list utility predicates
The Unlicense
11 stars 5 forks source link

Unexpected behaviour for minimum_with/3. #31

Open jamesnvc opened 6 years ago

jamesnvc commented 6 years ago

Currently, if multiple elements in the list project to the same value, it will return the minimum of those set of values. For example,

Current behavior:

?- minimum_with(length, [[b], [a]], M)
M = [a]

I would expect that the element that comes first in the list would be the one selected, e.g.

?- minimum_with(length, [[b], [a]], M)
M = [b]

I am not sure the current behavior is necessarily "wrong", but I did find it somewhat unexpected. While it is somewhat justifiable, I find it makes the predicate less flexible, since if it just returned the first minimum value, I can pre-sort the list according to some other criteria and thereby control which minimum value will be returned.

This behavior happens because the predicate uses minimum_by with compare as the comparator, meaning it compares based on the entire pair, not just the projected value. I was able to get the behavior I was looking for by implementing minimum_with as follows

minimum_with(Project, List, Minimum) :-
    map_list_to_pairs(Project, List, Pairs),
    minimum_by([O, T1-_, T2-_]>>compare(O, T1, T2), Pairs, _-Minimum).

(using a lambda for the compare function, but the idea being to just compare on the projected values).

mndrix commented 6 years ago

Your expectation seems reasonable. I'll certainly consider patches if that's something you're interested in.

I suppose it might also be reasonable to iterate different minimums on backtracking, although I'm not sure whether that's useful or not.