Просто для развлечения, это не совсем тот ответ, который вы ищете, если понимать название вопроса буквально:
?- _ == _ .
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).
или, используя лямбда-выражение:
print_tree_minimums(Refs) :-
meta::map([Ref]>>(optional(Ref)::if_present(write)), Refs).
Этот ответ становится длинным, и я не хочу превращать его в общее обсуждение плюсов и минусов опций и ожидаемых. Но описания как концепций, так и библиотек найти легко. Например.
https://en.wikipedia.org/wiki/Option_type
https://youtu.be/NhcHwkUPX7w
person
Paulo Moura
schedule
21.11.2018
=
Пролога - это не просто способ спросить, равны ли две вещи, это сердце и душа самого объединения, которое является одним из двух основных отличий Пролога от всех других языков. Было бы довольно странно и неприятно, если бы этот оператор иногда не объединялся просто потому, что приходил какой-то императивный программист, желавший повторить ошибка в миллиард долларов. Опять же, вы можете создать свой собственный предикат равенства, но, как вы подозреваете, null - это просто плохая идея, которой нет места в декларативном программировании. - person Daniel Lyons   schedule 21.11.2018null
. Как показывает ваш код в этом ответе, работа со случаемnull
становится немного громоздкой. Легче просто определить предикат так, чтобы он был успешным, если есть минимум, но не работал в противном случае. Что лучше? Это зависит от варианта использования, который часто не задается в таких вопросах. - person lurker   schedule 21.11.2018null
сам по себе, как вы говорите, всего лишь атом. У него нет истинной ценности.null \= null
должно быть ложным, посколькуnull
является атомом, а в Прологе, если два атома идентичны, они обязательно (тривиально) унифицируемы. - person lurker   schedule 21.11.2018null
это атом. То, что я пытаюсь задать такими плохими и трудными для понимания словами, - это как чисто смоделировать недостаток информации о ценности в Прологе. - person   schedule 22.11.2018