Предикат ограничения не начинается с максимального значения - PullRequest
1 голос
/ 08 мая 2020

Я пытаюсь найти совпадение для суммы первых элементов 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.

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Вы можете принудительно применить метку / 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. кажется больше ошибкой, чем особенностью. В конце концов, порядок решения должен быть таким, как вы заявили, как объявлено библиотекой (clpfd). Иначе порядок пунктов снова вернется, чтобы нас укусить ...

1 голос
/ 08 мая 2020
?- 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. Тогда вы можете его исключить.)

...