2012-01-14 76 views
1

私は、アキュムレータが何であるか、何をするかについてのチュートリアルを探していますが、すべての説明は非常に複雑すぎるようですが、どのように働いているので、私はそれを利用することができます。私は、アキュムレータが他のコードによって呼び出されて変更される可能性のある番号などを保持していることを理解しているようです。問題は、アキュムレータが何であるかを理解していて、必要なときに知っているにもかかわらず、実際に使用する方法があまりにも分かりません。Prologアキュムレータと +メンバ関数

アキュムレータは空のリストのように見えることがありますが、アキュムレータと見なすことができないものが何であるか不思議に思い浮かぶのは「0」と思われます。誰かが簡単にアキュムレータをどのように使用することができるか、私に説明してください。

また、私の質問の第二部のために、私は彼らのプロローグコードに多くのことを、これを使っている人に気づいているように見える:

\+member 

私はそれがため、リストとは何かを持っていることを推測するために管理してきました私はいつもそれが何かをリストにするコード行の中で使われているのを見ていますが、私が実際に何を意味するかは、 "否定としての否定 - 証明できません"たとえその人物が正しかったとしても。もう一度、誰かが正確に+メンバーが何をしているのか、あなたの説明を簡単に保つために何が使えるのかを私に説明してもらえますか?大きな言葉はxDを混乱させます。

この2つの問題に関するお手伝いがありがとうございました。

答えて

8

まず、\+は目標の否定です。それはそれに続く目標が失敗するとき、成功する。たとえば、

第2に、アキュムレータは、テール再帰最適化を利用するために、再帰を介して状態をスレッド化する方法です。最初のバージョンはちょうど完了する下位呼び出しを待ち、再帰に自分自身を呼び出す

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

は階乗を計算するこれらの2つの等価な方法を検討してください。それだけで、サブコールの結果にN値を乗算します。

2番目のバージョンでは、アキュムレータ(Acc)が使用されています。 1はアキュムレータではありませんが、初期値です。その後、述部への各呼び出しは、それを累算器にN値を掛け、再帰がそれに達すると、累算器の値はすでに最終値になります。

質問は本当に「アキュムレータは何ができますか? (0または空リストなど)。これは、「あなたが行ったように」値を累積し、呼び出し側の述語に戻ってこない単なる方法です。このようにして、Prologシステムは絶えず増大するコールスタックを構築する必要はありません。

ただし、この例では乗算の順序は自然に逆になります。乗算には関係ありませんが、リストのような他の値については、それを処理しなければなりません。

fact_simple1 * 2 * 3 * 4 * 5 * 6との乗算を行い、fact_acc1 * 6 * 5 * 4 * 3 * 2とした。それが不明な場合は、両方のトレースをしてください!

+0

ありがとうございます、これはトンを助けました – Arun22

+1

ようこそ。私は、アキュムレータ 'パターン'がプロローグに固有ではなく、むしろ関数型プログラミングの要素であると付け加えたいと思います。 – firefrorefiddle

関連する問題