prolog - 了解 Prolog 的副作用,例如 write/1
问题描述
我目前正在学习 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
每次递归调用都会调用它。
解决方案
这就是所谓的失败驱动循环。
一个更简单的情况是
repeat :- true.
repeat :- repeat.
forever_x :- repeat, write('x'), fail.
永远x
在提示符下打印。
为什么?因为 Prolog 的目标连词 ( ,
, "and") 就像嵌套循环:
find(G):- this(X1), that(X2).
就像(在伪代码中)
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)
,则产生 noG
,并且外部循环只是跳到满足的下一个X1
值this(X1)
。
Prolog 的;
目标分离( ,“或”)只是循环的并置(只是将一个循环放在另一个循环)。
因此,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_times(N) :- N =< 1.
% n_times(N) :- N > 1, N1 is N - 1, n_times(N1).
def n_times(n):
foreach solution to { n =< 1 }: % succeeds at most once
yield n
foreach solution to { n > 1 }: % at most once, mutually exclusively
foreach solution to { n1 = n - 1 }: % there will be only one solution
n_times(n1)
所以很自然这会成功,即“屈服”,n次。
推荐阅读
- python - 在 pandas seaborn 中制作堆叠条形图
- c# - 如何使用 Json (C#) 从 URL API 检索字符串值?
- sh - Raspberry Pi 在自动启动时不运行脚本
- linux - 我可以在不使用 mmap 的情况下防止文件页面驱逐吗?
- angular - 按下 Chrome 调试工具旋转到横向按钮时,Angular 组件会重新加载
- java - 错误“不兼容的操作数类型 Module.Category 和 ULocale.Category”
- elasticsearch - 带有传递参数的 Elasticserach sql 查询,因此我们可以防止 sql 注入
- function - 使用 PowerShell 对象和参数
- kotlin - java.lang.IllegalStateException:nicknameTextView 不能为空
- python - Python - 用嵌套字典中的空字符串替换无