Что никогда не бывает равным самому себе?

Есть ли в Прологе ценность, отличная от самой себя? Я пишу ответ на некоторый вопрос о min дерева, и в этом ответе также говорится, что если дерево пусто, min равно нулю. Сначала звучит хорошая идея, но теперь, когда я думаю, это звучит как плохая идея.

Это нормально, если null <> null, нет проблем. Но в Прологе я вижу, что null - это просто атом, поэтому ....

?- null = null.
true.

?- null == null.
true.

?- dif(null, null).
false.

Как я могу сделать какой-нибудь термин в Прологе, который всегда говорит:

?- dif(Something, Something).
true.

Но если это что-то другое, а не этот термин, это null вещь, все равно сказать false.?

Или, если это не то, как я должен думать в Прологе, тогда как мне думать не о true. и также не о false., а о «ни истинном, ни ложном, потому что чего-то не хватает»?


person Community    schedule 21.11.2018    source источник
comment
Это невозможно, вам придется создать свой собственный предикат с семантикой, которую вы хотите, вероятно, путем сопоставления с образцом на атоме, например null.   -  person Daniel Lyons    schedule 21.11.2018
comment
@DanielLyons, но откуда вы знаете, что это невозможно? Если это возможно, но вы не знаете, то же самое, что невозможно? Потому что в Прологе, если это неправда, это ложь, но на самом деле, если это не правда, может быть, это тоже не ложь, но мы просто этого не знаем. Как null.   -  person    schedule 21.11.2018
comment
Оператор = Пролога - это не просто способ спросить, равны ли две вещи, это сердце и душа самого объединения, которое является одним из двух основных отличий Пролога от всех других языков. Было бы довольно странно и неприятно, если бы этот оператор иногда не объединялся просто потому, что приходил какой-то императивный программист, желавший повторить ошибка в миллиард долларов. Опять же, вы можете создать свой собственный предикат равенства, но, как вы подозреваете, null - это просто плохая идея, которой нет места в декларативном программировании.   -  person Daniel Lyons    schedule 21.11.2018
comment
Что касается ответа на другой вопрос, то вам решать, хотите ли вы получить список, в котором действительно нет минимума для фактического успеха с минимум null. Как показывает ваш код в этом ответе, работа со случаем null становится немного громоздкой. Легче просто определить предикат так, чтобы он был успешным, если есть минимум, но не работал в противном случае. Что лучше? Это зависит от варианта использования, который часто не задается в таких вопросах.   -  person lurker    schedule 21.11.2018
comment
Потому что в Прологе, если это неправда, это ложь, но на самом деле, если это неправда, возможно, это тоже не ложь, но мы просто этого не знаем. Да, но ложь означает недоказуемость. Пролог может сказать вам, только если он может что-то доказать. Если не может, значит, не получится. У него нет способа познать вселенную того, что возможно, но не может быть доказано с помощью данных фактов / правил. Так что ответа на этот вопрос быть не может. null сам по себе, как вы говорите, всего лишь атом. У него нет истинной ценности. null \= null должно быть ложным, поскольку null является атомом, а в Прологе, если два атома идентичны, они обязательно (тривиально) унифицируемы.   -  person lurker    schedule 21.11.2018
comment
@lurker Я так понимаю, что null это атом. То, что я пытаюсь задать такими плохими и трудными для понимания словами, - это как чисто смоделировать недостаток информации о ценности в Прологе.   -  person    schedule 22.11.2018
comment
@DanielLyons Вы кажетесь таким уверенным и объясняете такие простые вещи, но я не уверен, что вы понимаете, о чем спрашивает мой вопрос. Я, конечно, пишу плохой вопрос, потому что людям сложно понять концепцию. Прошу прощения за глупый вопрос :-(   -  person    schedule 22.11.2018
comment
Буквальный ответ на ваш буквальный вопрос: вы не можете. Пауло ознакомился с вашим намерением и дал вам интересный ответ, но он все же более сложен, чем изменение унификации (и характерен для определенного диалекта Пролога). Тем не менее, я не думаю, что глупо задавать подобные вопросы. Это указывает на замешательство, но замешательство - это суть обучения. Вы не можете научиться, если не запутались. Но в обучении нет места стыду, поэтому, если я вас обидел, прошу прощения.   -  person Daniel Lyons    schedule 22.11.2018
comment
Думаю, в своем комментарии я объяснил, как справиться с отсутствием информации о стоимости. Как я уже упоминал, ответ Пролога false на самом деле не означает, что запрос не может быть истинным, если дана адекватная информация. Скорее, это означает, что это невозможно доказать с помощью известной информации (фактов и правил). Я не понимаю, как это можно сделать, если вы не укажете правила в отношении недостающей информации. Но затем, конечно, вы предоставили некоторую недостающую информацию. :)   -  person lurker    schedule 22.11.2018
comment
Однако я подозреваю, что я, вероятно, не полностью понимаю вашу мысль.   -  person lurker    schedule 22.11.2018
comment
@lurker Я подозреваю, что не совсем понимаю свою мысль. Я отредактирую вопрос, чтобы помочь понять, когда у меня будет время подумать.   -  person    schedule 22.11.2018


Ответы (1)


Просто для развлечения, это не совсем тот ответ, который вы ищете, если понимать название вопроса буквально:

?- _ == _ .
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
comment
Блестящий ответ, большое спасибо, Пауло Моура! Так это как-то похоже на опцию в Java, если я правильно прочитал? Это все еще не решает проблему, но лучше, чем ох, вы не можете. - person ; 22.11.2018
comment
Спасибо. Опции Java действительно предоставляют аналогичные функции. - person Paulo Moura; 22.11.2018
comment
Я пока не могу принять ответ, потому что теперь понимаю, что никто на самом деле не понял мой вопрос, который был не очень хорошим. Тем не менее, вы даете отличный ответ, и я постараюсь задать лучший вопрос и опробовать ваш подход, который вы объясняете в этом ответе. - person ; 22.11.2018
comment
@MunDong, в таких обстоятельствах было бы лучше принять ответ Пауло, а затем задать новый вопрос, если он будет достаточно другим, чтобы потребовать другого ответа. - person Daniel Lyons; 23.11.2018
comment
@DanielLyons Большое спасибо за ваше любезное предложение. Но если ответ не отвечает на вопрос или если я еще не знаю наверняка, отвечает ли он на вопрос, потому что я еще не пробовал код самостоятельно, вы можете любезно подождать, пока я не узнаю наверняка, тогда я могу принять отвечать. - person ; 23.11.2018