Свернуть /1 не переставляет порядок решений

Для Observatorio Fiscal из Колумбии [1] я кодирую простую проблему минимизации налогов, используя CLP(R) (в SWI-Prolog). Я хочу использовать свернуть /1, чтобы сначала найти наименьшее решение. Вместо этого он сначала перечисляет большее решение. Вот код:

:- use_module(library(clpr)).

deduction(_,3).            % Anyone can take the standard deduction.
deduction(Who,D) :- itemizedDeduction(Who,D). % Or they can itemize.

income(joe,10).            % Joe makes $10 a year.
itemizedDeduction(joe,4).  % He can deduct more if he itemizes.

taxableIncome(Who,TI) :-
   deduction(Who,D),
   income(Who,I),
   TI is I - D,
   minimize(TI).

Вот как выглядит интерактивная сессия:

?- taxableIncome(joe,N).
N = 7 ;
N = 6 ;
false.

Если я переключаю слово "минимизировать" на "максимизировать", оно ведет себя одинаково. Если я не включил предложение свернуть или развернуть, он не ищет третьего решения, но в остальном он ведет себя так же:

?- taxableIncome(joe,N).
N = 7 ;
N = 6.

[1] Observatorio Fiscal - это новая организация, которая стремится моделировать колумбийскую экономику, чтобы предвидеть последствия изменений в законодательстве, аналогично тому, что делают Бюджетное управление Конгресса или Центр налоговой политики в Соединенных Штатах.

2 ответа

Сначала добавим следующее определение в программу:

: - op (920, фу, *).
*_.

С помощью (*)/1 Мы можем обобщить отдельные цели в программе.

Например, давайте обобщим minimize/1 цель путем размещения * спереди:

taxableIncome (Кто,TI):-
        дедукция (Кто,D),
        доход (Кто,I),
        TI #= I - D,
        * минимизировать (TI).

Теперь мы получаем:

? - налогооблагаемый доход (X, Y).
Х = Джо,
Y = 7;
Х = Джо,
Y = 6

Это показывает, что CLP(R) на самом деле не имеет ничего общего с этой проблемой! Эти ответы показывают, что все уже создано в то время minimize/1 называется, так что нечего минимизировать.

Чтобы действительно извлечь выгоду из minimize/1 Вы должны выразить задачу в форме CLP(R) - или лучше: CLP(Q) - ограничения, затем применить minimize/1 на ограниченном выражении.

Также обратите внимание, что в SWI-Prolog и CLP(R), и CLP (Q) имеют элементарные ошибки, и вы не можете доверять их результатам.

Согласно ответу Мата, я переписал программу, выражающую ограничения, используя CLP. Сложность заключалась в том, что мне пришлось сначала собрать все (оба) возможных значения для вычета, а затем преобразовать эти значения в домен CLP. Я не мог заставить это преобразование работать в CLP(R), но я мог в CLP(FD):

:- use_module(library(clpfd)).

deduction(_,3).     % Anyone can take the same standard deduction.
deduction(Who,D) :- % Or they can itemize.
    itemizedDeduction(Who,D).

income(joe,10).
itemizedDeduction(joe,4).

listToDomain([Elt],Elt).
listToDomain([Elt|MoreElts],Elt \/ MoreDom) :-
    MoreElts \= []
    , listToDomain(MoreElts,MoreDom).

taxableIncome(Who,TI) :- 
    income(Who,I)
    , findall(D,deduction(Who,D),DList)
    , listToDomain(DList,DDomain)
    % Next are the CLP constraints.
    , DD in DDomain
    , TI #= I-DD
    , labeling([min(TI)],[TI]).
Другие вопросы по тегам