我是 Prolog 的新手,我只是在想为什么这个规则在一个正确的结果之后给我错误的结果。

likes(1,banana).
likes(1,mango).

test :- likes(1,banana),likes(1,mango).

?- test.  
true;  
false.

我想知道这个错误背后的原因。

有帮助吗?

解决方案

prolog 的工作方式是评估查询,直到因否定而失败。

在这里,您已经确定了两个事实:

likes(1, banana). 上面写着“1喜欢香蕉”

likes(1, mango). 上面写着“1喜欢芒果”

然后你就建立了一条规则,其基本评估如下:

left_hand_side :- right_hand_side. left_hand_side 如果 right_hand_side

作为查询尝试匹配事实并返回的规则的评估 true 如果可以匹配,则为 false,如果不能匹配则为 false。需要注意的一件重要事情是,如果指定,只要规则评估为,序言将继续匹配事实 true.

那么让我们逐步了解一下 test :- likes(1,banana),likes(1,mango).

如果 test 作为查询运行,prolog 首先尝试 likes(1,banana) 这是先前已确定的事实,也是事实。然后,它继续到 likes(1,mango) 这又是事实,而且是真的。然后 Prolog 到达规则的末尾,并输出 true.

此时,如果您不搜索更多匹配项,则可以缩短查询并只使用 true。但是,如果您正在寻找更多(所有)匹配项,请序言 回溯 并尝试再次评估规则,搜索更多匹配项。

但是,由于您的规则仅匹配“喜欢香蕉和喜欢芒果”,而我们已经匹配了 likes(1,banana), ,当 prolog 回溯并尝试评估时 likes(1,banana) 再次,由于我们之前已经匹配过它,所以这次没有另一个事实(换句话说,1 不能多次“喜欢”香蕉,除非已定义)可以匹配。所以这就是 false 来自。

在您的序言解释器中,您可以通过输入来跟踪程序的执行 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.

我很高兴你问这个问题,因为它让我对序言有了一点小小的回顾,我真的很喜欢它,但已经很长时间没有使用了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top