Проблемы, связанные с использованием отрицания и оператора отсечения
Применение средства отсечения позволяет достичь определенных успехов, но за j это приходится платить. Преимущества и недостатки использования оператора отсе- I чения были проиллюстрированы на примерах в предыдущих разделах. Подведем общий итог; вначале для этого рассмотрим преимущества, как описано ниже.
1. Оператор отсечения часто позволяет повысить эффективность программы. Общий замысел здесь состоит з том, что этот оператор дает возможность явно сообщить системе Prolog, что не следует проверять другие альтернативы, поскольку они неизбежно окончатся неудачей.
2. Использование оператора отсечения позволяет определять взаимоисключающие правила, поэтому с его помощью можно представлять правила, имеющие следующую форму:
Если условие Р, то заключение Q, а противном случае заключение R.
Таким образом, оператор отсечения повышает выразительную мощь языка Prolog.
Предпосылки, препятствующие применению оператора отсечения, вытекают из того факта, что при этом возникает опасность утратить ценное соответствие между декларативным и процедурным значениями программы. Если в программе не применяется оператор отсечения, имеется возможность изменять порядок предложений и целей и такая перестановка влияет лишь на эффективность или успешность завершения программы, но не на ее декларативное значение. С другой стороны, изменение порядка следования предложений в программах с операторами отсечения может повлиять на их декларативное значение. Таким образом, после перестановки предложенийв такой программе могут быть получены иные результаты, как показано в следующем примере:
р :- =. b. р : - с .
Эта программа имеет следующее декларативное значение: р является истинным, если и только если а и b одновременно являются истинными или с является истинным. Такое утверждение может быть записано в виде следующей логической формулы:
р <==> !о£ b) v с
Последовательность этих двух предложений может быть изменена, но при этом декларативное значение останется неизменным. Теперь вставим оператор отсечения следующим образом:
р : - а, !, Ь.
р : - с.
132 Часть I. Язык Prolog
После этого программа приобретает такое декларативное значение: р <:==> (а 6 Ы v (-а & с)
Если теперь порядок следования предложений будет изменен следующим образом на противоположный: р :- с.
р :- а, 1, to.
то программа примет такое значение: р <==> с v (a & b)-
Из этого следует важный вывод, что если применяется средство отсечения, то необходимо уделять больше внимания процедурным аспектам. К сожалению, эта дополнительная сложность приводит к повышению вероятности ошибок программирования.
Б примерах, приведенных в предыдущих разделах, было показано, что иногда удаление оператора отсечения из программы приводит к изменению декларативного значения программы. Но есть и такие случаи, в которых оператор отсечения не оказывает никакого влияния на декларативное значение. Использование операторов отсечения последнего типа в меньшей степени способствует возникновению ошибок в программе, и поэтому операторы отсечения такого типа иногда называют зелеными операторами отсечения. С точки зрения удобства программ для чтения зеленые операторы отсечения являются "безвредными", и их применение вполне допустимо. При чтении программы зеленые операторы отсечения могут игнорироваться.
В отличие от этого, операторы отсечения, влияющие на декларативное значение, принято называть красными операторами отсечения. Красные операторы отсечения представляют собой такие операторы, в результате введения которых программы становятся более сложными для понимания, и они должны использоваться с особой осторожностью.
Оператор отсечения часто используется в сочетании со специальной целью, fail. Б частности, мы определили отрицание цели (not) как неудачу в достижении цели. Отрицание, определенное таким образом, представляет собой особый, более ограниченный способ использования оператора отсечения. По соображениям наглядности мы предпочитаем использовать оператор not вместо сочетания "'оператор отсечения — цель fail" (если это возможно), поскольку интуитивно отрицание воспринимается как более понятная операция, чем сочетание "оператор отсечения — цель fail".
Следует отметить, что использование оператора not также может привести к возникновению проблем, поэтому и его следует использовать с осторожностью. Как уже было сказано, проблема, связанная с оператором not, состоит в том, что он не полностью соответствует понятию отрицания в математике. Например, если системе Prolog будет задан следующий вопрос: ?- not human [ тагу) .
то она, вероятно, ответит "yes". Но этот ответ не следует понимать таким образом, будто Prolog отвечает, что Мэри не человек. В действительности этот ответ Prolog означает, что в программе нет достаточной информации, чтобы определить, является ли Мэри человеком. Такая ситуация возникает в связи с тем, что при обработке цели not система Prolog не пытается доказать эту цель непосредственно. Вместо этого она пытается доказать обратное, а если обратное не может быть доказано, Prolog предполагает, что достигается цель not.
Такой ход рассуждений основан на так называемом предположении о замкнутости мира. В соответствии с этим предположением мир замкнут, в том смысле, что все существующее в мире утверждается в программе или может быть выведено из программы. Таким образом, если какие-то факты не заданы в программе (или не могут быть выведены на основе имеющейся в ней информации), то они не являются истинными, а, следовательно, истинным является их отрицание. Такая особенность функционирования системы Prolog говорит о том, что ее эксплуатация требует осо-
Глава 5, Управление перебором с возвратами
бой осторожности, поскольку пользователи обычно не руководствуются предположением о замкнутости мира. Поэтому если в программу не введено явно предложение
human( шагу) ,
то это не означает, что мы не считаем Мэри человеком, но ведь система об этом не знает!
Чтобы дополнительно изучить вопрос, связанный с тем, почему применение оператора notтребует осторожности, рассмотрим следующий пример, касающийся ресторанов:
good standard( jeanluis). expensive[ jeanluis).