Пролог работает сначала глубина , так что это означает, что он будет продолжать добавлять список с игрушками в список дальше, и никогда не будет смотреть, достигнута ли уже общая цена, и, таким образом, добавление дополнительных элементов делаетнет смысла.
Мы можем решить эту проблему, вычислив цену в обратном порядке: мы можем использовать library(clpfd)
и определить соотношение между ценой списка с игрушкой и ценой без игрушки, и добавитьограничение на то, что искомая цена всегда должна быть больше нуля, если мы повторяем, например:
<b>:- use_module(library(clpfd)).</b>
calculatePrice([], 0).
calculatePrice([H|T], PHT) :-
<b>PHT #> 0,</b>
toy(H, PH),
<b>PHT #= PT + PH,</b>
calculatePrice(T, PT).
Затем мы получаем, например:
?- calculatePrice(L, 21).
L = [train, train, train, doll] ;
L = [train, train, train, car, car] ;
L = [train, train, doll, train] ;
L = [train, train, car, train, car] ;
L = [train, train, car, car, train] ;
L = [train, doll, train, train] ;
...
?- calculatePrice([train, train], P).
P = 10.
?- calculatePrice(L, P).
L = [],
P = 0 ;
L = [train],
P = 5 ;
L = [train, train],
P = 10 ;
L = [train, train, train],
P = 15 ;
L = [train, train, train, train],
P = 20 ;
L = [train, train, train, train, train],
P = 25
...
Ограничение PHT #> 0
равнонеобходимо здесь.Вы можете видеть PHT
, когда мы запрашиваем, например, calculatePrice(L, 21)
как «сумму, которую мы оставили потратить».В случае, если эта сумма меньше или равна нулю, мы не можем больше тратить деньги, и, таким образом, это ограничение не будет выполнено.