ani*_*ebs 4 prolog prolog-toplevel
我是Prolog的新手,我只是在想,为什么这个规则在一个真实之后给我错误的结果.
likes(1,banana).
likes(1,mango).
test :- likes(1,banana),likes(1,mango).
?- test.
true;
false.
Run Code Online (Sandbox Code Playgroud)
我想知道这种错误背后的原因.
prolog的工作方式是通过评估查询,直到通过否定失败.
在这里,你已经建立了两个事实:
likes(1, banana). 其中说"1喜欢香蕉"
likes(1, mango). 其中说"1喜欢芒果"
然后你建立了一个规则,基本上评估为:
left_hand_side :- right_hand_side. left_hand_side 如果 right_hand_side
将规则评估为查询会尝试匹配事实并true在可能的情况下返回,如果不匹配则返回false.需要注意的一件重要事情是,如果指定,prolog将继续匹配事实,只要规则评估为true.
让我们一步一步来 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}
| ?-
Run Code Online (Sandbox Code Playgroud)
最后一两件事要注意:如果代替按;在true ?提示符下,只好我按下<ENTER>,脚本会只用完成true.
我很高兴你问这个问题'因为它让我对prolog做了一个小小的复习,我很喜欢但很长一段时间都没用过.