Скачиваний:
52
Добавлен:
01.05.2014
Размер:
346.11 Кб
Скачать

11.4. Красные отсечения: устранение явных условий

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

Исходным (плохим) примером в литературе является модификация программы 11.3, задающей отношение minimum. Можно отбросить сравнение во втором пред­ложении программы, что приводит к программе

minimum(X,Y,X)XY,!. minimum(X,Y,Y).

Законность этой программы объясняют так: “Если Х не больше Y, то минимум -X. В противном случае минимум равен Y и сравнение Х с Y не требуется”. Однако в программе 11.3 такое сравнение выполняется.

Эти доводы имеют серьезный изъян. Значение модифицированной программы отличается от значения стандартной программы minimum, В модифицированной программе выполняется цель minimum (2,5,5). Модифицированная программа явля­ется ложной логической программой.

Можно избавиться от ложных целей, выводимых из модифицированной про­граммы. Для этого необходимо неявную унификацию первого и третьего аргумента в первом правиле сделать явной. Измененное правило -

minimum(X,Y,Z)  Х  Y,!,Z = X.

Такой способ использования отсечения для фиксации правила после частичного выполнения унификации является достаточно обычным приемом. Но в случае программы minimum в результате получается слишком мудреный текст. Гораздо лучше просто записать корректную логическую программу, добавив для эффектив­ности отсечение, как это сделано в программе 11.3.

Использование отсечения в операционной среде Пролога весьма проблематично. Оно приводит к появлению Пролог - программ, которые неверны, если их рассматри­вать как логические программы, т.е. из таких программ выводимы ложные утверждения. Однако они же работают правильно, поскольку в Прологе невоз­можно доказать эти ложные утверждения. Например, если в цели вида mini­mum (X,Y,Z) аргументам Х и Y сопоставлены значения, а аргументу Z-нет, то модифицированная программа работает правильно.

Единственным следствием применения зеленых отсечений в разд. 11.1 является отбрасывание заведомо бесполезных ветвей в дереве поиска. Отсечения в програм­ме, которые приводят к изменению ее значения, называются красными отсечениями . Удаление красного отсечения изменяет значение программы, т. е. множество вы­водимых целей.

Обычный способ использования красных отсечений в Прологе - это устранение явных условий. Знание метода вычислений в Прологе и порядка использования правил в программе позволяет опускать заведомо выполнимые условия. В практи­ческом программировании это иногда существенно, так как явные условия, особен­но использующие отрицание, затрудняют описание и снижают эффективность выполнения программ. Однако такое устранение чревато ошибками.

Устранение явного условия возможно, если безуспешное применение предыду­щих правил влечет выполнение этого условия. Например, из безуспешности сравне­ния ХY в программе minimum следует, что Х больше Y Следовательно, проверка Х > Y может быть опущена. Обычно такое явное условие эквивалентно отрицанию предыдущих условий. Использование красных отсечений для устранения условий позволяет задавать отрицание неявно.

Рассмотрим программу 11.5 - программу сортировки перестановками. Первое (рекурсивное) правило применимо всегда, когда в списке имеется пара неупоря­доченных соседних элементов. Когда применяется второе правило sort, такие пары в списке отсутствуют и он должен быть упорядочен. Следовательно, условие orde­red(Xs) может быть опущено, что превращает второе правило в факт sort(Xs, Xs). Как и в случае программы minimum, данное предложение логически некорректно.

Как только из программы удалено условие Ordered, цвет отсечения меняется с зеленого на красный. Удаление отсечений из варианта программы, не содержащего условия ordered, приводит к программе, дающей ложные решения.

Обратимся к другому примеру устранения явного условия. Рассмотрим програм­му 3.18, удаляющую элементы из списка. В двух рекурсивных предложениях рассматриваются различные случаи, зависящие от того, совпадает ли голова списка с удаляемым элементом. Взаимоисключащий характер этих случаев может быть выражен с помощью отсечений, как это сделано в программе 11.8а.

Ввиду того что безуспешное выполнение первого предложения означает несовпа­дение удаляемого элемента с головой списка, явную проверку на неравенство во втором предложении можно опустить. Программа 11.8б содержит соответствующие изменения. Все отсечения программы 1 l.8a зеленые в отличие от красного отсечения в первом предложении программы 11,8б.

delete (Xs.X.Ys)

список Ys получен в результате удаления всех вхождений элемента Х из списка Xs.

delete([X|Ys],X,Zs)!,delete(Ys,X,Zs) delete([Y|Ys],X,[YZs])YX,!,delete(Ys,X,Zs).

deleted: ],X,[ ]).

Программа 11.8a. Удаление всех вхождений элемента из списка.

delete (Х s,X,Ys)

список Ys получен в результате удаления всех вхождений элемента Х из списка Xs.

delete([X |Ys], X, Zs)!, delete (Ys, X., Zs).

delete([Y | Ys],X,[Y) Zs])!, delete (Ys, X, Zs).

delete([ ],X,[ ]).

Программа 11.8б. Удаление всех вхождений элемента из списка.

В общем случае удалять простые проверки, как это сделано в программе 11,86, нецелесообразно. Выигрыш в эффективности, который дает такое удаление, ничто­жен по сравнению с потерями удобочитаемости текста программы и его модифи­цируемости.

Рассмотрим использование отсечения при задании управляющей конструкции if_then_else. Программа 11.9 определяет отношение if_.then_else(P,Q,R). Декларатив­ное понимание предиката: предикат выполнен, если Р и Q истинны или не Р и R истинны. Операционное понимание: мы пытаемся доказать Р, в случае успеха доказываем Q, в противном случае доказываем R.

If_ then_ else (P,Q,R)-

Или Р и Q, или не Р и R.

if_Jhen_else(P,Q,R) Р,!, Q. if_then_else(P,Q,R)R.

Программа 11.9. Конструкция if_then_else.

Очевидно, что использование красного отсечения в данном случае разумно. Альтернатива к использованию отсечения состоит в явном указании условия, при котором доказывается R. В этом случае второе предложение будет иметь вид

if_then_else(P,Q,R) not Р, R.

С вычислительной точки зрения это может привести к большим затратам. При вычислении предиката not придется полностью повторить вычисление цели Р.

До сих пор мы встречались с двумя вариантами использования красных отсечений, В первом красное отсечение было встроено в программу, как в опреде­лениях отношений not и . Во втором красное отсечение возникало из зеленого при удалении условий из программы. Однако имеется и третий вариант красного отсечения. Отсечение, вводимое в программу в качестве зеленого, предназначенного лишь для повышения эффективности, может оказаться красным, меняющим значение программы.

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

member(X,[X | Xs])!.

member(X,[Y | Ys]) member(X,Ys).

Добавление отсечения действительно изменило функционирование программы. Однако полученная программа некорректна, так как решение, например, цели member(Х,[1,2.3])? дает лишь одно значение Х = 1. Эта программа является вариан­том программы member_check (программа 7.3), в которой опущено явное условие X Y, и, следовательно, отсечение является красным.

Упражнения к разд. 11.4

1. Рассмотрите возможность добавления отсечений в программу 9.3, задающую отноше­ние Substitute. Полезно ли использовать комбинацию «отсечение-fail» и имеет ли смысл исключать явные условия?

2. Исследуйте связь между программой Select (программа 3.19) и программой, получен­ной добавлением одного отсечения:

select(X,[X |Xs],Xs)!.

select (X,[Y | Ys],[Y | Zs])select(X, Ys, Zs).

(Указание: Рассмотрите варианты программы select.)

Соседние файлы в папке 1-13