Отрицание как неудача обычно считается нечистым. Интерпретатор Пролога, необходимый для отрицания ошибки, должен реализовать SLDNF, который является расширением SLD.
Предикат (\=)/2
, например, используется в библиотеке (reif). Он может быть загружен через отрицание как отказ следующим образом, но часто является встроенным:
X \= Y :- \+ X = Y.
Можно ли реализовать (\=)/2
как чистый предикат? Использование только чистого Пролога, то есть только роговых предложений первого порядка?
if-then-else является базовым стандартом ISO Prolog, базовый стандарт ISO обеспечивает SLDNF и немного больше, а не только SLD. Но это не роговые предложения первого порядка. В вопросе требуется чистая реализация Пролога, а чистота указана в вопросе как предложения рога первого порядка.
@WillemVanOnsem ->
и fail
не являются рогами.
Если бы было возможно реализовать \=
на чистом Прологе, то мы могли бы также реализовать пересечение списков на чистом Прологе (см. ответ Дэвида здесь). Последнее пока никому не удавалось. Если мы даже этого не можем сделать, это заставляет вас усомниться в парадигме логического программирования в целом.
фейл - Хорн. Только не определяй. Пустое количество предложений Хорна для неудачи. Например, в базовом прологе ISO вы можете определить его как :- dynamic fail/0. И если вы ничего не утверждаете, это будет вести себя как встроенный отказ.
Можно ли реализовать (=)/2 как чистый предикат? Использование только чистого Пролога, то есть только роговых предложений первого порядка?
Вы не можете реализовать (\=)/2
на чистом Прологе.
Доказательство:
В логике конъюнкция коммутативна, и запросы на чистом Прологе, если они заканчиваются, должны быть логическими.
Однако с (\=)/2
порядок терминов имеет значение, поэтому это не логично:
?- X \= Y, X=0, Y=1.
false.
?- X=0, Y=1, X \= Y.
X = 0,
Y = 1.
X \= Y :- X = Y -> fail; true.