prolog - 什么永远不等于自己?
问题描述
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 系统中使用它们。看:
和
您使用一个库或另一个库取决于您对“缺失”的解释,这意味着某些东西是可选的(没有值是好的)或预期的(没有值是错误的)。例如,假设在您的特定应用程序中,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).
这个答案越来越长,我不想把它变成对optionals和Expects优缺点的一般性讨论。但是很容易找到关于概念和库的描述。例如
推荐阅读
- excel - Excel VBA - 从不正确的工作簿中删除行/列的问题
- reactjs - react context provider在渲染方法中抛出错误
- ios - 嵌套请求的完成块
- ios - 以编程方式在 iOS 中为所有应用程序启用/禁用相机(全局)
- java - 让 Hazelcast Native Client 与 Hibernate 5.2.x 一起工作
- c# - 防止两个组合框选择同一个项目
- python - TypeError:一元操作数类型错误〜:float
- ruby-on-rails - 如何动态链接rails中的where子句?
- asp.net-core - 表 'Ratings' 上的 'FK_Ratings_Users_UserId' 可能会导致循环或多个级联路径
- jquery - 如何在所选选项多于一行时添加类?