Search code examples
prologclpfd

Constraint predicate not starting with the maximum value


I'm trying to get a match for the sum of the first Y elements of a certain list, for Y in the 1..10 range, and for the maximum of the sum. I would like the first match to be Res=10,Y=10, but it is just giving answers starting from Y=1, and increasing to Y=10. What am I missing here?

get_max(Res,Y):-
        Y in 1..10,
        add_list([1,1,1,1,1,1,1,1,1,1],Y,0,Res),
        labeling([max(Y)],[Y,Res]).

add_list(_,0,Res,Res).
add_list([H|Rest],C,Temp,Final):-
        NewTemp #= H+Temp,
        NewC #= C-1,
        add_list(Rest,NewC,NewTemp,Final).

?- get_max(Res,Y).
Res = Y, Y = 1 ;
Res = Y, Y = 2 ;
Res = Y, Y = 3 ;
Res = Y, Y = 4 ;
Res = Y, Y = 5 ;
Res = Y, Y = 6 ;
Res = Y, Y = 7 ;
Res = Y, Y = 8 ;
Res = Y, Y = 9 ;
Res = Y, Y = 10.

Solution

  • You could force labeling/2 to take effect swapping the goals in this way:

    get_max(Res,Y):-
            [Y,Res] ins 1..10,
            labeling([max(Y)],[Y,Res]),
            add_list([1,1,1,1,1,1,1,1,1,1],Y,0,Res).
    
    ?- get_max(Res,Y).
    Res = Y, Y = 10 ;
    Res = Y, Y = 9 .
    

    but this requires the declaration on Res' domain as well.

    To be true, seems more a bug than a feature. After all, the solution order should be as you declared, as advertised by library(clpfd). Otherwise, the clauses' order again come back to bite us...