Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Логическое программирование.docx
Скачиваний:
13
Добавлен:
16.11.2019
Размер:
62.21 Кб
Скачать

2. Синтаксис и семантика пролог программ

2.1. Синтаксис Пролога

Общий синтаксис программ на языке Пролог можно описать следующей грамматикой: <программа>::=<предложение> | <программа> <предложение> <предложение>::=<утверждение> | <запрос> | <команда> <утверждение>::=<факт> | <правило> <факт> =<терм>. <правило> =<терм>:-<термы>. <запрос> =?-<термы>. <команда> =:-<терм>. <термы>::=<терм> | <термы>,<терм> <терм> =<атом> | <структура> | <константа> | <переменная> <структура> =<атом>(<термы>) <атом> =<идент> | '<символы>' | <слецсимволы> <константа> =<число> | <строка> <строка> ="<символы>" Комментарии записываются либо в скобках /* */, либо после символа % до конца строки. ^ Команда (директива) используется для управления процессом трансляции про­граммы во внутреннее представление. Логическая программа состоят из определений предикатов. Предикат (отношение) - это элементарная формула в логическом выра­жении, которая является истинной, если выполняется ли некоторое свойство или от­ношение для указанных аргументов, и ложной в противном случае. Определение пре­диката позволяет проверить истинность предиката и состоит из набора фактов и пра­вил с одинаковым именем и количеством аргументов (предикат с именем name и двумя аргументами часто обозначают как name/2). Язык Пролог не включает средств для ука­зания типа аргументов, и аргументами предикатов могут быть произвольные термы, при этом аргументы не вычисляются, а передаются в виде термов, являющихся ос­новной структурой данных в логических программах. Тело правила и запрос должны содержать обращения только к встроенным или определяемым в программе предика­там. Обычно для программирования на языке Пролог достаточно только целых чисел, но большинство интерпретаторов допускает использование также и вещественных чи­сел. Строки в Прологе рассматриваются как списки кодов символов, что позволяет их обрабатывать так же, как и другие списки. Некоторые версии интерпретаторов могут включать в себя и другие типы констант. Атомы используются как имена для объектов и отношений в программе. В качест­ве имени можно использовать: 1) традиционный идентификатор, состоящий из букв, цифр и символов "_" и начинающийся со строчной буквы; 2) произвольную последова­тельность символов а апострофах (т е даже неадаптированная версия интерпретато­ра допускает использование русских наименований); 3) последовательность специаль­ных символов, которым относятся +-*/=\== & ~ и др. Пример. Следующие цепоч­ки являются атомами: atom x_23 'Наташа' ::= Переменная в логической программе используется только как ссылка на конкрет­ный объект. Переменная, еще не имеющая значения, называется неконкретизированной. Имя переменной состоит из буке, цифр и символов "_" и начинается с прописной латинской буквы или символа подчеркивания. Область действия переменной ограни­чена одним предложением. Если переменная при согласовании цели получит какое-либо значение, то значение этой переменной не может быть изменено в ходе даль­нейшего логического вывода, так как подобное изменение могло бы повлечь измене­ние истинности проверенных ранее предикатов. Переменная с именем "_" называется анонимной. Анонимные переменные избавляют программиста от необходимости да­вать имена переменным, которые используются в предложении только один раз. После трансляции программы, каждому вхождению анонимной переменной соответствует своя временная переменная. Пример. Определение наличия детей при определенном предикате parent: haschald(X):-parent(X, _). Значение анонимной переменной не выводится на печать. Если несколько анонимных переменных, то они все разные. Использование анонимных переменных позволяет не выдумывать имена переменных, когда не надо. Если в языке Lisp данные принято в основном представлять в виде списков, то в Прологе основ­ной формой представления являются структуры. Структура со­стоит из функтора (имени структуры) и набора компонент (со­ставных частей структуры). Число аргументов функтора назы­вается арностью. Для структур удобно использовать графиче­ское представление в виде дерева, корнем дерева является функтор, а ветвями - компоненты. Как набор структур представляется и текст программы. Это позволяет программам интерпретировать свой текст как данные, вносить измене­ния в программу в процессе выполнения. Пример. Дату можно рассматривать как структуру, состоящую из трех компонент: день, месяц, год. Хотя они и составлены из нескольких компонент, структуры в программе ведут себя как единые объекты. Для того, чтобы объединить компоненты в структуру, требуется выбрать функтор. Для нашего примера выберем функтор дата. Тогда дату 1-е мая 1983 г. можно записать так: дата(1, май, 1983). Все компоненты в данном примере являются константами (две компоненты - целые числа и одна - атом). Компоненты могут быть также переменными или структурами. Все структурные объекты можно изображать в виде деревьев (пример см. на рис. 2.2). Корнем дерева служит функтор, ветвями, выходящими из него, - компоненты. Если некоторая компонента тоже является структурой, тогда ей соответствует поддерево в дереве, изображающем весь структурный объект. Рис. 3.2.1.  Дата - пример структурного объекта: (а)    его представление в виде дерева;     (б)    запись на Прологе. Арифметическое выражение также можно представить как некоторую структуру например, выражение х+2*у может быть записано как +(х,*(2,у)) Такая форма сложнее для восприятия, но, к счастью, язык Пролог позволяет определить функторы как опе­раторы с нужными свойствами (приоритетом, позицией и ассоциативностью) и использовать привычную форму записи арифметических выражений и предикатов. Для этого используется команда: :-ор(приоритет, тип, функтор). Если оператор инфиксный, то указывается тип xfx, xfy (правоассоциативный) или yfx (левоассоциативный). Для постфиксного оператора указывается тип xf или yf для префиксного - fx или fy. Буква f указывает расположение функтора, буква х указы­вает на аргумент, чей приоритет должен быть строго выше приоритета оператора, а буква у обозначает аргумент с приоритетом выше или равным приоритету оператора. В таблице 3.2.1 показан приоритет предопределенных операторов.

