Главная
»
Информационные системы
»
Представление знаний в ИС
»
Язык Prolog. Арифметические действия.
Язык Prolog. Арифметические действия.
Язык Prolog. Арифметические действия
Пролог
рассчитан главным образом на обработку символьной информации, при
которой потребность в арифметических вычислениях относительно мала.
Поэтому и средства для таких вычислений довольно просты. Для
осуществления основных арифметических действий можно пользоваться
несколькими предопределенными операторами.
+ сложение
- вычитание
* умножение
/ деление
mod модуль, остаток от целочисленного деления.
Следующий вопрос - наивная попытка произвести арифметическое действие:
?- Х =1+ 2
Пролог-система «спокойно» ответит
Х = 1+2
а
не Х=3, как возможно ожидалось. Причина этого проста: выражение 1+2
обозначает лишь прологовский терм, в котором + является функтором, а 1
и 2 - его аргументами. В вышеприведенной цели нет ничего, что могло бы
заставить систему выполнить операцию сложения. Для этого в Прологе
существует специальный оператор is (есть). Этот оператор заставит
систему выполнить вычисление. Таким образом, чтобы правильно
активизировать арифметическую операцию надо написать
?- Х is 1 + 2
Вот теперь ответ будет
Х=3
Сложение здесь выполняется специальной процедурой, связанной с оператором +. Мы будем называть такие процедуры встроенными.
В
Прологе не существует общепринятой нотации для записи арифметических
действий, поэтому в различных реализациях она может слегка различаться.
Например, оператор `/' в одних реализациях означать целочисленное
деление, а в других вещественное. В нашей реализации `/' означает
вещественное деление, а для целочисленного же будем использовать
оператор `//'. В соответствии с этим на вопрос
?- Х is 3 / 2,
Y is 3 // 2.
ответ должен быть такой
Х = 1.5
Y = 1.
Левым
аргументом оператора is является простой объект. Правый аргумент -
арифметическое выражение, составленное с помощью арифметических
операторов, чисел и переменных. Поскольку оператор is запускает
арифметические вычисления, к моменту начала вычисления этой цели все ее
переменные должны быть конкретизированы какими-либо числами. Приоритеты
этих предопределенных операторов выбраны с таким расчетом, чтобы
операторы применялись к аргументам в том порядке, который принят в
математике. Чтобы изменить обычный порядок вычислений, применяются
скобки (тоже, как в математике). Заметьте, что +, -, *, /, //
определены как yfx, что определяет порядок их выполнения слева направо.
Например,
Х is 5 - 2 -1
понимается как
Х is (5 -2) - 1
Арифметические
операции используются также и при сравнении числовых величин. Мы можем,
например, проверить, что больше 10000 или результат умножения 277 на 37
с помощью цели
?- 277 * 37 > 10000
yes
Заметьте, что так же как и is, оператор `>' вызывает выполнение вычислений.
Предположим,
у нас есть программа, в которую входят отношения рожд, связывающее имя
человека с годом его рождения. Тогда имена людей, родившихся между 1950
и 1960 годами включительно, можно получить при помощи такого вопроса:
?- рожд( Имя, Год),
Год >= 1950,
Год <= 1960.
Ниже перечислены операторы сравнения
X > Y X больше Y
X < Y X меньшеY
X >= Y X больше или равенY
X =< Y X меньше или равенY
X =:=Y величины X и Yсовпадают (равны)
X =\=Y величины X иYне равны
Обратите
внимание на разницу между операторами сравнения `=' и `=:=', например в
таких целях как X = Y и X =:= Y. Первая цель вызовет сопоставление
объектов X и Y, и если X и Y сопоставимы, возможно приведет к
конкретизации каких-либо переменных в этих объектах. Никаких вычислений
при этом производиться не будет. С другой стороны X =:= Y вызовет
арифметическое вычисление и не может привести к конкретизации
переменных. Это различие можно проиллюстрировать следующими примерами
?- 1+2 =:= 2+1
yes
? - 1+2 =2+1
no
?- 1 + A = B + 2
A = 2
B =1.
Давайте
рассмотрим использование арифметических операций на двух простых
примерах. В первом примере ищется наибольший общий делитель, во втором
- определяется количество элементов в некотором списке.
Если заданы два целых числа Х иY, то их наибольший общий делитель Д можно найти, руководствуясь следующими тремя правилами:
1) Если Х иY равны то Д равен Х.
2) Если Х >Y, то Д равен наибольшему общему делителю Y и разности Х - Y.
3) Если Y < Х, то формулировка аналогична правилу 2), если Х иY поменять в нем местами.
На
примере легко убедиться, что эти правила действительно позволяют найти
наибольший общий делитель. Выбрав, скажем, Х=20 и Y=25 мы
руководствуясь приведенными правилами, после серии вычитаний получим
Д=5.
В
нашем следующем примере требуется произвести некоторый подсчет, для
чего, как правило, необходимы арифметические действия. Примером такой
задачи может служить вычисление длины какого-либо списка; иначе говоря,
подсчет его элементов. Определим процедуру
длина( Список, N)
Которая
будет подсчитывать элементы списка Список и конкретизировать N
полученным числом. Как и раньше. Когда речь шла о списках, полезно
рассмотреть два случая:
1) Если список пуст, то его длина равна 0.
2) Если список не пуст, то Список = [Голова| Хвост] и его длина равна 1 плюс длина хвоста Хвост.
Эти два случая соответствуют следующей программе:
длина([],0).
длина([_| Хвост], N):-
длина( Хвост, N1) ,
N is 1 + N1.
Применить процедуру длина можно так:
?- длина( [a,b, [c,d], e], N).
N=4
Заметим,
что во втором предложении этой процедуры две цели его тела нельзя
поменять местами. Причина состоит в том, что переменная N1 должна быть
конкретизирована до того, как начнет вычисляться цель
N is 1+N1
Таким
образом, мы видим, что введение встроенной процедуры is привело нас к
примеру отношения, чувствительного к порядку обработки предложений и
целей. Очевидно, что процедурные соображения для подобных отношений
играют жизненно важную роль.
Итак
· Для выполнения арифметических действий используются встроенные процедуры.
·
Арифметические операции необходимо явно запускать при помощи встроенной
процедуры is. Встроенные процедуры связаны также с предопределенными
операторами +, -, *, /, // и mod.
· К моменту выполнения операций все их аргументы должны быть конкретизированы числами.
·
Значения арифметических выражений можно сравнивать с помощью таких
операторов, как <, =< и т.д. Эти операторы вычисляют значения
своих аргументов.
Друзья! Приглашаем вас к обсуждению. Если у вас есть своё мнение, напишите нам в комментарии.