Скачиваний:
50
Добавлен:
01.05.2014
Размер:
283.14 Кб
Скачать

Глава 8

Арифметика

Логические программы разд. 3.1, реализующие арифметику, очень элегантны, но практически непригодны. Любой приличный компьютер имеет эффективную аппаратную реализацию арифметических операций, и ни один реальный язык логического программирования не может игнорировать этот факт. Время выполнения операций, таких, как сложение, на большинстве компьютеров не зависит от размера слагаемых (если они не превосходят некоторой большой константы). Время же работы рекурсивной программы plus (программа 3.3) пропорционально размеру первого слагаемого. И хотя временные характеристики могут быть улучшены за счет использования двоичной или десятичной записи, но все же не на столько, чтобы быть сравнимыми с характеристиками мощной аппаратной реализации.

8.1. Системные арифметические предикаты

Роль арифметических предикатов, встроенных в Пролог, обеспечить непосредственный интерфейс с арифметическими возможностями компьютера. Плата за эффективность состоит в потере некоторыми машинно-ориентированными арифметическими операциями общности, присущей их логическим аналогам. Указанный интерфейс это арифметический вычислитель, использующий особенности арифметики применяемого компьютера. Edinburgh-Пролог содержит бинарный оператор is, предназначенный для арифметических вычислений. Мы предпочитаем более привычный бинарный оператор:= для обозначения того же предиката.

Операторы используются для того, чтобы сделать программу более удобной для чтения. Люди способны обучаться и приспосабливаться ко многому, например, они могут привыкнуть к чтению программ и на Лиспе, и на Фортране. Тем не менее, мы считаем, что синтаксис имеет важное значение; роль удачных обозначений в математике общеизвестна. Возможность определять и использовать операторы составляет существенную часть удобного синтаксиса языка Пролог.

Такие операторы, как , <, использовались и в предыдущих главах. Мы рассмотрим несколько операторов Пролога, которые будут вводиться по мере необходимости. Большинство версий Пролога предоставляет пользователю воз­можность определять свои собственные бинарные инфиксные и унарные префиксные и постфиксные операторы. При этом необходима некоторая форма объявления операторов для указания старшинства, имени и ассоциативных свойств каждого оператора. Способ описания этой информации в различных версиях различен. форма объявления операторов в версиях Edinburgh-Пролог и Wisdom-Пролог приведена в приложении С, там же дан список всех операторов, используемых в книге, и указано их старшинство.

Основной вопрос для арифметического вычислителя имеет вид Значение : = Выражение? и читается: “Значение есть Выражение”. Его интерпретация происходит следующим образом. Выражение вычисляется как арифметическое выражение. Результат успешного вычисления унифицируется с термом Значение, в соответствии с этим цель решается успешно или безуспешно.

Приведем несколько примеров простого сложения, поясняющих способ реализации и использования вычислителя. Цель (X:=5+3)? имеет решение Х = 8. Это обычное использование вычислителя, сопоставляющее переменной значение арифметического выражения. Цель (8:= 5+3)? решается успешно. Конкретизация обоих аргументов оператора “:=” позволяет проверять значение арифметического выражения. Вопрос (3+5:= 3+5)? приводит к отказу, так как левый аргумент 3+5 не унифицирован с термом 8, значением вычисленного выражения.

Вычислитель допускает использование стандартных операторов сложения, вычитания, умножения и деления (+, —,*,/), старшинство операций такое же, как в математике. В данной книге мы ограничимся целочисленной арифметикой. Поэтому / обозначает целочисленное деление, a mod обозначает целочисленный остаток.

Что происходит в тех случаях, когда вычисленный терм не является правильным арифметическим выражением? Выражение может быть неправильным по одной из двух причин, которые, по крайней мере концептуально, следует различать. Терм вида 3+х, где x - константа, не может быть вычислен. В отличие от этого терм 3+Y, где Y-переменная, может быть вычислен или не вычислен в зависимости от значения переменной Y.

Семантика любой логической программы полностью определена, и в этом смысле при работе логической программы не может возникнуть ошибки. Например, цель Х:= Y+3 имеет решения {X =3.Y= 0} Однако при выполнении логических программ на компьютере следует учитывать аппаратные ограничения. Ошибка возникает в тех случаях, когда машина не может определить результат вычислений из-за недостаточности информации, т.е. из-за неопределенности переменных. Эта ситуация отличается от той, в которой решение цели приводит к отказу. Расширения Пролога и других логических языков реагируют на подобные “ошибки” приостанов­кой вычисления выражения до тех пор, пока значения требуемых переменных не станут известны. Наша вычислительная модель Пролога не допускает приостановки вычислений. Поэтому в подобных случаях мы будем говорить не о безуспешных вычислениях, а о возникновении ошибочной ситуации (сообщении об ошибке).

Цель (X ;= 3+х)? приводит к отказу, так как правый аргумент не может быть вычислен как арифметическое выражение. Цель (Х:=3+Y)? является примером цели, которая может быть успешно решена, если Y сопоставлен с арифметическим выражением. В случае такой цели должно быть предусмотрено сообщение об ошибке.

Общее для новичков заблуждение состоит в трактовке оператора “:=” как оператора присваивания, знакомого по обычным языкам программирования, что приводит к такой записи цели: (N:=N+ 1)? Подобный вопрос бессмыслен. Решение цели приведет к отказу, если N сопоставлено со значением, и к ошибке, если N- переменная.

