Подтвердить что ты не робот

Пролог подразумевает отрицательный предикат

Как я могу написать следующее правило в PROLOG: , если P, а не Q

Я понимаю, что вы можете легко написать, если P тогда Q предикаты, такие как q(X) :- p(X), но как вы можете отменить предикат q/1? Я не хочу определять новые предикаты с другой семантикой, например non_q/1.

4b9b3361

Ответ 1

Предложение "если P, а не Q" логически эквивалентно отрицательному предложению "не P ИЛИ не Q". Таким образом, это предложение Хорна без положительного литерала и как применение соответствия доказательств теоремы SLD и предложений Хорна, может быть представлено в Пролог-программирование как предложение цели или "запрос":

?- P, Q.

Вернемся к этой идее через минуту.

Но предложение цели, возможно, не такое представление, которое вы имеете в виду. Факты и правила, составляющие базу знаний "Пролог", являются определенными положениями, т.е. Предложениями Хорна, каждая из которых имеет ровно один положительный литерал. "Если P, а не Q", не имеет положительного литерала, поэтому в этом смысле он не может быть представлен (как определенный пункт).

Вышеуказанное предложение цели "спрашивает", если оба доказательства P и Q могут быть доказаны. В Prolog содержится понятие "отрицание как сбой", поэтому более естественным способом "спросить" будет ли "не P ИЛИ не Q":

?- not((P,Q)).

Тогда мы получим успех, если либо P, либо Q не удастся, и сбой, если оба успеха.

Однако, если ваша цель - утверждать отрицание чего-то в базе знаний, Prolog, естественно, не поддерживает это. В зависимости от вашего приложения может быть разумный способ обойти синтаксис Prolog и выполнить то, что необходимо (всегда есть необоснованный способ сделать это, как вы намекали, как с предикатом non_q),.

Ответ 2

Вы когда-нибудь слышали о сокращении Prolog?

Во всяком случае, я мало знаю о стандарте Prolog, но в SWI-Prolog символ \+ означает отрицание. Я знаю, что ему не нужно работать в каждом интерпретаторе Prolog.

Вы можете сделать отрицание предиката с помощью пролога. Предикат определяется следующим образом:

not(Goal) :- call(Goal),!,fail.
not(Goal). 

Это означает, что цель не может быть доказана, а не цель. Возможно, эта ссылка Prolog and Cut будет полезна.

Ответ 3

"... если P, а не Q", можно представить через предикат -> if-then control-flow (например, GNU) вместе с оператором отрицания (или "не доказуемым" ) \+ (например, GNU) следующим образом:

(P -> \+ Q),

Обратите внимание, что обычно \+ будет реализовывать так называемое отрицание как отказ; т.е. подцель/выражение \+ Q будет успешным, если Q не может. Обратите внимание, что оценка Q под \+ не будет влиять на привязки любых переменных, присутствующих в выражении Q при выполнении.

Например, рассмотрим:

foo(a).
bar(b).

Учитывая эти факты, имеем:

foo(a) -> \+ bar(a). % succeeds, as bar(a) is not provable.
foo(a) -> \+ bar(b). % fails, as bar(b) is provable.
foo(a) -> \+ bar(X). % fails, as bar(X) is provable; note that X remains unbound.
foo(X) -> \+ bar(X). % succeeds, as bar(X) where X unified to 'a' isn't provable.

Реализация чего-то сродни \+ q(X) :- p(X), как вам может захотеть (в терминах "правила" ) не является простой, как вы описали, однако потенциальный взлом:

q(X) :- p(X), !, fail.

Это определение будет отражать только то, что q(X) будет терпеть неудачу для всех X, где p(X) преуспеет, если он утверждается перед любыми другими предложениями q(X), но может быть не идеальным.

Ответ 4

Вы можете использовать минимальную логику для определения отрицательной головки. В минимальной логике ~ A можно рассматривать как A → ff. Таким образом, следующее

P -> ~Q

Можно просмотреть как:

P -> (Q -> ff).

Теперь, если взять следующее тождество (A → (B → C)) = (A и B → C), мы см., что приведенное выше эквивалентно:

P & Q -> ff.

Теперь есть одна проблема, как мы можем задавать отрицательные запросы? Есть один способ использовать минимальную логику, которая отличается от отрицания как отказ. Идея состоит в том, что запрос формы:

G |- A -> B

ответят, временно добавив A в пролог-программу G, а затем пытаясь решить B, т.е. делать следующее:

G, A |- B

Теперь перейдем к нотации Пролога, покажем, что p, и p → ~ q подразумевает ~ q путем выполнения (минимальной логики) программы Prolog. Пролог:

p.
ff :- p, q.

И запрос:

?- q -: ff.

Сначала нам нужно определить новый соединитель (-:)/2. Быстрое решение выглядит следующим образом:

(A -: B) :- (assert(A); retract(A), fail), B, (retract(A); assert(A), fail).

Здесь вы видите реализацию этого минимального логического отрицания в SWI Prolog:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 5.10.4)
Copyright (c) 1990-2011 University of Amsterdam, VU Amsterdam

1 ?- [user].
:- op(1200,xfy,-:).
|: (A -: B) :- (assertz(A); retract(A), fail), B, (retract(A); assertz(A), fail).
|: p.
|: ff :- p, q.
|:
% user://1 compiled 0.02 sec, 1,832 bytes
true.

2 ?- q -: ff.
true .

С наилучшими пожеланиями

Ссылка: Единообразные доказательства как основа для логического программирования (1989) Дейл Миллер, Гопалан Надатур, Фрэнк Пфеннинг, Андре Себеров