При использовании отсечения возможно возникновение двух видов ловушек:
• отсечение исключает необходимые альтернативы;
• отсечение разрушает декларативное восприятие программы.
В качестве примера ловушки первого типа рассмотрим применение предиката 'между'(X,Y,Z) в двух различных вариантах: для генерации всех целых чисел Х, принадлежащих интервалу [Y,Z], и для проверки, находится ли целое число X в интервале [Y,Z], т.е. Y<=X<=Z.
'между'(X,X,Z):- X=
'между'(X,Y,Z):- Y1 is Y+1,Y1=
При запросе: ? - 'между'(Х,5,8). будут получены следующие решения
X=5 --> ;
X=6 --> ;
X=7 --> ;
X=8 --> ;
что показывает, что предикат 'между' в этом случае выполняет роль генератора целых чисел в заданном интервале.
Введем в целях повышения эффективности программы отсечение в граничное условие предиката 'между':
'между1'(X,X,Z):-!,X=
'между1'(X,Y,Z):-Y1 is Y+1,Y1=
и попытаемся его использовать для контроля, принадлежит ли Х заданному интервалу [Y,Z]:
? - Х=3,'между1'(Х,2,4).
yes
Как только будет достигнут момент согласования граничного условия 'между'(3,3,4), благодаря отсечению бесцельный поиск других решений в ответ на ввод <;> (или при любом другом способе инициирования возврата) производиться не будет, время доказательства цели сократится. Однако в таком виде этот предикат уже не сможет выступать в роли генератора, что показывает ответ на следующий запрос:
?-'между'(Х,4,8).
'между'(4,4,8).?;
no
Сравнение двух вариантов программы в примере 2 иллюстрирует ту ситуацию, когда введение отсечения приводит к потере декларативности определения отношения.
Применять отсечение следует осторожно, соразмеряя выгоду от повышения эффективности программы с опасностью возникновения нежелательных эффектов.
|