【问题标题】:Why is this prolog query both true and false?为什么这个序言查询既真又假?
【发布时间】:2011-03-20 09:18:53
【问题描述】:

我的 SWI-Prolog 知识库包含以下两个事实:

f(a,b).
f(a,c).

现在如果我提出问题

?- f(a,c).
true.

但是

?- f(a,b).
true ;
false.

为什么 f(a,b) 既为真又为假?当知识库中有三个事实时,也会发生这种情况。如果我附加 f(a,d)。到 KB,则 f(a,d) 为真(仅),但 f(a,b) 和 f(a,c) 既为真又为假。发生了什么事,我该怎么做才能使 Prolog (仅)正确回答这些查询?

【问题讨论】:

    标签: prolog swi-prolog prolog-toplevel


    【解决方案1】:

    除了迈克尔威廉姆森的回答。如果你想告诉 Prolog 在第一次成功命中后停止寻找答案,那么使用 cut (!):

    ?- f(a, b), !.
    true.
    
    ?- f(a, c), !.
    true.
    

    【讨论】:

      【解决方案2】:

      (注意:这个答案有点猜测)

      考虑 Prolog 如何确定f(a,c) 是否为真。它检查第一条规则f(a,b),没有找到匹配项,但第二条规则f(a,c) 匹配。因此,f(a,c) 为真。此外,由于f 没有更多规则,因此允许回溯发生是没有意义的——没有其他可能的解决方案。

      现在考虑f(a,b)。 Prolog 将检查第一条规则,并找到匹配项。因此,f(a,b) 为真。但是,并非所有规则都已用尽。因此,Prolog 将允许继续搜索(如果您点击;)。当您继续搜索和回溯时,它会发现剩余的规则,特别是f(a,c),与f(a,b) 不匹配。因此,结果为假。

      【讨论】:

      • 这个答案是正确的。在 Prolog 中,您的事实是规则的写入顺序决定了它们将被查询找到的顺序。更具体地说,“回溯”选项“;”本质上告诉强制查询引擎丢弃返回的结果并回答问题“是否有任何其他答案?”。所以,并不是 f(a,b) 既真又假;而是它是真的,如果您选择忽略该结果,引擎会告诉您没有其他 f(a,b) 事实条目。为了证明这一点,请观察如果添加第二个 f(a,b) 事实会发生什么。
      • 这也说明了为什么如果你关心性能,你应该注意你的论点的顺序。如果谓词f 中的参数顺序颠倒了,则不会发生这种情况,因为初始参数不再相同,因此不要留下选择点。发生这种情况是因为大多数 prologs 执行参数索引,这允许预先从搜索空间中删除具有不兼容参数的谓词。 SWI Prolog 默认只索引第一个参数,但可以更改。
      猜你喜欢
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      • 2020-03-12
      相关资源
      最近更新 更多