2016-09-22 4 views
1

私は最近Prologを学習していて、それをどのように機能させるのに問題がありますか。一例として、プロローグの精神科医を作成し、それを質問に変える作業を設定しました。私は「私がうまくいないと思う」と思うのはなぜあなたが気分が悪いと思いますか?Prolog write無限ループ

しかし、これまでのところ、私のコードは終了時に無限ループを生成しています。それはprintSentenceに対してredoを呼び出し、出力リストの最後にそれを固定し、これを永久に行う、別のバインドされていない変数を呼び出します。ここで

は私のコードです:

/* printSentence simply calls the in-built Prolog write function. */ 
printSentence([]) :- write('?'). 
printSentence([H|T]) :- write(H),write(' '), printSentence(T). 

answer([], _) :- write('Why are you silent? Talk to me.'). 
answer(Input, Output) :- thinkMatch(Input, Output), printSentence(Output). 

thinkMatch(['I', 'think'|Rest], ['Why', 'do', 'you', 'think'|SwitchedRest]) :- switchPronouns(Rest, SwitchedRest). 

switchPronouns([], _). 
switchPronouns([H|T], [R|SwitchedRest]) :- switchWord(H, R),switchPronouns(T, SwitchedRest). 


switchWord('I', 'you'). 
switchWord('myself', 'yourself'). 
switchWord('am', 'are'). 
switchWord('you', 'me'). 
switchWord('yourself', 'myself'). 
switchWord(H, H). 

入力、

answer(['I', 'think', 'therefore', 'I', 'am'],Output). 

はそれが小さく、ダム何かあれば、私はきた、永遠にこれらの結果は起こって

?- Input = ['I', 'think', 'therefore', 'I', 'am'],answer(Input, Output). 
Why do you think therefore you are ? 
Input = ['I', think, therefore, 'I', am], 
Output = ['Why', do, you, think, therefore, you, are] ; 
_G4395 ? 
Input = ['I', think, therefore, 'I', am], 
Output = ['Why', do, you, think, therefore, you, are, _G4395] ; 
_G4398 ? 
Input = ['I', think, therefore, 'I', am], 
Output = ['Why', do, you, think, therefore, you, are, _G4395, _G4398] ; 
_G4401 ? 
Input = ['I', think, therefore, 'I', am], 
Output = ['Why', do, you, think, therefore, you, are, _G4395, _G4398|...] 

謝罪を生成しますまだPrologの内部の仕掛けを完全に把握する。

ありがとうございます。

答えて

2

あなたはswitchPronouns([], _).と書いています。つまり、空の入力の場合は何でも構いません。もちろんこれは正しくありません。あなたが本当に望むのは、空の入力に対しては、出力も空であるということです:switchPronouns([], []).

printSentence([H|T])Tのインスタンス化されていない変数で呼び出すことになるので、無限ループに入る理由があります(出力が「何か」で、Prologにまだ値がないときは、非インスタンス化)。今、Prologは再帰句にマッチして、Tが空のリストであれば疑問符が表示されることを確認します。これが最初に見つかった解決策です。

しかし、Prologはそれが本当に空リストであることを意味するのかどうかわかりません。したがって、第2節も試します:Tが[_H | _T]という形式の空でないリストであればどうなりますか?この場合、頭と尾の両方が不明です。したがって、割り当てられていないヘッドを出力し、テールを伴う再帰呼び出しを続けます。しかし、尾は未知の価値です!だから我々は無限の再帰で終わる。


あなたはswitchPronounsを更新した後、出力はまだ正しくないことがわかります。この理由はswitchWordにある

Why do you think therefore you are ? 
Output = ['Why', do, you, think, therefore, you, are] 
Why do you think therefore you am ? 
Output = ['Why', do, you, think, therefore, you, am] 
... 

:今すぐ回答の有限数ありますが、それはあなたが期待していない回答の束を提供します。たとえば、入力語が「I」の場合、Prologはそれを句switchWord('I', 'you').に一致させることができます。ただし、switchWord(H, H).にも一致します。あなたが本当に望むのは、「本当の」マッチを使用し、マッピングがない場合にのみ単語を変更しないようにすることです。

私が書くだろうと、このような何か:

switchWord(I、O): - word_map(I、R) - > O = R; O = I.

word_map('I', 'you'). 
word_map('myself', 'yourself'). 
word_map('am', 'are'). 
word_map('you', 'me'). 
word_map('yourself', 'myself'). 

これで、1つの期待される答えが得られました。


私がここに見る別の小さな問題:answer([], _)。上のように、入力が空の場合、出力は何でもかまいません。

最後に
answer([], _) :- write('Why are you silent? Talk to me.'), fail. 

、一般的にPrologの述語がsnake_case、ないキャメルケースで記述されている:あなたは、常に答えがないことを示すために失敗する原因を引き起こす場合があります。これは主に優先事項ですが、標準を使用すると、他のプログラマーにとってコードを読みやすくなります。

+0

おかげでたくさんの非常に徹底した答えです!この再現は、Prologがどのように動作するかを理解するのに役立ちました。 – SHolmes

1

あなたはswitchPronouns([], _). switchPronouns([], []).の理由は何でその_試合でanswer([], [])answer([], _)を変更しても変更できます。two..andが進むと、空のリスト、一つの要素を持つリストので、あなたがすることを強制空リストそれはswitchWord/2による一部の間違った答えを与える

?- answer(['I', 'think', 'therefore', 'I', 'am'],Output). 
Why do you think therefore you are ? 
Output = ['Why', do, you, think, therefore, you, are] ; 
Why do you think therefore you am ? 
Output = ['Why', do, you, think, therefore, you, am] ; 
Why do you think therefore I are ? 
Output = ['Why', do, you, think, therefore, 'I', are] ; 
Why do you think therefore I am ? 
Output = ['Why', do, you, think, therefore, 'I', am]. 

: はまた、もう一つの問題があります。また、変更することができます:

answer(Input, Output) :- thinkMatch(Input, Output), printSentence(Output). 

answer(Input, Output) :- thinkMatch(Input, Output), printSentence(Output),!. 

これらの間違った出力カットれる:

?- answer(['I', 'think', 'therefore', 'I', 'am'],Output). 
Why do you think therefore you are ? 
Output = ['Why', do, you, think, therefore, you, are]. 
+0

ああ大丈夫です。今、感謝します。私の脳は昨日少し遅くなりました。私は '!'それは何の前に表記法ですか? – SHolmes

+0

これはcutと呼ばれ、プロローグが述語を証明しようとすると、可能なすべての解を試すと、cut(!)演算子はすでに解決策を見つけたら可能な解を切り捨てます。場所はどこに!それが最初の正しい解決策を見つけたらそれを止めるようなものでした。 !の場所を変える!たとえば、2つのソリューションを提供し、他のすべてのものをカットすることができます。それはどこに依存するのですか?置かれている... – coder