如何在序言中正确表达不平等?
How to properly express inequality in prolog?
TL;DR: sibling(a,X)
成功获得答案 X = a
,但 sibling(a,a)
失败。
我有以下 Prolog 文件:
children(a, c).
children(a, d).
children(b, c).
children(b, d).
sibling(X, Y) :-
X \== Y, A \== B,
children(X, A), children(X, B),
children(Y, A), children(Y, B).
对我来说似乎很清楚,如果 parents 相同,那么两个人就是兄弟姐妹。还有,一个人不是自己的兄弟姐妹。
但是当我尝试 运行 在 GNU Prolog 上进行一些查询时,我得到了一些奇怪的结果:
| ?- sibling(a, b).
true ? a
true
true
yes
这是预期的行为。 a
和 b
是兄妹。有三个结果,这有点奇怪,但我假设 Prolog 绑定了 A = c, B = d
和 A = d, B = c
.
| ?- sibling(a, a).
no
我认为这意味着 a
和 a
不是兄弟姐妹。
| ?- sibling(a, X).
X = a ? a
X = b
X = a
X = b
X = a
X = b
X = a
X = b
(15 ms) yes
这是我卡住的地方:它说 X = a
,这意味着 sibling(a,a)
是正确的,但是 sibling(a,a)
失败了 查询!
我觉得我不理解 \==
在 Prolog 中的实际作用。
这是怎么回事,我该如何解决?
尝试将不等式移动到谓词的末尾。也许它给你的是真的,因为它还没有实例化。
sibling(X,Y):- children(X, A), children(X, B),
children(Y, A), children(Y, B),
X \== Y, A \== B.
TL;DR: 使用 prolog-dif—or iso_dif/2
(on iso-prolog conforming systems like gnu-prolog)!
好问题,+1!
事实上,这是我问过自己的一个问题,答案与logical-purity有关:逻辑纯度是什么的核心方面
使 Prolog 作为一种语言如此特别,因为它使您能够:
- 描述—不开处方
- 编写关系代码——而不仅仅是功能代码
- 从问题/解决方案的角度思考——而不是搜索过程本身的各个步骤
- 在更高层次上运作——不要迷失在细节中
与许多其他编程语言不同,Prolog 程序同时具有过程语义(定义执行步骤及其顺序)和声明语义(允许您声明应该保持的关系并让 Prolog 处理器找到一个正确的执行方式).
但是,请注意: Prolog 有一些特性,在使用时,破坏 声明性语义。为防止这种情况,请尝试将您的应用程序分为两部分:不纯的 shell 用于处理副作用 (input/output) 和 一个逻辑上纯的基础,它包含纯单调的 Prolog 代码。
TL;DR: sibling(a,X)
成功获得答案 X = a
,但 sibling(a,a)
失败。
我有以下 Prolog 文件:
children(a, c).
children(a, d).
children(b, c).
children(b, d).
sibling(X, Y) :-
X \== Y, A \== B,
children(X, A), children(X, B),
children(Y, A), children(Y, B).
对我来说似乎很清楚,如果 parents 相同,那么两个人就是兄弟姐妹。还有,一个人不是自己的兄弟姐妹。
但是当我尝试 运行 在 GNU Prolog 上进行一些查询时,我得到了一些奇怪的结果:
| ?- sibling(a, b).
true ? a
true
true
yes
这是预期的行为。 a
和 b
是兄妹。有三个结果,这有点奇怪,但我假设 Prolog 绑定了 A = c, B = d
和 A = d, B = c
.
| ?- sibling(a, a).
no
我认为这意味着 a
和 a
不是兄弟姐妹。
| ?- sibling(a, X).
X = a ? a
X = b
X = a
X = b
X = a
X = b
X = a
X = b
(15 ms) yes
这是我卡住的地方:它说 X = a
,这意味着 sibling(a,a)
是正确的,但是 sibling(a,a)
失败了 查询!
我觉得我不理解 \==
在 Prolog 中的实际作用。
这是怎么回事,我该如何解决?
尝试将不等式移动到谓词的末尾。也许它给你的是真的,因为它还没有实例化。
sibling(X,Y):- children(X, A), children(X, B),
children(Y, A), children(Y, B),
X \== Y, A \== B.
TL;DR: 使用 prolog-dif—or iso_dif/2
(on iso-prolog conforming systems like gnu-prolog)!
好问题,+1!
事实上,这是我问过自己的一个问题,答案与logical-purity有关:逻辑纯度是什么的核心方面 使 Prolog 作为一种语言如此特别,因为它使您能够:
- 描述—不开处方
- 编写关系代码——而不仅仅是功能代码
- 从问题/解决方案的角度思考——而不是搜索过程本身的各个步骤
- 在更高层次上运作——不要迷失在细节中
与许多其他编程语言不同,Prolog 程序同时具有过程语义(定义执行步骤及其顺序)和声明语义(允许您声明应该保持的关系并让 Prolog 处理器找到一个正确的执行方式).
但是,请注意: Prolog 有一些特性,在使用时,破坏 声明性语义。为防止这种情况,请尝试将您的应用程序分为两部分:不纯的 shell 用于处理副作用 (input/output) 和 一个逻辑上纯的基础,它包含纯单调的 Prolog 代码。