Aru*_*n22 1 rules function prolog member accumulator
我一直在寻找关于累加器是什么以及它们做什么的教程,但是所有的解释似乎都非常简单,并没有真正给我一个清晰的图片说明它们是如何工作的,这样我就可以利用它.我似乎明白累加器会保留一些数字,然后可以被其他代码调用并更改.问题是虽然我理解累加器是什么并知道什么时候需要它,我不太确定如何实际使用它.
我的意思是从我见过的教程,有时累加器似乎是一个空列表,而有时它似乎是'0'让我想知道究竟什么可以被认为是累加器,什么不能.有人可以用简单的语言向我解释一下如何使用累加器?
同样对于我的问题的第二部分,我似乎注意到人们在他们的prolog代码中使用了很多:
\+member
Run Code Online (Sandbox Code Playgroud)
我已经设法推断它与列表有关,因为我总是看到它在一行代码中使用,但是在搜索后我发现+成员实际上意味着"否定为失败" - 不可证明"虽然我不明白这意味着什么,或者即使那个人是正确的.再说一次,有人可以向我解释一下+成员究竟做了什么以及它可以用于什么,同时试图让你的解释变得简单,大词让我迷惑xD.
非常感谢您对这两件事的任何帮助.
首先,\+是否定目标.当它的目标失败时,它会成功.例如:
?- member(3, [1,2,3]). # 3 is a member of the List
true.
?- member(4, [1,2,3]). # 4 is not a member
false.
?- \+member(4, [1,2,3]). # succeeds, because 'member' fails
true.
?- \+member(3, [1,2,3]).
false.
?- atom_chars('hi', C).
C = [h, i].
?- atom_chars('hi', [h, i]).
true.
?- atom_chars('hello', [h, i]).
false.
?- \+atom_chars('hello', [h, i]).
true.
Run Code Online (Sandbox Code Playgroud)
其次,累加器是一种通过递归线程化状态的方法,以利用尾递归优化.
考虑这两种计算阶乘的等价方法:
?- [user].
|: fact_simple(0, 1).
|: fact_simple(N, F) :-
N1 is N-1,
fact_simple(N1, F1),
F is N*F1.
|: % user://2 compiled 0.00 sec, 440 bytes
true.
?- fact_simple(6, F).
F = 720 .
[user].
|: fact_acc(N, F) :- fact_acc(N, 1, F).
|: fact_acc(0, Acc, Acc).
|: fact_acc(N, Acc0, F) :-
N1 is N-1,
Acc is Acc0 * N,
fact_acc(N1, Acc, F).
|: % user://4 compiled 0.00 sec, 1,912 bytes
true.
?- fact_acc(6, F).
F = 720 .
Run Code Online (Sandbox Code Playgroud)
第一个版本只是在递归中调用自身,等待子查询完成.然后它将它的N值与子查询的结果相乘.
第二个版本使用累加器代替(Acc).请注意,这1不是累加器,而是初始值.之后,对谓词的每次调用都将它的N值与累加器相乘,并且当递归到达它的基本情况时,累加器的值已经是最终值.
问题实际上不是"蓄能器能做什么?(0或空列表或任何东西).它只是一种累积值的方式,而且永远不会返回到调用谓词.这样,Prolog系统就不必构建一个不断增长的调用堆栈.
但是请注意,在这个例子中,乘法的顺序自然是相反的.乘法并不重要,但对于其他值(如列表),必须要考虑到这一点.
fact_simple做了乘法1 * 2 * 3 * 4 * 5 * 6,虽然fact_acc它是1 * 6 * 5 * 4 * 3 * 2.如果这还不清楚,那就去做一下这两个!
| 归档时间: |
|
| 查看次数: |
2798 次 |
| 最近记录: |