什么永远不等于自己



Prolog中是否存在不等于自身的值?我写了一些关于树的最小值的问题的答案,这个答案还说,如果树是空的,最小值就是空的。起初听起来是个好主意,但现在我觉得这听起来是个坏主意。

如果null <> null也可以,没问题。但在Prolog中,我看到null只是原子,所以…

?- null = null.
true.
?- null == null.
true.
?- dif(null, null).
false.

我如何才能在Prolog中创造一些术语,总是说:

?- dif(Something, Something).
true.

但如果是任何其他的东西,而不是这个术语,那么null的东西仍然说false.

或者,如果我在Prolog中不应该这样想,那么我应该如何看待true.false.,而不是"既不正确也不错误,因为缺少了一些东西"?

只是为了好玩,并不是你真正想要的答案,把问题标题改成字面意思:

?- _ == _ .
false.

dif/2没有被破坏(提示:匿名变量的每次出现都代表一个不同的变量(:

?- dif(_, _).
true.

现在,说真的。从树最小谓词示例开始,有一个简单的替代方案:当树为空时,谓词可能会失败。更好的选择可能是使用可选预期术语库。这些库背后的概念可以在几种编程语言中找到,它们为null提供了更好的替代方案。Logtalk中有这两个库,可以与大多数Prolog系统一起使用。参见:

  • https://logtalk.org/library/optional_0.html
  • https://logtalk.org/library/optional_1.html

  • https://logtalk.org/library/expected_0.html
  • https://logtalk.org/library/expected_1.html

您使用一个或另一个库,这取决于您对"missing"的解释,即可选(没有值可以(或预期的东西(没有值是错误(。例如,假设在您的特定应用程序中,在执行特定的计算时,使用0作为空树的最小值是有意义的(例如,树集的最小值之和(。如果树最小谓词返回一个可选的术语引用Ref,而不是整数,则可以执行例如

...,
optional(Ref)::or_else(Minimum, 0),
Sum1 is Sum0 + Minimum,
...

与使用if-then-else结构相比,这是一个更清洁的解决方案:

...,
(   tree_minimum(Tree, Minimum) ->
Sum1 is Sum0 + Minimum
;   Sum1 is Sum0
),
...

它还允许您对不同的计算使用不同的默认值。例如:

...,
optional(Ref)::or_else(Minimum, 1),
Product1 is Product0 * Minimum,
...

更重要的是,它不会像默认值那样掩盖你正在处理一个空树。例如,以下代码只会写入非空树的最小值:

print_tree_minimums(Refs) :-
meta::map(print_tree_minimum, Refs).
print_tree_minimum(Ref) :-
optional(Ref)::if_present(write).

或者,使用lambda表达式:

print_tree_minimums(Refs) :-
meta::map([Ref]>>(optional(Ref)::if_present(write)), Refs).

这个答案越来越长,我不想把它转化为对选项预期的利弊的一般性讨论。但是关于概念和库的描述很容易找到。例如

https://en.wikipedia.org/wiki/Option_type

https://youtu.be/NhcHwkUPX7w

最新更新