Предикат “: =” является примером системного предиката- Системные предикаты реализуются системой Пролога и доступны программисту. Другое название системных предикатов - вычисляемые предикаты. Приложение В содержит описание системных предикатов Wisdom-Пролога, используемых в книге.

Другими арифметическими системными предикатами являются операторы сравнения. Вместо того чтобы использовать логически определенные отношения <, >,, Пролог непосредственно использует арифметику применяемого компьютера. Мы опишем использование предиката <, остальные предикаты используются аналогично. Для ответа на вопрос < В)? А и В вычисляются как арифметические выражения. Численные результаты сравниваются. Если результат вычисления А меньше результата вычисления В, то решение цели успешно. Как и раньше, если А или В не является арифметическим выражением, то вычисление безуспешно, если А и В не основной пример, то выдается сообщение об ошибке.

Приведем несколько простых примеров. Вычисление цели (1<2)? успешно, то же самое относится к цели (3-2<2*3+ /)?. С другой стороны, вычисление цели (2<1)? приводит к отказу, a (N<1)? приводит к сообщению об ошибке, если N-переменная.

Проверка равенства и неравенства значений арифметических выражений производится с помощью системных предикатов =:= и =/=, которые вычисляют значения обоих аргументов и сравнивают результаты.

8.2. Повторное рассмотрение арифметических логических программ

Выполнение арифметики с помощью вычислений, а не логики требует пересмот­ра арифметических логических программ, приведенных в разд. 3.1. Очевидно, вычисления могут выполняться более эффективно. Например, при нахождении минимума двух чисел можно использовать арифметическое сравнение. При этом программа синтаксически не будет отличаться от программы 3.7. Аналогично наибольший общий делитель двух целых чисел можно эффективно вычислить с помощью обычного алгоритма Евклида, как это показано в программе 8.1. Заметим, что явное условие J < 0 необходимо, чтобы избежать неоднозначности решений при J= 0 и ошибок при обращении к предикату mod с нулевым аргументом.

greatest_.common_divisorfX Y,Z)

Z-наибольший общий делитель целых чисел Х и Y

greatest_common_divisor (1, 0, 1). greatest_common_divisor (I, J, Ged) 

J>0, R:= I mod J, greatest_common_divisor(J,R,Ged).

Программа 8.1. Нахождение наибольшего делителя двух целых чисел.

Арифметические программы на Прологе теряют два свойства арифметических логических программ. Прежде всего использование программ становится более ограниченным. Предположим, что мы хотим с помощью оператора := построить предикат plus(X,Y,Z), подобный описанному ранее. Очевидное определение-

plus(X,Y,Z)Z:=X+Y.

Оно пригодно, если Х и Y cопоставлены с целыми числами. Однако мы не можем использовать эту программу для вычитания, задавая вопросы вида plus (3.X,8)?,поскольку это вызовет сообщение об ошибке. Для того чтобы одну и ту же программу использовать и для сложения, и для вычитания, необходимы металогические проверки. Мы отложим этот вопрос до рассмотрения металогических предикатов в гл. 10.

Эффективность программы обусловливается специализацией ее использования, и поэтому трудно понять, что происходит при непредусмотренных использованиях программы. Например, программа 3,7, задающая отношение minimum, может быть надежно использована только при нахождении минимума двух целых чисел.

Другое свойство, отсутствующее в арифметических программах на Прологе, - рекурсивная структура чисел. В логических программах эта структура использовалась для определения применяемого правила и для гарантии завершения вычислений. Программа 8.2, вычисляющая факториал на Прологе, похожа на программу 3.6. Однако рекурсивное правило стало более громоздким. Первый аргумент рекурсивного обращения к процедуре factorial должен быть вычислен явно, он не может быть получен в результате унификации. Кроме того, следует явно указать условие применимости рекурсивного правила N>0, Это препятствует возникновению незавершающихся вычислений при решении таких вопросов, как factorial (—1,N)? или factorial (3,F)? В логической программе унификация рекурсив­ной структуры очевидным образом запрещает незавершающиеся вычисления.

factorial (N ,F)

F равно факториалу целого числа N.

factorial (N ,F)

N>0,N1 :=N-1,factorial(Nl,Fl),F:=N*F1.

factorial(0,l).

Программа 8.2. Вычисление факториала.

Программа 8.2 соответствует обычному рекурсивному определению факториала. В отличие от программы 3.7 данная программа может использоваться только для нахождения факториала заданного числа. Вопросы, в которых первый аргумент предиката factorial - переменная, вызовут сообщение об ошибке.

Нам следует изменить понятие корректности программ на Прологе с учетом особенностей выполнения арифметических проверок. Другие системные предикаты, вызывающие сообщения об ошибках, учитываются сходным образом. Программа на Прологе тотально корректна в области D, если решение любой цели, принадлежащей области D, завершается, не приводит к сообщению об ошибке и дает правильный ответ. Программа 8.2 тотально корректна во множестве целей, у которых первый аргумент-целое число.

Упражнения к разд. 8.2

1. Треугольное число с индексом N - это сумма всех натуральных чисел до N включительно.Напишите программу, задающую отношение triangle(N,Т), истинное, если T-треугольное число с индексом N. (Указание: используйте программу 8.2.)

2. Напишите программу на Прологе, задающую предикат power (Х,N,V), выполненный,если V равно XN. Как она может быть использована? {Указание: возьмите за основу программу 3.5, задающую отношение exp.)

3. Напишите программы на Прологе, аналогичные другим арифметическим логическим программам, приведенным в основном тексте и упражнениях разд.3.1.

Соседние файлы в папке 1-13