Программирование на языке Пролог для искусственного интеллекта

       

В точке помеченной



Рисунок 5. 2.  В точке, помеченной словом "ОТСЕЧЕНИЕ", уже известно,
что правила  2  и  3  должны потерпеть неудачу.


При вычислении первой цели  f( l, Y)   Y конкретизируется нулем. Поэтому вторая цель становится такой:

        2 < 0

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

Три правила, входящие в отношение f, являются взаимоисключающими, поэтому успех возможен самое большее в одном из них. Следовательно, мы (но не пролог-система) знаем, что, как только успех наступил в одном из них, нет смысла проверять остальные, поскольку они все равно обречены на неудачу. В примере, приведенном на Рисунок 5.2, о том, что в правиле 1 наступил успех, становится известно в точке, обозначенной словом "ОТСЕЧЕНИЕ". Для предотвращения бессмысленного перебора мы должны явно указать пролог-системе, что не нужно осуществлять возврат из этой точки. Мы можем сделать это при помощи конструкции отсечения. "Отсечение" записывается в виде символа '!', который вставляется между целями и играет роль некоторой псевдоцели. Вот наша программа, переписанная с использованием отсечения:

        f( X, 0) :- X < 3,  !.

        f( X, 2) :- 3 =< X,  X < 6,  !.

        f( X, 4) :- 6 =< X.

Символ  '!'  предотвращает возврат из тех точек программы, в которых он поставлен. Если мы теперь спросим

        ?-  f( 1, Y),  2 < Y.

то пролог-система породит левую ветвь дерева, изображенного на Рисунок 5.2. Эта ветвь потерпит неудачу на цели  2  <  0.   Система попытается сделать возврат, но вернуться она сможет не далее точки, помеченной в программе символом   '!' .  Альтернативные ветви, соответствующие правилу 2 и правилу 3, порождены не будут.

Новая программа, снабженная отсечениями, во всех случаях более эффективна, чем первая версия, в которой они отсутствуют. Неудачные варианты новая программа распознает всегда быстрее, чем старая.

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



Содержание раздела