Рассмотрим арифметическое выражение, составленное из функторов * и +, имеющих по два аргумента. Пусть мы хотим отобразить одно выражение в другое, устраняя при этом все умножения на 1. Это алгебраическое приведение могло быть определено с помощью предиката 'п' такого, что 'п'(ОР,L,R,ANS) означает, что выражение, состоящее из операции ОP с левым аргументом L и правым аргументом R, приводится к упрощенному выражению ANS. Факты, необходимые для устранения умножения на 1, могли бы выглядеть так (из-за коммутативности умножения нужны два факта):
'п'(*,1,Х,Х).
'п'(*,Х,1,Х).
Эта таблица упрощений позволяет нам любое выражение вида 1*Х отобразить в Х. Посмотрим, как можно воспользоваться этим в программе.
При приведении выражения Е с помощью таблицы упрощений мы вначале должны привести левый аргумент Е, затем привести правый аргумент Е и, наконец, посмотреть, подходит ли этот приведенный результат под случаи, предусмотренные в нашей таблице. Если это так, то мы порождаем новое выражение в соответствии с указаниями таблицы. В качестве "листьев" дерева, представляющего выражение, фигурируют целые числа или атомы, поэтому для приведения листьев к ним самим в граничном условии мы должны использовать встроенный предикат atomic. Целевое утверждение atomic(X) согласуется с базой данных, если на текущий момент Х обозначает либо целое число, либо атом. Чтобы разложить выражение Е на функтор и компоненты, будем использовать предикат '=..'.
'привести'(Е,Е) :- atomic(Е),!.
'привести'(Е,F) :-Е=..[ОР,L,R],'привести'(L,Х),'привести'(R,Y),
'п'(ОР,Х,Y,F).
Итак, предикат 'привести' отображает выражение Е в выражение F, используя для этого факты, имеющиеся в таблице упрощений 'п'. А что делать, если невозможны такие упрощения? Чтобы избежать в этом случае неудачного завершения 'п'(OP,X,Y,F), мы должны поместить в конец каждого раздела таблицы упрощений, относящегося к определенному оператору, правило-ловушку. Приведенная таблица упрощений содержит правила для сложения и умножения. Кроме того, в ней выделены правила ловушки для каждого вида операций.
'п'(+,Х,0,Х).
'п'(+,0,Х,Х).
'п'(+,Х,Y,Х+Y)./* ловушка
для + */
'п'(*,_,0,0).
'п'(*,0,_,0).
'п'(*,1,Х,Х).
'п'(*,Х,1,Х).
'п'(*,Х,Y,Х*Y)./* ловушка
для * */
При наличии правил-ловушек возникает вопрос о выборе способа упрощения некоторых выражений. Например, если нам дано выражение 3+0, мы можем либо использовать первый факт, либо применить правило-ловушку для +. Благодаря способу упорядочения фактов, прежде чем применить правило-ловушку, Пролог всегда будет пытаться применить правило для специальных случаев.
|