Логическое отрицание в Prolog

Я читал довольно много о Prolog Negation by Failure, где Prolog для доказательства того, что \+Goal содержит попытки доказать, что Goal терпит неудачу.

Это сильно связано с CWA (близкое мировое предположение), где, например, если мы запрашиваем \+P(a) (где P - предикат arity 1), и мы не имеем никаких подсказок, которые приводят к доказать P(a) Prolog предполагает (из-за CWA), что not P(a) выполняется так, что \+P(a) преуспевает.

Из того, что я искал, это способ решить слабость классической логики, если бы мы не имели понятия о P(a), тогда мы не могли бы ответить, существует ли \+P(a).

То, что описано выше, способ введения в Prolog немонотонных рассуждений. Более того, интересная часть состоит в том, что Clark доказал, что Negation by Failure совместим/аналогично с классическим отрицанием только для основных предложений. Я понимаю это, например:

X=1, \+X==1.: должен возвращать false в Prolog (и в классической логике).

\+X==1, X=1.: должен возвращать false в классической логике, но он преуспевает в Prolog с тех пор, пока NF не рассматривается. X не связан, это отличается от классической Pure Logic.

\+X==1.: не должен давать никакого ответа в классической логике до тех пор, пока X не будет связан, но в Prolog он возвращает false (возможно, чтобы нарушить слабость классической логики), и это не то же самое/совместимо с чистой логикой.

Моя попытка состояла в том, чтобы моделировать классическое отрицание, благодаря @false предложениям в комментариях, текущая реализация:

\\+(Goal) :- when(ground(Goal), \+Goal). 

Некоторые тесты:

?- \\+(X==1).
when(ground(X), \+X==1).

?- X=1, \\+(X==1).
false.

?- \\+(X==1), X=1.
false. 

Мой вопрос:

Является ли приведенная выше правильная интерпретация классического отрицания? (Есть ли какие-либо очевидные угловые случаи, которые он пропускает? Также я обеспокоен логикой Purity при использовании, когда /2, можно ли предположить, что вышеописанное чисто?).

Ответ 1

Пролог не может выполнять классическое отрицание. Поскольку это не используйте классический вывод. Даже в присутствии Кларка завершение, он не может обнаружить следующее два классических закона:

Закон непротиворечия: ~ (p/\ ~ p)

Закон исключенного среднего: p \/~ p

Вот пример, возьмите эту логическую программу и эти запросы:

   p :- p

   ?- \+(p, \+p)

   ?- p; \+p

Завершение Clark логической программы следующим образом, а отрицание - как запрос сбоя выполнение дает следующее:

   p <-> p

   loops

   loops

Завершение Кларка указывает на проблему определения предикатов и отрицательная информация. См. Также раздел 5.2 Правила и их завершение. С другой стороны, когда нет предиката определения существуют, CLP (X) иногда может выполнять оба закона, когда оператор отрицания определяется стилем deMorgan. Здесь оператор отрицания для CLP (B):

?- listing(neg/1).
neg((A;B)) :-
    neg(A),
    neg(B).
neg((A, _)) :-
    neg(A).
neg((_, A)) :-
    neg(A).
neg(neg(A)) :-
    call(A).
neg(sat(A)) :-
    sat(~A).

И вот какое выполнение:

?- sat(P); neg(sat(P)).
P = 0 
P = 1.
?- neg((sat(P), neg(sat(P)))).
P = 0 
P = 1.

CLP (X) также будет иметь проблемы, когда отрицание влияет на домены, которые обычно являются конечными, и тогда они будут бесконечными. Таким образом, для Например, ограничение, такое как (# =)/2,... не должно быть проблемой, так как его можно заменить ограничением (#\=)/2,....

Но отрицание для CLP (FD) обычно не работает при применении к ограничениям (В)/2. Ситуацию можно слегка смягчить, если система CLP (X) предлагает материализация. В этом случае дизъюнкция может быть немного более разумной, чем просто использование дизъюнкции обратного слежения Prolog.