首页 > 解决方案 > 什么永远不等于自己?

问题描述

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.是,而是“既不是真的也不是假的,因为缺少某些东西”?

标签: prologprolog-dif

解决方案


只是为了好玩,而不是你正在寻找的答案,从字面上看问题标题:

?- _ == _ .
false.

但是没有被犯规(提示:匿名变量dif/2的每次出现代表一个不同的变量):

?- dif(_, _).
true.

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

您使用一个库或另一个库取决于您对“缺失”的解释,这意味着某些东西是可选的(没有值是好的)或预期的(没有值是错误的)。例如,假设在您的特定应用程序中,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).

这个答案越来越长,我不想把它变成对optionalsExpects优缺点的一般性讨论。但是很容易找到关于概念和库的描述。例如

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

https://youtu.be/NhcHwkUPX7w


推荐阅读