41

我面临的问题有点微不足道。我想在 Prolog 中不使用逻辑,但似乎这not/1不是我想要的:

course(ai).
course(pl).
course(os).

have(X,Y) :- course(X),course(Y),not(X = Y).

我查询:

have(X,Y), write(X-Y), nl , fail.

而且我没有得到我想要的结果:(

4

5 回答 5

42

代替not(X = Y)你需要写\+ X = Yor X \= Y。但考虑改为使用dif(X,Y)dif/2存在于 B、SWI、YAP、SICStus。要查看差异:

?- X = b, dif(a, X).
X = b.

?- X = b, \+ a = X.
X = b.

所以到目前为止,一切似乎都很好。但是,如果我们简单地交换两个目标的顺序呢?

?- \+ a = X, X = b.
false.

?- dif(a, X), X = b.
X = b.

(\+)/1现在给我们一个不同的结果,因为 有一个答案a = X,目标\+ a = X将失败。

(\+)/1因此不是否定的,而是意味着在这个时间点上不可证明

在 ISO Prolog中dif/2也可以安全地近似。

于 2011-12-15T17:01:31.253 回答
14

在 SWI-Prolog 和 GNU Prolog 中,以下内容应该有效:

have(X, Y) :- course(X), course(Y), X \= Y.

在 SWI-Prolog 中,您还可以使用dif/2,这会更方便,因为您可以在谓词中更早地使用它:

have(X, Y) :- dif(X, Y), course(X), course(Y).
于 2011-12-15T17:00:38.410 回答
6

作为上述用户“false”的答案的补充,即

"代替 not(X = Y) 你需要写 \+ X = Y,"

这可能给人的印象是:

一个。"not" 和 "\+" 是不同的东西

湾。\+ 会起作用,而 not 会,错误,不会。

我的理解是“not”和“\+”是等价的,但是在现代Prolog程序中首选\+,因为它传达了一种更直观的感觉。具体来说,虽然“不”可能对粗心的编码人员表示“不正确”,但“\+”表示“不可证明”,这更接近于该操作的真实含义。在 Prolog 中,“not”是“negation as failure”的一个例子,但感觉 \+ 将使程序员更清楚地知道在任何给定规则中断言的确切内容。因此,您可以使用“不”(大多数 PL 实现保留它是为了向后兼容),但要成为惯用的现代 PL 程序员,您可能应该更喜欢使用 \+。

于 2014-03-17T21:37:06.087 回答
3

阅读 Samuel Kamin 关于第 8 章序言的,我发现这个解决方案也适合这里,并解释了如何使用cut

剪切是一种让程序员额外控制计算的方法,允许他指出不允许回溯的地方。具体来说,cut 被写成一个感叹号 (!),作为一个目标出现在一个子句的右侧,例如:

G :- H, !, R.

假设选择这个子句是为了满足与 G统一的目标g。尝试满足 H。如果成功,则证明 R。如果 R 的证明成功,则 g 被证明;在这种情况下,剪辑没有任何作用。然而,如果 R 的证明失败,而不是回溯并尝试重新证明 H,割的存在会导致目标 g 立即失败;即使有可能适用于 g 的其他条款也会发生这种情况。一个例子是not-equals的定义:

equals(X, X).
not-equals(X, Y) :- equals(X, Y), !, fail.
not-equals(X, Y).

not-equals(X, Y)如果 X 不等于 Y 则应该成功,如果是则失败;当试图满足这个目标时, X 和 Y 应该绑定到基本表达式(即没有自由变量)。

于 2018-03-24T03:44:40.370 回答
1

就像你说的,OP,这是微不足道的。

尝试

course(ai).
course(pl).
course(os).

have(X,Y) :- course(X), course(Y), X \== Y).

那应该可以解决您的谓词。

不过,向前迈出一步,从数学上讲,您可能正在寻找 (n C 2) 的解决方案,而不是您的谓词当前提供的 (n P 2) — 组合而不是排列,选择选择而不是选择安排的选择。这就是我的想法。

如果这是你想要的,我建议你试试

course(ai).
course(pl).
course(os).

have(X,Y) :- course(X), course(Y), X @< Y).

这将防止重复的反向结果。

@<意味着原子地小于。<是整数,@<是原子。

于 2013-05-31T08:51:21.857 回答