了解Prolog的副作用,例如写/ 1

时间:2018-10-15 19:53:42

标签: prolog

我目前正在学习Prolog,并且很难理解副作用。

我很乐于写一个谓词,它写一些N次字符串。给定的解决方案如下所示:

n_times(N) :- 1 =< N.
n_times(N) :- N > 1, N1 is N - 1, n_times(N1).
test_x(N) :- n_times(N), write('x'), fail.
test_x(_).

有人可以解释为什么这样做吗?为什么write('x')被执行N次?据我了解,Prolog应该尝试为n_times(N)找到解决方案,然后执行一次write('x')。我想这与副作用有关,但是我找不到对此的实用解释。

我自己的解决方案如下:

test_x(N) :- write('x'), N1 is N - 1, N1 >= 1, test_x(N1).

在这里,我看到每次递归调用都被调用write

1 个答案:

答案 0 :(得分:1)

这是所谓的故障驱动循环

一种更容易达成协议的情况是

repeat :- true.
repeat :- repeat.

forever_x :- repeat, write('x'), fail.

永远在提示符下显示x

为什么?因为Prolog的目标连结(,,“和”)就像嵌套循环

find(G):- this(X1), that(X2).

就像(在 pseudocode 中)

def find(G):
         foreach solution X1 to { this(X1) }:
             foreach solution X2 to { that(X2) }:
                 yield G using the found values X1, X2.

回溯是自然发生的循环。 。如果对于某些X1,没有X2满足that(X2)的情况,则没有{{ 1}}产生,并且外循环仅跳到满足G的下一个X1值。

Prolog对目标的析取(this(X1),“或”)只是循环的并置(只是将一个循环接一个循环)。

因此,;的定义就像是由

定义的一样
repeat

和您的def repeat: yield % yield an empty value that isn't used anywhere repeat % call self, yielding again; and again; repeating endlessly def forever_x: foreach solution to { repeat }: % endless stream of empty solutions foreach solution to { write('x') }: % there will be only one, empty solution foreach solution to { fail }: % there will be no solutions, ever, so yield % this will never happen ,就像

n_times/1

因此自然会成功,即“产量”, n 次。