Prolog
Шрифт:
Предположим, что более предпочтительной для нас является следующая форма записи:
Элемент входит_в Список,
конкатенация_списков Список1 и Список2
дает Список3,
удаление_элемента Элемент из_списка Список
дает НовыйСписок, ...
Определите операторы "входит_в", "конкатенация_списков", "и" и т.д. таким образом, чтобы обеспечить эту возможность. Переопределите
Посмотреть ответ
Назад | Содержание | Вперёд
Назад | Содержание | Вперёд
3. 4. Арифметические действия
Пролог рассчитан главным образом на обработку символьной информации, при которой потребность в арифметических вычислениях относительно мала. Поэтому и средства для таких вычислений довольно просты. Для осуществления основных арифметических действий можно воспользоваться
несколькими предопределенными
операторами
.
+ сложение
– вычитание
* умножение
/ деление
mod модуль, остаток от целочисленного деления
Заметьте, что это как раз тот исключительный случай. когда оператор может и в самом деле произвести некоторую операцию. Но даже и в этом случае требуется дополнительное указание на выполнение действия. Пролог-система знает, как выполнять вычисления, предписываемые такими операторами, но этого недостаточно для их непосредственного использования. Следующий вопрос - наивная попытка произвести арифметическое действие:
?- Х = 1 + 2.
Пролог-система "спокойно" ответит
Х = 1 + 2
а не X = 3, как, возможно, ожидалось. Причина этого проста: выражение 1 + 2 обозначает лишь прологовский терм, в котором + является функтором, а 1 и 2 - его аргументами.
В вышеприведенной цели нет ничего, что могло бы заставить
систему выполнить операцию сложения.
Для этого в Прологе
существует
специальный оператор
is
(есть). Этот оператор заставит систему выполнить вычисление. Таким образом, чтобы правильно активизировать арифметическую операцию, надо написать:
?- Х is 1 + 2.
Вот теперь ответ будет
Х = 3
Сложение здесь выполняется специальной процедурой, связанной с оператором +. Мы будем называть такие процедуры встроенными.
В Прологе не существует общепринятой нотации для записи арифметических действий, поэтому в разных реализациях она может слегка различаться. Например, оператор '/' может в одних реализациях обозначать целочисленное деление, а в других - вещественное. В данной книге под '/' мы подразумеваем вещественное деление, для целочисленного же будем использовать оператор div. В соответствии с этим, на вопрос
?- Х is 3/2,
Y is 3 div 2.
ответ должен быть такой:
Х = 1.5
Y = 1
Левым аргументом оператора is
Х is 5 - 2 - 1
понимается как
X is (5 - 2) - 1
Арифметические операции используются также и при сравнении числовых величин. Мы можем, например, проверить, что больше - 10000 или результат умножения 277 на 37, с помощью цели
?- 277 * 37 > 10000.
yes (да)
Заметьте, что точно так же, как и is, оператор '>' вызывает выполнение вычислений.
Предположим, у нас есть программа, в которую входит отношение рожд, связывающее имя человека с годом его рождения. Тогда имена людей, родившихся между 1950 и 1960 годами включительно, можно получить при помощи такого вопроса:
?- рожд( Имя, Год),
Год >= 1950,
Год <= 1960.
Ниже перечислены операторы сравнения:
Х > Y Х больше Y
Х < Y Х меньше Y
Х >= Y Х больше или равен Y
Х =< Y Х меньше или равен Y
Х =:= Y величины Х и Y совпадают (равны)
Х =\= Y величины Х и Y не равны
Обратите внимание на разницу между операторами сравнения '=' и '=:=', например, в таких целях как X = Y и Х =:= Y. Первая цель вызовет сопоставление объектов Х и Y, и, если Х и Y сопоставимы, возможно, приведет к конкретизации каких-либо переменных в этих объектах. Никаких вычислений при этом производиться не будет. С другой стороны, Х =:= Y вызовет арифметическое вычисление и не может привести к конкретизации переменных. Это различие можно проиллюстрировать следующими примерами:
?- 1 + 2 =:= 2 + 1.
yes
>- 1 + 2 = 2 + 1.
no
?- 1 + А = В + 2.
А = 2
В = 1
Давайте рассмотрим использование арифметических операций на двух простых примерах. В первом примере ищется наибольший общий делитель; во втором - определяется количество элементов в некотором списке.