这个 Prolog 程序如何解析为 H=2?执行线看不懂
How does this Prolog program resolve to H=2? I don't understand the line of execution
我从 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,然后将 P 设置为 100-S(这是 100)。
H = 0 怎么没有完成?我错过了什么?
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
会成功。
除了操作解释之外,我想为此类问题建议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)
肯定会失败。
我从 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,然后将 P 设置为 100-S(这是 100)。
H = 0 怎么没有完成?我错过了什么?
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
会成功。
除了操作解释之外,我想为此类问题建议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)
肯定会失败。