Главная
»
Информационные системы
»
Представление знаний в ИС
»
Язык 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.
· К моменту выполнения операций все их аргументы должны быть конкретизированы числами.
· Значения арифметических выражений можно сравнивать с помощью таких операторов, как <, =< и т.д. Эти операторы вычисляют значения своих аргументов.
Друзья! Приглашаем вас к обсуждению. Если у вас есть своё мнение, напишите нам в комментарии.