:- op( 600, xfx, имеет).
Такая запись сообщит Прологу, что мы хотим использовать "имеет" в качестве оператора с приоритетом 600 и типом ' xfx
', обозначающий одну из разновидностей инфиксного оператора. Форма спецификатора ' xfx
' указывает на то, что оператор, обозначенный через ' f
', располагается между аргументами, обозначенными через ' х
'.
Обратите внимание на то, что определения операторов не содержат описания каких-либо операций или действий. В соответствии с принципами языка ни с одним оператором не связывается каких-либо операций над данными (за исключением особых, редких случаев). Операторы обычно используются так же, как и функторы, только для объединения объектов в структуры и не вызывают действия над данными, хотя само слово "оператор", казалось бы, должно подразумевать какое-то действие.
Имена операторов это атомы, а их приоритеты — точнее, номера их приоритетов — должны находиться в некотором диапазоне, зависящем от реализации. Мы будем считать, что этот диапазон располагается в пределах от 1 до 1200. [1] Чем выше приоритет, тем меньше его номер. — Прим. перев .
Существуют три группы типов операторов, обозначаемые спецификаторами, похожими на xfx
:
(1) инфиксные операторы трех типов:
xfx xfy yfx
(2) префиксные операторы двух типов:
fx fy
(3) постфиксные операторы двух типов:
хf yf
Спецификаторы выбраны с таким расчетом, чтобы нагляднее отразить структуру выражения, в котором ' f
' соответствует оператору, а 'x' и ' y
' представляют его аргументы. Расположение ' f
' между аргументами указывает на то, что оператор инфиксный. Префиксные и постфиксные спецификаторы содержат только один аргумент, который, соответственно, либо следует за оператором, либо предшествует ему.
Рис. op3.7. Две интерпретации выражения а-b-с
в предположении, что ' -
' имеет приоритет 500. Если тип ' -
' есть yfx
, то интерпретация 2 неверна, так как приоритет b-с
не выше, чем приоритет ' -
'.
Между ' x
' и ' y
' есть разница. Для ее объяснения нам потребуется ввести понятие приоритета аргумента . Если аргумент заключен в скобки или не имеет структуры (является простым объектом), тогда его приоритет равен 0; если же он структурный, тогда его приоритет равен приоритету его главного функтора. С помощью ' x
' обозначается аргумент, чей приоритет должен быть строго выше приоритета оператора (т e. его номер строго меньше номера приоритета оператора); с помощью ' y
' обозначается аргумент, чей приоритет выше или равен приоритету оператора.
Такие правила помогают избежать неоднозначности при обработке выражений, в которых встречаются операторы с одинаковым приоритетом. Например, выражение
а-b-с
обычно понимается как (а-b)-с
, а не как а-(b-с)
. Чтобы обеспечить такую обычную интерпретацию, оператор ' -
' следует определять как yfx
. На рис. 3.7 показано, каким образом исключается вторая интерпретация.
В качестве еще одного примера рассмотрим оператор not
(логическое отрицание "не"). Если not
oпределён как fy
, тогда выражение
not not p
записано верно; однако, если not
определен как fx
, оно некорректно, потому что аргументом первого not
является структура not p
, которая имеет тот же приоритет, что и not
. В этом случае выражение следует писать со скобками:
not (not p)
:- op( 1200, xfx, ':-').
:- op( 1200, fx, [:-, ?-] ).
:- op( 1100, xfy, ';').
:- op( 1000, xfy, ',').
:- op( 700, xfx, [=, is, <, >, =<, >=, ==, =\=, \==, =:=]).
:- op( 500, yfx, [+, -] ).
:- op( 500, fx, [+, -, not] ).
:- op( 400, yfx, [*, /, div] ).
:- op( 300, xfx, mod).
Рис. 3.8. Множество предопределенных операторов.
Для удобства некоторые операторы в пролог-системах определены заранее, чтобы ими можно было пользоваться сразу, без какого-либо определения их в программе. Набор таких операторов и их приоритеты зависят от реализации. Мы будем предполагать, что множество этих "стандартных" операторов ведет себя так, как если бы оно было определено с помощью предложений, приведенных на рис. 3.8. Как видно из того же рисунка, несколько операторов могут быть определены в одном предложении, если только они все имеют одинаковый приоритет и тип. В этом случае имена операторов записываются в виде списка. Использование операторов может значительно повысить наглядность, "читабельность" программы. Для примера предположим, что мы пишем программу для обработки булевских выражений. В такой программе мы, возможно, захотим записать утверждение одной из теорем де Моргана, которое в математических обозначениях записывается так:
Читать дальше