【发布时间】:2021-02-13 05:47:27
【问题描述】:
我似乎无法理解这一点。考虑以下虚拟谓词:
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
咨询时:
?- foo(1, a).
true;
false.
我不确定我是否完全理解选择点是如何创建的(也许是因为两个可能的foo 谓词处于一种 or 关系,而 Prolog 只是 尝试 em> 与两者统一?基于跟踪中的这一行:Redo: (24) test:foo(8, a) 和随后的失败,我想是这种情况),但真正让我困惑的是为什么它在参数顺序改变时起作用:
foo(a, X) :- X < 10.
foo(b, X) :- X > 20.
?- foo(a, 1).
true.
没有选择点。我在这里错过了什么?
【问题讨论】:
-
Prolog 通常会在第一个参数上“索引”。所以它知道
b永远不会是一个很好的匹配,并跳过它。 -
好的,但是为什么它不知道在第一种情况下,即使
X可以匹配,b仍然不匹配? -
因为对于大多数 Prolog 解释器来说,这个索引只在 first 参数上完成。通常 Prolog 程序的编写是为了区分函子,第一个参数用于提高效率。
-
这也不是很重要(除了如果剩余的选择点开始在长时间运行/深度程序中影响性能 - 这确实很快)。只要
findall(found, foo(1,a), All)吐出一个解决方案[found],就很好。添加一个“!”或“-”,使 Prolog 处理器在保护测试后“提交”其子句:foo(X) :- guard(X),!,do_sth(X).或(可能更清楚)foo(X) :- guard(X) -> do_sth(X).以增加确定性,同时确保findall/3收集的解决方案保持不变。 -
我明白了,这就是Prolog中的就像这样。 @DavidTonhofer 我为什么要这样做,而不是在我已经切割时使用
foo(1, a), !.?谢谢你们,请你们中的一个人也可以创建一个答案,以便我可以选择它作为解决方案吗?
标签: prolog logic unification