对于哥伦比亚的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] Observatorio Fiscal是一个旨在模拟哥伦比亚经济的新组织,旨在预测法律变化的影响,类似于国会预算办公室或税务政策中心在美国的做法
答案 0 :(得分:2)
首先,让我们在程序中添加以下定义:
:- op(920,fy, *). *_.
使用(*)/1
,我们可以概括计划中的各个目标。
例如,让我们通过将minimize/1
放在前面来概括*
目标:
taxableIncome(Who,TI) :- deduction(Who,D), income(Who,I), TI #= I - D, *minimize(TI).
我们现在得到:
?- taxableIncome(X, Y). X = joe, Y = 7 ; X = joe, Y = 6.
这表明CLP(R)实际上与此问题无关!这些答案显示,在调用minimize/1
时,所有内容都已经实例化,因此没有任何内容可以最小化。
要真正受益于minimize/1
,您必须以CLP(R)的形式表达任务 - 或者更好:CLP(Q) - 约束,然后应用{{1}在受约束的表达式上。
另请注意,在SWI-Prolog中,CLP(R)和CLP(Q)都有elementary mistakes,您不能相信他们的结果。
答案 1 :(得分:1)
Per 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]).