Reputation: 53
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.
Upvotes: 1
Views: 63
Reputation: 60004
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...
Upvotes: 1
Reputation: 9378
?- add_list([1,1,1,1], Y, 0, Res).
Y = Res, Res = 0 ;
Y = Res, Res = 1 ;
Y = Res, Res = 2 ;
Y = Res, Res = 3 ;
Y = Res, Res = 4.
This goal enumerates values for Y
and Res
in this order. Labeling is not needed because the values are sufficiently determined. Later labeling also cannot force a different order once this goal enumerates the solutions like this.
(Also, if all you want to do is sum a list, you don't need this many arguments to the predicate. If you named them better, you might also see this. Your C
had better be named UselessCounterFromZeroTowardsNegativeInfinity
. Then you could eliminate it.)
Upvotes: 1