Search code examples
prologminclpfd

Counter-intuitive behavior of min_member/2


min_member(-Min, +List)

True when Min is the smallest member in the standard order of terms. Fails if List is empty.

?- min_member(3, [1,2,X]).
X = 3.

The explanation is of course that variables come before all other terms in the standard order of terms, and unification is used. However, the reported solution feels somehow wrong.

How can it be justified? How should I interpret this solution?

EDIT:

One way to prevent min_member/2 from succeeding with this solution is to change the standard library (SWI-Prolog) implementation as follows:

xmin_member(Min, [H|T]) :-
    xmin_member_(T, H, Min).

xmin_member_([], Min0, Min) :-
    (   var(Min0), nonvar(Min)
    ->  fail
    ;   Min = Min0
    ).
xmin_member_([H|T], Min0, Min) :-
    (   H @>= Min0 
    ->  xmin_member_(T, Min0, Min)
    ;   xmin_member_(T, H, Min)
    ).

The rationale behind failing instead of throwing an instantiation error (what @mat suggests in his answer, if I understood correctly) is that this is a clear question:

"Is 3 the minimum member of [1,2,X], when X is a free variable?"

and the answer to this is (to me at least) a clear "No", rather than "I can't really tell."

This is the same class of behavior as sort/2:

?- sort([A,B,C], [3,1,2]).
A = 3,
B = 1,
C = 2.

And the same tricks apply:

?- min_member(3, [1,2,A,B]).
A = 3.

?- var(B), min_member(3, [1,2,A,B]).
B = 3.

Solution

  • This is a common property of many (all?) predicates that depend on the standard order of terms, while the order between two terms can change after unification. Baseline is the conjunction below, which cannot be reverted either:

    ?- X @< 2, X = 3.
    X = 3.
    

    Most predicates using a -Value annotation for an argument say that pred(Value) is the same as pred(Var), Value = Var. Here is another example:

    ?- sort([2,X], [3,2]).
    X = 3.
    

    These predicates only represent clean relations if the input is ground. It is too much to demand the input to be ground though because they can be meaningfully used with variables, as long as the user is aware that s/he should not further instantiate any of the ordered terms. In that sense, I disagree with @mat. I do agree that constraints can surely make some of these relations sound.