最小化/1 不是重新排列解决方案的顺序



对于哥伦比亚的Observatorio Fiscal[1],我正在使用CLP(R)(在SWI-Prolog中)编写一个简单的税收最小化问题。我想先使用 minimize/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] 财政观察站是一个新组织,旨在模拟哥伦比亚经济,以预测法律变化的影响,类似于国会预算办公室或税收政策中心在美国所做的。

首先,让我们向程序添加以下定义:

:- op(950,fy, *). *_.

使用(*)/1,我们可以概括程序中的各个目标。

例如,让我们通过将*放在前面来概括minimize/1目标:

应纳税所得额(谁,TI) :- 扣除(谁,D), 收入(谁,我), TI #= I - D, *最小化(TI)。

我们现在得到:

?- 应税收入(X,Y)。 X = 乔, Y = 7 ; X = 乔, Y = 6。

这说明CLP(R)其实和这个问题无关!这些答案表明,在调用minimize/1时,所有内容都已实例化,因此没有什么可以最小化的。

要真正从minimize/1中受益,您必须以 CLP(R)(或更好的:CLP(Q))约束的形式表达任务,然后在约束表达式上应用minimize/1

另请注意,在SWI-Prolog中,CLP(R)和CLP(Q)都有基本错误,你不能相信它们的结果。

根据 Mat 的响应,我重写了使用 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]).

最新更新