Программирование на языке пролог
Шрифт:
Рассмотрим сначала сравнение чисел. Для двух заданных чисел всегда можно сказать, равно лиодно число другому, меньше лиодно число другого, больше лиодно число другого. Пролог предоставляет некоторые «встроенные» предикаты, позволяющие
сравнивать числа. Для этого могут использоваться обсуждавшиеся в разд. 2.4 предикаты '='и '\='. Их аргументами могут быть конкретизированные переменные, значениями которых являются целые числа, а также целые числа, записанные в виде констант. Существует еще несколько предикатов, позволяющих сравнивать числа. Перечислим здесь все эти предикаты, отметив предварительно,
X = Y X и Y представляют одно и то же число
X \= Y X и Y представляют разные числа
X ‹ Y X меньше Y
X › Y X больше Y
X =‹ Y X меньше или равно Y
X ›= Y X больше или равно Y
Отметим, что символ «меньше или равно» записывается не так, как во многих других языках программирования (обычно ‹=). Это сделано в Прологе для того, чтобы программист мог использовать похожий на стрелку атом ‹= для своих собственных нужд.
Поскольку операторы сравнения являются предикатами, можно было бы предположить, что в Прологе допустим следующий факт:
2›3.
утверждающий, что 2 на самом деле больше 3. Факты, подобные этому, с формальной стороны полностью соответствует правилам Пролога. Однако Пролог не разрешает добавлять факты к «встроенным» предикатам. Такая особенность предотвращает непредсказуемые изменения смысла встроенных предикатов. В главе 6 будут описаны все встроенные предикаты, в том числе и те, с которыми мы уже познакомились.
В качестве первого примера использования чисел предположим, что у нас есть база данных, содержащая сведения о принцах, правивших Уэльсом в 9-м и 10-м веках. Предикат правил(Х,Y,Z)истинен, если принц с именем Xнаходился у власти с года Yпо год Z. Список фактов базы данных выглядит следующим образом:
правил(родри,844,878).
правил(анаравд,878,916).
правил(хивел_дда,916,950).
правил(лаго_ад_идвал,950,979).
правил(хивел_аб_иеуаф,979,985).
правил(кадваллон,985,986).
правил(маредудд, 986,999).
Теперь предположим, что мы хотим узнать, кто был на троне Уэльса в каком-то конкретном году. Можно было бы определить правило, аргументами которого являлись бы имя и дата и которое просматривало бы базу данных и сравнивало заданную дату с теми, что указаны в фактах. Давайте определим предикат принц(X, Y),который истинен, если принц по имени Xбыл на троне в год Y:
X был
принцем в год Y, если:
X правил с года А по год В и
Y находится между А и В или совпадает с А или В.
Первое целевое утверждение будет согласовываться с базой данных путем поиска подходящего факта. Второе целевое утверждение верно, если Yравно А, или Yравно В, или Yлежит между Аи В. Для проверки можно использовать утверждения Y›=Аи Y=‹В. Переписав это на Прологе, получаем следующее правило:
принц (X,Y):-правил(Х,А,В),Y ›= А,Y =‹ В.
Ниже
приведено несколько возможных запросов и ответов, даваемых Пролог-системой.?- принц(кадваллон,986).
да
?- принц(родри,1979).
нет
?- принц(Х,900).
Х = анаравд
да
?- принц(X,979).
X = лаго_ад_идвал
X = хивел_аб_иеуаф да
Заметьте использование переменных в последних примерах. Убедитесь, что вы понимаете, как работает механизм поиска Пролога при ответе на подобные вопросы.
Арифметические операции могут также использоваться для вычислений. Например, если имеются сведения о населении и площади некоторой страны, то можно вычислить среднюю плотность населения для этой страны. Средняя плотность населения показывает, сколь тесно было бы в данной стране, если бы ее население было равномерно распределено по всей ее территории.
Рассмотрим следующую базу данных, содержащую сведения о населении и площади некоторых стран в 1976 г. Для представления связи между страной и ее населением будет использоваться предикат нас.В наши дни население обычно характеризуется довольно большими числами. Не все версии Пролога позволяют работать с такими числами. Поэтому будем исчислять население в миллионах: нас(Х, Y)означает, что население страны Xсоставляет примерно « Yмиллионов» людей. Предикат площадьбудет обозначать связь между страной и ее площадью (в миллионах квадратных километров):
нас(сша,203).
нас(индия, 548).
нас(китай,800).
нас(бразилия,108).
площадь(сша,8).
площадь(индия,3).
площадь(китай,9).
площадь(бразилия,8).
Теперь для того, чтобы найти среднюю плотность населения некоторой страны, мы должны использовать правило, гласящее, что значение плотности получается делением числа, представляющего население, на число, представляющее площадь.
Введем предикат плотность(Х,Y), где X – это страна, a Y – плотность населения в данной стране, и запишем соответствующее правило на Прологе:
плотность(X,Y):-нас(Х,Р), площадь(Х,А), Y is Р/А.
Данное правило читается следующим образом:
Плотность населения страны X представляется числом Y, если:
Население X– это Р, и Площадь X– это A, и Y вычисляется делением Р на A.
В правиле используется оператор деления '/' введенный в предыдущем разделе. Операция деления выполняется на самом деле как целочисленное деление, сохраняющее только целую часть результата.
Новым здесь является инфиксный оператор 'is'. Его правый аргумент – терм, интерпретируемый как арифметическое выражение. Для того чтобы выполнить 'is', Пролог сначала вычисляет его правый аргумент в соответствии с правилами арифметики. Результат вычислений проверяется на соответствие с левыми аргументами, чтобы определить, доказуемо ли целевое утверждение. В вышеприведенном примере переменная Yдо исполнения isне конкретизирована, и она остается в таком состоянии до вычисления выражения. Когда выражение вычислено, Yпринимает значение, равное полученной величине. Это означает, что должны быть известны значения всех переменных, находящихся справа от is.