在使用DCG反转字符串时,Prolog如何判断何时结束递归?
我正在使用Scryer Prolog。我从Power of Prolog的 YouTube频道看到这个:
qes([]) --> [].
qes([L|Ls]) --> qes(Ls), [L].
使用listing,我得到了它在Prolog子句中的形式:
?- listing(qes/3).
qes([],A,B) :-
A=B.
qes([L|Ls],A,B) :-
qes(Ls,A,C),
C=[A|B].
true.
我正在努力逐步弄清它的执行过程。
当我调用phrase(qes, "abc").时,它在内部被转换为qes(X, "abc",[]).
它们被统一:X = [L|Ls], A = "abc", B = []. Prolog尝试基条款。abc不等于 []。
第一次调用:
qes([L1|Ls1], "abc", []) :- qes(Ls1,"abc",C1), C1=[L1|[]].
第二次调用:
qes([L2|Ls2], "abc", C2) :- qes(Ls2,"abc",C2), C2=[L2|C1].
类似地,第三次调用也是如此。由于L 与Ls是变量,在基准情形成功之前它们都不会被绑定到任何东西,那么Prolog如何知道何时结束递归?在我看来,没有任何情形是任何Ls = []。Prolog如何进入基准情形?
解决方案
我使用了SWI-Prolog,但在Scryer上也应该可以完全做到同样的效果。我加载了你的代码,测试它确实能工作,然后对谓词进行了 跟踪,以按顺序查看发生了什么:
102 ?- phrase(qes(`abc`), S).
S = [99, 98, 97].
103 ?- trace(qes//1).
% qes/3: [all]
true.
104 ?- phrase(qes(`abc`), S).
T [15] Call: qes([97, 98, 99], _30682, [])
T [22] Call: qes([98, 99], _30682, _32214)
T [29] Call: qes([99], _30682, _33258)
T [36] Call: qes([], _30682, _34302)
T [36 +0.2ms] Exit: qes([], _30682, _30682) % second and third argument
% are now the same!
T [29 +0.9ms] Exit: qes([99], [99|_33258], _33258)
T [22 +1.3ms] Exit: qes([98, 99], [99, 98|_32214], _32214)
T [15 +1.9ms] Exit: qes([97, 98, 99], [99, 98, 97], [])
S = [99, 98, 97].
你现在看清楚了吗?
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。