Prolog的逻辑"不"是什么?

Mas*_*rah 35 prolog prolog-dif

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

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

have(X,Y) :- course(X),course(Y),not(X = Y).
Run Code Online (Sandbox Code Playgroud)

我查询:

have(X,Y), write(X-Y), nl , fail.
Run Code Online (Sandbox Code Playgroud)

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

fal*_*lse 36

代替not(X = Y)你需要写\+ X = YX \= Y.但请考虑dif(X,Y)改用.dif/2存在于B,SWI,YAP,SICStus中.要看到差异:

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

?- X = b, \+ a = X.
X = b.
Run Code Online (Sandbox Code Playgroud)

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

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

?- dif(a, X), X = b.
X = b.
Run Code Online (Sandbox Code Playgroud)

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

(\+)/1因此,这不是否定,而是指在此时无法证明.

dif/2ISO Prolog 中也可以安全地进行近似.

  • 为了完整起见,这个"声音否定"在ECLiPSe中也可用,使用`〜/ 2`或`〜=/2`,等效查询将是`? - 〜(a = X),X = b .`或`? - a~ = X,X = b (3认同)

Fre*_*Foo 14

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

have(X, Y) :- course(X), course(Y), X \= Y.
Run Code Online (Sandbox Code Playgroud)

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

have(X, Y) :- dif(X, Y), course(X), course(Y).
Run Code Online (Sandbox Code Playgroud)

  • 无论如何,OP标记了swi-pl而没有检查swi我猜是因为他的版本适用于swi,即使没有/ 1在那里被弃用. (7认同)

Kai*_*ain 5

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

“代替not(X = Y),您需要编写\ + X = Y,”

这可能给人的印象是:

一种。“ not”和“ \ +”是不同的东西

b。\ +将起作用,而不是,则不会。

我的理解是“ not”和“ \ +”是等效的,但是\ +在现代Prolog程序中是首选,因为它传达了一种更直观的感觉。具体而言,尽管“不”可能暗示粗心的编码器“不正确”,但“ \ +”却暗示“不可证明”,这与该操作实际上在说什么很接近。在Prolog中,“不是”是“否定即失败”的一个示例,但是可以感觉到\ +将使程序员更清楚在任何给定规则中确切地断言了什么。因此,您可以使用“ not”(大多数PL实现将其保留为向后兼容),但要成为惯用的现代PL程序员,您可能应该更喜欢使用\ +。


Nil*_*oct 5

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

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

G :- H, !, R.
Run Code Online (Sandbox Code Playgroud)

假设选择该子句是为了满足与 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).
Run Code Online (Sandbox Code Playgroud)

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