约束谓词不是以最大值开头
Constraint predicate not starting with the maximum value
我正在尝试匹配某个列表的前 Y 个元素的总和,Y 在 1..10 范围内,以及总和的最大值。我希望第一个匹配项是 Res=10,Y=10,但它只是给出从 Y=1 开始并增加到 Y=10 的答案。
我在这里错过了什么?
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.
?- 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.
此目标按此顺序枚举 Y
和 Res
的值。不需要标记,因为这些值已充分确定。一旦这个目标列举了这样的解决方案,以后的标签也不能强制不同的顺序。
(此外,如果您只想对列表求和,则谓词不需要这么多参数。如果您将它们命名得更好,您可能还会看到这个。您的 C
有最好叫UselessCounterFromZeroTowardsNegativeInfinity
。这样就可以去掉了。)
您可以强制 labeling/2 以这种方式交换目标生效:
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 .
但这也需要在 Res 的域上声明。
说实话,与其说是功能,不如说是错误。
毕竟,解决方案顺序应该如您所声明的那样,如 library(clpfd) 所宣传的那样。
否则,条款的秩序又回来咬我们了...
我正在尝试匹配某个列表的前 Y 个元素的总和,Y 在 1..10 范围内,以及总和的最大值。我希望第一个匹配项是 Res=10,Y=10,但它只是给出从 Y=1 开始并增加到 Y=10 的答案。 我在这里错过了什么?
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.
?- 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.
此目标按此顺序枚举 Y
和 Res
的值。不需要标记,因为这些值已充分确定。一旦这个目标列举了这样的解决方案,以后的标签也不能强制不同的顺序。
(此外,如果您只想对列表求和,则谓词不需要这么多参数。如果您将它们命名得更好,您可能还会看到这个。您的 C
有最好叫UselessCounterFromZeroTowardsNegativeInfinity
。这样就可以去掉了。)
您可以强制 labeling/2 以这种方式交换目标生效:
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 .
但这也需要在 Res 的域上声明。
说实话,与其说是功能,不如说是错误。 毕竟,解决方案顺序应该如您所声明的那样,如 library(clpfd) 所宣传的那样。 否则,条款的秩序又回来咬我们了...