2012-01-14 52 views
1

我一直在寻找关于什么是累加器和它们做什么的教程,但是所有的解释似乎都非常复杂,并且不能真正给我一个足够清晰的图片他们如何工作,以便我可以利用它。我似乎明白,累加器保存着一些数字,然后可以通过其他代码调用并更改。问题是虽然我明白什么是累加器,知道什么时候需要累加器,但我不太确定如何实际使用它。序言什么是累加器和 +成员函数

我的意思是从我看过的教程中,有时候累加器似乎是一个空的列表,而其他时候它似乎是'0',让我想知道什么可以被认为是累加器,什么不能。有人可以请简单地向我解释一下如何使用累加器?

也为我的问题的第二部分,我似乎有使用这个很多他们的序言代码注意到人:

\+member 

我已经成功地推断出它的东西,因为做处理列表我总是看到它在一行代码中使用,但是在四处搜索之后,我发现+成员的实际含义是“作为失败的否定 - 不可证明”,尽管我不明白这意味着什么,或者即使那个人是正确的。再说一遍,有人能向我解释成员究竟做了什么以及它可以用于什么,同时试图让你的解释变得简单,大词汇让我困惑xD。

非常感谢您对这两件事的任何帮助。

回答

8

首先,\+是否定目标。它成功了,当它追随它的目标失败时。例如:

?- 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. 

其次,累加器是一种通过递归线程化状态以利用尾递归优化的方法。

考虑计算阶乘的这两种等价的方式:

?- [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 . 

第一个版本只是调用自身的递归,等待subcall完成。只有它的N -value与subcall的结果相乘。

第二个版本使用累加器代替(Acc)。请注意,1不是累加器,而是初始值。之后,每次调用谓词时,都会将它的值与累加器相乘,并且当递归达到它的基本情况时,累加器的值已经是最终值。

这个问题真的不是'累加器可以做什么? (0或空列表或任何东西)。这只是一种积累价值的方式,“随你走”,永远不会回到调用谓词。这样,Prolog系统不必建立一个不断增长的调用堆栈。

但是请注意,在这个例子中,乘法的顺序自然是相反的。对乘法无关紧要,但对于其他值(如列表),则必须注意这一点。

fact_simple做了乘法作为1 * 2 * 3 * 4 * 5 * 6,而fact_acc把它作为1 * 6 * 5 * 4 * 3 * 2。如果不清楚,只需做一下两者的追踪!

+0

谢谢,这有助于吨 – Arun22 2012-01-14 18:30:06

+1

不客气。我只想补充说,累加器的'模式'并不是关于序言的具体情况,而是函数式编程的一个元素。 – firefrorefiddle 2012-01-15 08:13:15

相关问题