Prolog中的指令顺序和递归



我刚从prolog开始,我有一个关于递归的问题。

我基本上想计算某个值在列表中的时间,所以我有一个例子:

count( a, [ a, s, d, f, g, a, s, d, a, s ], W ).  W = 3.

在我想计算时间的地方";a";在列表中,并将该号码存储在"0"中;W";。

正确答案是

count( _, [], 0 ). 
count( A, [B|S], X ) :- A==B, count( A, S, Y ), X is Y + 1. 
count( A, [B|S], X ) :- + A == B, count( A, S, X ).

Howhever,我不明白为什么在第2行;X是Y+1";最后。这条线不应该是吗

count( A, [A|S], X ) :- Y is X + 1, count( A, S, Y ).

在这种情况下,我们首先将Y设置为1,然后将其发送到"0";计数";再次使用递归。

如果有人能帮我,我将不胜感激!

当您调用:时,请考虑

?- count(a,[a,s,d,f,g,a,s,d,a,s],W).

则匹配的第一个谓词是CCD_ 1。这意味着它把它看作count(a,[a|S],X),其中S&CCD_ 4是变量。X只是来自原始调用的W,因此它仍然是一个变量。

建议对Y is X + 1进行评估是没有意义的,因为X是一个变量。

然而,最初的谓词确实有意义。

count(A,[B|S],X) :- A==B, count(A,S,Y), X is Y + 1.

当它递归时,它将一个新的变量Y发送到第二个count(A,[B|S],X)0谓词中(或者只是在第三个谓词中传递相同的变量(。它一直这样做,直到它最终将变量统一到0时达到基本情况。在这一点上,它取消了递归,现在它终于可以执行X is Y + 1(因为Y是一个值(,因此X现在是一个数值。

Prolog是一种有趣的语言,因为它几乎有一种时间旅行的感觉,你必须向前和向后思考才能理解程序是如何工作的。

count( A, [B|S], X ) :- A==B, count( A, S, Y ), X is Y + 1.

这意味着:如果S包含AA == BY次出现,则[B | S]包含A的一次出现。

例如,假设我们在计算[prolog, prolog, prolog]prolog的出现次数时到达这里。[B | S] = [prolog, prolog, prolog]S = [prolog, prolog]prologS中的出现次数是2,所以我们应该有Y = 2prolog[B | S]中的出现次数是3,所以我们应该有X = 3。一旦我们知道Y = 2,那么X is Y + 1计算X的这个正确值。

count( A, [A|S], X ) :- Y is X + 1, count( A, S, Y ).

这意味着:如果[A | S]包含AX次出现,则S包含A的一次出现。这不可能。

再次使用上面的例子:很明显,[A | S] = [prolog, prolog, prolog]包含X0的3次出现,所以X = 3应该成立。但是Y必须是4,并且体内的目标将试图证明S = [prolog, prolog]包含4prolog的出现。事实显然并非如此。

请注意,这个解释只是关于谓词的含义。它不需要我们考虑递归、目标的顺序或程序实际执行的确切方式。在进行Prolog编程时,首先要清楚程序的逻辑含义

最新更新