从来没有等于自己的东西?

时间:2018-11-21 04:28:15

标签: prolog prolog-dif

Prolog中的价值是否不等于自身?我将answer写到某些question about min of tree上,这个答案还说,如果树为空,则min为null。首先听起来是个好主意,但现在我觉得这听起来像个坏主意。

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

?- null = null.
true.

?- null == null.
true.

?- dif(null, null).
false.

我该如何在Prolog中经常说一句话:

?- dif(Something, Something).
true.

但是如果是其他事情而不是null这个词,还说false.吗?

或者如果这不是我应该在Prolog中思考的方式,那么我应该如何考虑不是true.也不是false.,而是“因为缺少了某些东西,所以不是真假”?

1 个答案:

答案 0 :(得分:3)

只是为了好玩,并不是您真正想要的答案,而是直接从字面上回答问题标题:

?- _ == _ .
false.

但是dif/2不受污染(提示:每次匿名变量都代表一个不同的变量):

?- dif(_, _).
true.

现在,认真。从树最小谓词示例开始,有一个琐碎的选择:当树为空时,谓词可能会失败。更好的替代方法是使用 optional expected 术语库。这些库背后的概念可以在几种编程语言中找到,它们为 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).

这个答案越来越长,我不想将其转变成对 optional expected 的优缺点的一般讨论。但是,很容易找到有关概念和库的描述。例如

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

https://youtu.be/NhcHwkUPX7w