Шаг 49.
Основы логического программирования.
Арифметические вычисления и сравнения

    На этом шаге мы рассмотрим арифметические вычисления и сравнения.

    Возможности вычислений и сравнений в Прологе аналогичны соответствующим возможностям таких языков программирования, как С, Pascal. Пролог включает полный набор арифметических функций. Вычислительные возможности Пролога уже были показаны на нескольких простых примерах.

    На этом шаге приведен обзор встроенных в Пролог предикатов и функций для выполнения вычислений и сравнений.

Арифметические выражения

    Арифметические выражения состоят из операндов (чисел и переменных), операторов (+,-,/,*,div и mod) и скобок. Символы в правой части от знака равенства (который является предикатом =) составляют арифметическое выражение. Например:

    А=1+6/(11+3)*Z

    Шестнадцатеричные и восьмеричные числа начинаются с "0х" или "0о" соответственно. Например:

    OxFFF=4095
    86=0о112+12

    Значение выражения может быть вычислено, только если все переменные в момент вычисления определены. При этом вычисления производятся в порядке, определяемом приоритетом операции. Операции с высшим приоритетом выполняются первыми.

Операции

    Пролог может выполнять все четыре осноные арифметические операции (сложение, вычитание, умножение и деление) между целыми и вещественными числами. Тип результата приведен и таблице 1.

Таблица 1. Арифметические операции
Операнд 1 Оператор Операнд 2 Результат
Целое +, -, * Целое Целое
Вещественное +, -, * Целое Вещественное
Целое +, -, * Вещественное Вещественное
Вещественное +, -, * Вещественное Вещественное
Целое или вещественное / Целое или вещественное Вещественное
Целое Div Целое Целое
Целое Mod Целое Целое

    В случае смешанной целочисленной арифметики, включающей и знаковые и безнаковые числа, результат знаковый. Размер результата будет равен большему из размеров двух операндов.

Порядок вычислений

    Арифметические операции вычисляются в следующем порядке:

    Порядок операций показан в таблице 2.

Таблица 2. Порядок операций
Операция Приоритет
-, + 1
x, /, mod, div 2
-, +(унарные) 3

    В выражении A=1+6/(11+3)*Z, предположим, что Z имеет значение 4, ибо переменные должны быть связаны до вычисления. Вычислим это выражение:

  1. (11+3) - первое вычисляемое подвыражеие, т. к. оно заключено в скобки, оно вычисляется как 14.
  2. Затем вычисляется 6/14, т. к. / и * вычисляются слева направо. В результате получим 0.428571.
  3. Далее 0.428571*4 дает 1.714285.
  4. Наконец, вычисляя 1+1.714285, получаем значение выражения 2.714285.

    А получит значение 2.714285, которое принадлежит вещественному домену.

    Следует поупражняться в управлении вещественными числами. В большинстве случаев они не представлены точно, и маленькие ошибки могут накапливаться, выдавая непредсказуемые результаты.

Функции и предикаты

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

Таблица 3. Арифметические предикаты и функции Пролога
Имя Описание
X mod Y Возвращает остаток от деления (модуль) X на Y
X div Y Возвращает частное от деления X на Y
abs(X) Если значение X- положительная величина value, abs(X) возвращает это значение; в противном случае - 1*value
cos(X) Возвращает косинус своего аргумента
sin(X) Возвращает синус своего аргумента
tan(X) Возвращает тангенс своего аргумента
arctan(X) Возвращает арктангенс вещественного значения, с которым связан X
exp(X) Возводит е в степень X
ln(X) Логарифм X по основанию е
sqrt(X) Корень квадратный из X
random(X) Присваивает X случайное вещественное число; 0<=X<1
random(X,Y) Присваивает Y случайное целое число; 0<=Y
round(X) Округляет значение X. Результат вещественный
trunc(X) Усекает X. Результат вещественный


    Замечание. Тригонометрические функции требуют, чтобы X был величиной, представляющей угол в радианах.

Генератор случайных чисел

    Для генерации случайных чисел в Прологе предусмотрены два стандартных предиката. Один из них возвращает случайное вещественное число в диапазоне от 0 до 1, другой возвращает случайное целое число в диапазоне от 0 до данного числа. Кроме того, случайная числовая последовательность может быть переинициализирована.

Предикат random/1

    Эта версия random возвращает случайное вещественное число RandomReal, которое удовлетворяет условию:

    0<=RandomReal<1.

    random/1 имеет формат:

   random(RandomReal)  %  (о)

Предикат random/2

    Эта версия random имеет два аргумента, его формат:

   random(MaxValue,Randomlnt)  %  (i,о)

    Этот предикат ставит в соответствие RandomInt случайное целое, удовлетворяющее условию:

    0<=RandomInt<MaxValue

    Предикат random/2 работает значительно быстрее, чем random/1, т.к. random/2 использует только целочисленную арифметику.

    В качестве примера приведем программу, которая использует random/1 для набора трех имен из пяти случайным обpaзом.

   predicates
      person(integer,symbol) 
      rand_int_1_5(integer)
      rand_person(integer)
   clauses
      person(1,fred).
      person(2,tom).
      person(3,mary). 
      person(4,dick).
      person(5,george).

      rand_int_1_5(X):-
         random(Y),
         X=Y*4+1.
      rand_person(0):-!.
      rand_person(Count):-
         rand_int_1_5(N),
         person(N,Name),
         write(Name),nl,
         NewCount=Count-1,
         rand_person(NewCount).
   goal
      rand_person(3).
    Текст этой программы можно взять здесь.

    На следующем шаге мы рассмотрим целочисленную и вещественную арифметику.




Предыдущий шаг Содержание Следующий шаг