更改参数顺序时 Prolog 统一中断
Prolog unification broken when argument order is changed
我似乎无法理解这个问题。考虑以下虚拟谓词:
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
咨询时:
?- foo(1, a).
true;
false.
我不确定我是否完全理解选择点是如何创建的(也许是因为两个可能的 foo
谓词处于一种 or 关系和 Prolog只是 尝试 与两者统一?基于跟踪中的这一行: Redo: (24) test:foo(8, a)
和随后的失败,我想是这种情况),但真正让我困惑的是为什么它在更改参数顺序时起作用:
foo(a, X) :- X < 10.
foo(b, X) :- X > 20.
?- foo(a, 1).
true.
没有选择点。我在这里错过了什么?
TL;DR:阅读您正在使用的 Prolog 的文档。注意“子句索引”或类似的东西。
您错过了您正在使用的任何 Prolog 实现都足够聪明,可以对第二个示例中的第一个参数进行索引。因此,当您提出查询 ?- foo(a, Something).
时,它永远不会考虑其他子句。
但这实际上是 Prolog 实现的问题,而不是 Prolog 作为一种语言的问题。也许有Prologs也可以避免第一个例子中的选择点。或者它可能提供了一种不同的机制来实现相同的目标。例如 SWI-Prolog (在其他序言中)有一种叫做“制表”的东西。有了它,你可以这样做:
:- table foo/2.
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
bar(a, X) :- X < 10.
bar(b, X) :- X > 20.
现在foo/2
和bar/2
都没有意想不到的选择点:
?- foo(1, a).
true.
?- bar(a, 1).
true.
我似乎无法理解这个问题。考虑以下虚拟谓词:
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
咨询时:
?- foo(1, a).
true;
false.
我不确定我是否完全理解选择点是如何创建的(也许是因为两个可能的 foo
谓词处于一种 or 关系和 Prolog只是 尝试 与两者统一?基于跟踪中的这一行: Redo: (24) test:foo(8, a)
和随后的失败,我想是这种情况),但真正让我困惑的是为什么它在更改参数顺序时起作用:
foo(a, X) :- X < 10.
foo(b, X) :- X > 20.
?- foo(a, 1).
true.
没有选择点。我在这里错过了什么?
TL;DR:阅读您正在使用的 Prolog 的文档。注意“子句索引”或类似的东西。
您错过了您正在使用的任何 Prolog 实现都足够聪明,可以对第二个示例中的第一个参数进行索引。因此,当您提出查询 ?- foo(a, Something).
时,它永远不会考虑其他子句。
但这实际上是 Prolog 实现的问题,而不是 Prolog 作为一种语言的问题。也许有Prologs也可以避免第一个例子中的选择点。或者它可能提供了一种不同的机制来实现相同的目标。例如 SWI-Prolog (在其他序言中)有一种叫做“制表”的东西。有了它,你可以这样做:
:- table foo/2.
foo(X, a) :- X < 10.
foo(X, b) :- X > 20.
bar(a, X) :- X < 10.
bar(b, X) :- X > 20.
现在foo/2
和bar/2
都没有意想不到的选择点:
?- foo(1, a).
true.
?- bar(a, 1).
true.