我从Prolog的YouTube tutorial中获取了以下一段Prolog:
change(H, Q, D, N, P) :-
member(H, [0, 1, 2]),
member(Q, [0, 1, 2, 3, 4]),
member(D, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
member(N, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]),
S is 50*H + 25*Q + 10*D + 5*N,
S =< 100,
P is 100-S.
这是一个改变美元的计划。 H是半美元,Q是四分之一,D是硬币,N是镍,P是便士。
如果我输入change(H, 0, 0, 0, 0).
作为查询,则会解析为H = 2。在视频中,他提到这是一个以1美元换货的程序,所以我知道两个半美元是1美元,但我不明白它是如何得到的。
我对Prolog的理解是,当我通过change(H, 0, 0, 0, 0).
时,它会找到满足条件的H的值,所以它会转到第一行,看到0会起作用,然后是另一行“member”行看到传递的0也是正确的。
然后将S设置为一个值,给定上述值为S = 0.下一行确保它小于或等于100,其中0为0,然后将P设置为100-S(即100) )。
H = 0时怎么办?我错过了什么?
答案 0 :(得分:2)
member(H,[0,1,2])
将H
绑定到0,1或2.由于Q
,D
,N
和P
都为0, H
唯一能满足底部方程的值是2。
当H
= 0时,S
将为0,100-S
将为100,并且由于P
为0,P is 100-S
将失败。
当H
= 1时,S
将为50,100-S
将为50,并且由于P
为0,P is 100-S
将失败。
当H
= 2时,S
将为100,100-S
将为0,并且由于P
为0,P is 100-S
将成功。
答案 1 :(得分:1)
除了操作说明之外,我还建议对这些问题提出CLP(FD)约束,这些问题比低级算术谓词更容易理解和更具声明性。例如,在SICStus Prolog,YAP和SWI中:
:- use_module(library(clpfd)).
change(H, Q, D, N, P) :-
H in 0..2,
Q in 0..4,
D in 0..10,
N in 0..20,
S #= 50*H + 25*Q + 10*D + 5*N,
S #=< 100,
P #= 100-S.
现在让我们以声明的方式说明理由:
根据您的要求H = 0
,如您所指定,其他参数为0
,那么P
的可接受值是多少?
?- change(0, 0, 0, 0, P).
P = 100.
由此我们可以看到,如果所有其他参数都是0
,则查询的唯一有效解决方案是P = 100
。因此,目标change(0, 0, 0, 0, 0)
肯定会失败。