Тип 

Позиция 

Ассоциативность 

xfx 

инфиксный 

неассоциативный

xfy 

инфиксный 

правоассоциативный

yfx 

инфиксный 

левоассоциативный

fx 

постфиксный 

неассоциативный

fy 

постфиксный 

правоассоциативный

xf 

префиксный 

неассоциативный

yf 

префиксный 

левоассоциативный

Таблица 3.2.1. Типы (ассоциативность) операторов Приоритет оператора должен быть в диапазоне от 1 до 1200, самый высокий при­оритет - 1, самый низкий - 1200. Тип оператора определяет его позицию и ассоциа­тивность.

Встроенный оператор (функтор)

Тип 

Приоритет

?- :- --> 

xfx

1200

:- 

fx 

1200

xfy

1100

xfy 

1000

not \+ 

fy 

900

-> 

xfy 

800

xfy 

700

is \== \= ==

xfx 

700

=\= =:= 

xfx 

650

>= > =< < 

xfx 

600

>> << 

yfx 

550

- + 

yfx 

500

xfy 

500

- + 

fx 

500

mod // / * 

yfx 

400

xfy 

300

\ * & 

fy 

300

Таблица 3.2.2. Приоритет предопределенных операторов При необходимости программист может ввести свои операторы или переопреде­лить существующие. Пример. Определив оператор «нравится» как: :-op(600, xfx, likes) можно записать факт того, что Мэри нравится кино likes(mary, cinema). в более естественном виде: mary likes cinema. В Прологе выполняются следующие арифметические операции: + - сложение - - вычитание * - умножение / - деление mod - остаток от целочисленного деления. // - целочисленное деление ^ - возведение в степень Поддерживается ряд стандартных математических функций (sqrt, sin, random и др.) Пример. Если записать: x = 2+1. то получим результат: X=2+1 т.к. это просто сопоставление переменной и структуры. Чтобы арифметическое выражение рассчитывалось, необходимо использовать встроенный оператор is, который заставляет выполнять арифметические операции. Пример. Вычисление суммы двух целых чисел. X is 2+1. X=3 В арифметических выражениях могут встречаться и переменные, но они должны иметь значение к моменту вычисления. Пример. Вычисление суммы квадратов двух чисел. f(X, Y, Z):-Z is X*X + Y*Y. ?- f(3,4,X). X=25; No К операциям сравнения относятся следующие предикаты: =:= - проверка на равенство =\= - проверка на неравенство > - отношение «больше» < - отношение «меньше» =< - отношение «меньше либо равно» (запомнить порядок!) >= - отношение «больше либо равно» Пример. Проверка на равенство суммы двух чисел их произведению. ?- 2+2=:=2*2 С помощью операций сравнения можно создавать запросы на выборку фактов, удовлетворяющих заданным условиям. Пример. Из заданных фактов возрастов, выделим те, что лежат в указанном диапазоне. age(mary, 20). age(ann , 23). age(bob , 25). ?- age(X, Y), Y>21, Y=<23. X=ann; Y=20; Пролог позволяет формировать сложные логические выражения. Простейшими ло­гическими предикатами являются true (истина) и fail (ложь, неудача) Согласование це­ли true всегда успешно. Согласование цели fail всегда неудачно Для конъюнкции це­лей используется предикат "," (X,Y), а для дизъюнкции - предикат "," (X;Y) Приоритет у оператора "," выше, чем у оператора ",", поэтому лишние скобки можно опускать. Пример. Выражение A,B,C,D интерпретируется как (A,B),(C,D) Для отрицания исполь­зуется предикат not(X). Так как запятая служит как для конъюнкции целей, так и для разделения аргументов, требуются дополнительные скобки, если аргумент not не яв­ляется элементарным выражением. Например, нужно писать not((A,B)), а не not(A,B) Конструкция "если А то В иначе С" на языке Пролог может быть записана как (A,B,not(A) С) или (А,В,С), а конструкция "если А то В" - как (A,B,true) Можно даже вве­сти условный оператор в язык, задав необходимые операторы и предикаты Пример. Зададим условные операторы и запишем с их помощью определение прдиката max :-op(1160, fx, if). :-op(1150, xfx, then). :-op(1155, xfx, else). if A then B else C :- A, B; not(A), C. max(X,Y,Z) :- if X>Y then Z is X else Z is Y.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]