Пролог - различия между красным и зеленым срезом

Я начал изучать пролог и хотел сделать все порезы яснее. Я прочитал, что "зеленый разрез не меняет декларативный смысл программы, а красный -". Но смысл программы не является действительно чистым декларативным (только из-за того, что пролог фактически отступает для всех вариантов).

Вот пример:

p(1).
p(2) :- !.
p(3).

было сказано, что это зеленый срез. Но если я запустил это:

p(X), X =:= 3.

Я получу "истину" без разреза и "ложную" с разрезом. так, что я пропущу?

Спасибо заранее.

Ответ 1

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

Вот моя попытка сделать все еще менее ясным.

Оперативный смысл разреза,

  • Из справочного руководства SWI-Prolog:" Отбросьте все точки выбора, созданные с момента ввода предиката, в котором отображается разрез. Другими словами, зафиксируйте, в котором появляется надпись и отбрасывает точки выбора, созданные целями слева от разреза в текущем разделе.

  • Из "Искусство Пролога" Стерлинга и Шапиро: "Цель преуспевает и обязывает Prolog ко всем выборам, сделанным с момента объединения родительской цели с главой предложения сокращение происходит в [не моем]. Хотя это определение является полным и точным, его последствия и последствия не всегда интуитивно понятны или очевидны".

  • Из "Ремесло Пролога" О'Кифа: "[Сокращение] сокращает стек пунктов выбора обратно туда, где это было, когда предикат, который лексически содержит разрез, был назван другим способом. Еще один способ сказать, что разрез преуспевает и фиксирует Prolog для всех вариантов, сделанных с тех пор, как родительская цель была вызвана [снова, акцент не мой]"

Я предлагаю вам прочитать разделы о разрезе и его использовании, по крайней мере, из двух упомянутых выше книг. Это определенно поможет вам понять, что на самом деле происходит.

Одно общее обсуждение заключается в различии между поиском решений и ответами против доказательств. Нам (пользователям, программистам) обычно нужны ответы. Результатом оценки предикатов Пролога являются решения. Однако то, что Пролог действительно ищет, является доказательством.

Возьмем ваш пример. У вас есть база данных p(1). p(2). p(3).. Теперь вы хотите спросить Prolog: "Существует ли p(X) такое, что X =:= 3,

?- p(X), X =:= 3.
X = 3.

Вы получаете одно решение, X = 3. Вы также получите ответ на свой вопрос: да, есть такой p(X), а X равно 3, и ответов явно нет.

(Попробуйте выполнить запрос ?- p(X), X =:= 2.. Он ведет себя идентично исходному запросу?)

Дерево доказательств можно увидеть (в порядке), проверив запрос:

?- trace(p/1), trace(=:=).
%         p/1: [call,redo,exit,fail]
%         (=:=)/2: [call,redo,exit,fail]
true.

[debug]  ?- p(X), X =:= 3.
 T Call: (7) p(_G1004)
 T Exit: (7) p(1)
 T Call: (7) 1=:=3
 T Fail: (7) 1=:=3
 T Redo: (7) p(_G1004)
 T Exit: (7) p(2)
 T Call: (7) 2=:=3
 T Fail: (7) 2=:=3
 T Redo: (7) p(_G1004)
 T Exit: (7) p(3)
 T Call: (7) 3=:=3
 T Exit: (7) 3=:=3
X = 3.

В принципе, каждый из предложений p/1 проверяется поочередно. Первые два не дают доказательств, так как второй подцель конъюнкции терпит неудачу. Поиск доказательства продолжается каждый раз из последней точки выбора (следующее предложение p/1). Последнее можно проверить, и вы получите решение и ответ на свой запрос.

Теперь вы помещаете разрез в тело второго предложения p/1: p(1). p(2) :- !. p(3).. Вы сообщаете Prolog (в терминах определения 3. сверху): "когда поиск доказательства достигает второго предложения p/1, тот, который объединяет свой аргумент с 2, обрезает стек пунктов выбора, где он был, когда p/1. Когда вызывается p/1, точек выбора не было. Таким образом, когда X =:= 3 терпит неудачу, поиск доказательства завершен, соединение не может быть доказано, нет решений, и вы не получите никаких ответов.

(Попробуйте выполнить запрос ?- p(X), X =:= 2.. Он идентичен тому же запросу, когда у вас нет разреза?)

Теперь к цветам..... В контексте конъюнкции p(X), X =:= 3. этот разрез сократил решение и доказательство. Вы не получили ответ, которого ожидали. Этот разрез красный.

Было бы неплохо, если бы мы могли сказать Prolog, что мы имеем в виду, что срез будет либо зеленым, либо красным (или зеленым, или грубым, или красным или синим), но Prolog не позволяет нам это делать. "Цвет" является следствием предполагаемого значения программы (намерение программиста) и операционных (процедурных) эффектов разреза.

Но на самом деле, попробуйте получить книгу и прочитать раздел о разрезах. Или даже две книги.