6

我在 prolog 中使用以下代码实现了以下功能:

abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.

如何在不使用 cut ("!") 的情况下实现此功能?

4

3 回答 3

10

Prolog 的 if-then-else 结构中存在“隐藏”剪切:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.

这是一个怪癖,但 Prolog 不会回溯形成 if-then 或 if-then-else 构造的“前提”的子目标。在这里,如果 X < 0 第一次尝试成功,则选择“then”子句而不是“else”子句(因此将此行为描述为“隐藏”剪切)。

如问题中所写,谓词abs2/2的第一个子句中的剪切作用更多。正如 Nicholas 指出的那样,第二个子句末尾的删减没有任何效果(到达那里时没有选择点)。但正如 Kaarel 指出的那样,如果第一个子句成功,则存在一个选择点。

所以我会写的,允许使用剪辑,是这样的:

abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.

Nicholas 的评论还提出了将绝对值“算术化”(而不是使用逻辑定义)并避免以这种方式“切割”的方法。

于 2011-01-27T04:23:57.403 回答
6

我的序言有点生疏了,但你为什么还需要剪辑呢?如果你正确地编写谓词,回溯是不会成功的,所以cut是不必要的:

abs(X, Y) :- number(X) , X <  0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .
于 2011-01-26T20:08:16.387 回答
4

无需使用

简单地写:

abs2(X,Y) :- Y is abs(X).
于 2015-05-26T07:14:07.180 回答