问题
Is there value in Prolog that is not equal to itself? I write answer to some question about min of tree and this answer also says that if tree is empty min is null. Sounds good idea first but now when I think it sounds like bad idea.
It is kinda OK if null <> null
, no problem. But in Prolog I see null is just atom so....
?- null = null.
true.
?- null == null.
true.
?- dif(null, null).
false.
How can I make some term in Prolog that always say:
?- dif(Something, Something).
true.
But if it is any other thing and not this term that is the null
thing still say false.
?
Or if this is not how I should think in Prolog then how should I think about not true.
and also not false.
but "neither true nor false because something is missing"?
回答1:
Just for fun, not really the answer you're looking for, taking the question title quite literally:
?- _ == _ .
false.
But dif/2
is not fouled (hint: each occurrence of the anonymous variable represents a different variable):
?- dif(_, _).
true.
Now, seriously. Starting with your tree minimum predicate example, there's a trivial alternative: the predicate can simply fail when the tree is empty. A better alternative may be to use optional or expected term libraries. The concepts behind these libraries are found in several programming languages, where they provide a better alternative to null. You have both libraries in Logtalk, which you can use with most Prolog systems. See:
- https://logtalk.org/library/optional_0.html
- https://logtalk.org/library/optional_1.html
and
- https://logtalk.org/library/expected_0.html
- https://logtalk.org/library/expected_1.html
You use one library or the other depending on your interpretation of "missing" meaning something that is optional (absence of a value is fine) or expected (absence of a value is an error). For example, assume that in your particular application it makes sense to use 0
as the minimum value of an empty tree when doing a specific computation (e.g. the sum of the minimums of a set of trees). If the tree minimum predicate returns an optional term reference, Ref
, instead of an integer, you could do e.g.
...,
optional(Ref)::or_else(Minimum, 0),
Sum1 is Sum0 + Minimum,
...
This is a cleaner solution compared with using an if-then-else construct:
...,
( tree_minimum(Tree, Minimum) ->
Sum1 is Sum0 + Minimum
; Sum1 is Sum0
),
...
It also allows you to use different defaults for different computations. For example:
...,
optional(Ref)::or_else(Minimum, 1),
Product1 is Product0 * Minimum,
...
More important, it doesn't mask that you're processing an empty tree in the same way that a default value would do. For example, the following code will only write the minimum values of non-empty trees:
print_tree_minimums(Refs) :-
meta::map(print_tree_minimum, Refs).
print_tree_minimum(Ref) :-
optional(Ref)::if_present(write).
or, using a lambda expression:
print_tree_minimums(Refs) :-
meta::map([Ref]>>(optional(Ref)::if_present(write)), Refs).
This answer is getting long and I don't want to transform it into a general discussion of the pros and cons of optionals and expecteds. But descriptions on both concepts and libraries is easy to find. E.g.
https://en.wikipedia.org/wiki/Option_type
https://youtu.be/NhcHwkUPX7w
来源:https://stackoverflow.com/questions/53405266/what-is-never-equal-to-itself