这个Prolog程序如何解析为H = 2?我不了解执行的路线

时间:2015-04-20 20:24:29

标签: prolog

我从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时怎么办?我错过了什么?

2 个答案:

答案 0 :(得分:2)

member(H,[0,1,2])H绑定到0,1或2.由于QDNP都为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)肯定会失败。