我是Prolog的新手,我只是想到为什么这个规则在一个真实之后给我错误的结果。
likes(1,banana).
likes(1,mango).
test :- likes(1,banana),likes(1,mango).
?- test.
true;
false.
我想知道这种错误背后的原因。
答案 0 :(得分:7)
prolog的工作方式是评估查询,直到通过否定失败。
在这里,你已经建立了两个事实:
likes(1, banana).
说“1喜欢香蕉”
likes(1, mango).
说“1喜欢芒果”
然后你建立了一个规则,基本上评估为:
left_hand_side :- right_hand_side.
left_hand_side
如果 right_hand_side
将规则评估为查询会尝试匹配事实,如果可以,则返回true
,如果不匹配则返回false。需要注意的一件重要事情是,如果指定,只要规则评估为true
,prolog就会继续匹配事实。
让我们逐步完成test :- likes(1,banana),likes(1,mango).
如果test
作为查询运行,prolog首先尝试likes(1,banana)
这是先前建立的事实,并且为真。然后,它继续前进到likes(1,mango)
,这又是一个事实,并且是真的。然后Prolog到达规则的末尾,并输出true
。
此时,如果您没有搜索更多匹配项,则可以缩短查询次数,只需执行此操作即可。但是,如果您正在寻找更多(所有)匹配,请prolog 回溯并尝试再次评估规则,搜索更多匹配项。
但是,由于您的规则仅匹配“喜欢香蕉并喜欢芒果”,我们已经匹配likes(1,banana)
,当prolog回溯并再次尝试评估likes(1,banana)
时,因为我们之前已经匹配过了,这次没有其他事实(换句话说,1不能“喜欢”香蕉不止一次,除非已定义)匹配。这就是false
来自的地方。
在您的prolog解释器中,您可以通过键入trace.
然后运行查询来跟踪程序的执行情况。我的追踪如下:
| ?- trace
.
The debugger will first creep -- showing everything (trace)
(1 ms) yes
{trace}
| ?- test.
1 1 Call: test ?
2 2 Call: likes(1,banana) ?
2 2 Exit: likes(1,banana) ?
3 2 Call: likes(1,mango) ?
3 2 Exit: likes(1,mango) ?
1 1 Exit: test ?
true ? ;
1 1 Redo: test ?
2 2 Redo: likes(1,banana) ?
2 2 Fail: likes(1,banana) ?
1 1 Fail: test ?
(1 ms) no
{trace}
| ?-
最后要注意的一件事:如果我在;
提示符下按true ?
,而不是按<ENTER>
,则脚本只会以true
结束
我很高兴你问这个问题'因为它让我对prolog做了一个小小的复习,我很喜欢但很长时间没用过。