理解规则 - 错误作为答案

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)

我想知道这种错误背后的原因.

aqu*_*qua 7

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做了一个小小的复习,我很喜欢但很长一段时间都没用过.