Prolog写无限循环

时间:2016-09-22 05:38:49

标签: prolog output infinite-loop

我最近在学习Prolog,但我无法按照自己的意愿运作。作为一个例子,我已经设定了一个任务来创建一个Prolog精神病学家,它接受输入并把它变成一个问题,我,我认为我不舒服"成为"为什么你认为自己身体不适?"。

但是到目前为止,我的代码在退出时会生成一个无限循环。它在printSentence上调用redo,另一个未绑定的变量将其添加到Output列表的末尾并永远执行此操作。

这是我的代码:

/* 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 个答案:

答案 0 :(得分:2)

你写了List<Color> ColorList = new List<Color>() { Color.Yellow, Color.Red}; public Form1() { InitializeComponent(); this.listBox1.DataSource = ColorList; } // if this event is fired you don't need to check whether an item is selected or not (no if-clause needed) private void colorsLstBx_SelectedIndexChanged(object sender, EventArgs e) { // just assign the selected item and no switching is needed this.BackColor = (Color)listBox1.SelectedItem; } ,这意味着对于空输入,输出可以是任何东西。当然这不对;你真正想要的是,对于空输入,输出也是空的:switchPronouns([], _).

它进入无限循环的原因是因为它最终会使用switchPronouns([], []).的未实例化变量调用printSentence([H|T])(当输出可以是'任何'并且Prolog没有值时对于它,它让它没有实例化)。现在Prolog尝试匹配递归子句,并看到如果T为空列表,则打印问号。这是第一个找到的解决方案。

但是,Prolog不知道你是否真的想把它作为空列表,所以它也会尝试第二个子句:如果T是一个非空的表单[_H | _T]怎么办?在这种情况下,头部和尾部都是未知的。因此它打印未分配的头部,并继续使用尾部的递归调用。但尾巴又是一个未知的价值!所以我们最终会进行无限递归。

您会注意到在更新T后,输出仍然不正确。虽然现在答案数量有限,但它提供了一些您不期望的答案:

switchPronouns

原因在于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子句匹配。但是,它也可以匹配switchWord('I', 'you').!你真正想要的是使用“真实”匹配,只有在没有映射时才保持单词不变。

我写的是这样的:

switchWord(I,O): - word_map(I,R) - &gt; O = R; O = I。

switchWord(H, H).

现在你最终得到了单一的预期答案!

我在这里看到的另一个小问题:word_map('I', 'you'). word_map('myself', 'yourself'). word_map('am', 'are'). word_map('you', 'me'). word_map('yourself', 'myself'). 。如上所述,这表示如果输入为空,则输出可以是任何输出。您可能希望导致此原因始终无法指示没有答案:

answer([], _)

最后,一般来说,Prolog谓词是用snake_case编写的,而不是camelCase。这主要是一个偏好问题,但使用该标准使代码更容易为其他程序员阅读。

答案 1 :(得分:1)

您可以将answer([], _)更改为answer([], []),也可以将switchPronouns([], _).更改为switchPronouns([], []). 原因是_与任何东西匹配:空列表,带有一个元素的列表,有两个......然后继续,所以你强制它为空列表。 还有一个问题:

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

由于switchWord/2,它给出了一些错误的答案。你也可以改变:

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