top-shop.ru
Мягкая игрушка Magic
Арифмитические действия

Прологовская арифметика.

Пролог система не считает символы +, -, * и т. д. чем то особым, и не пытается ничего вычислять до тех пор, пока мы не укажем ей, что это - запись арифметических действий. Чтобы лучше понять, что нам непонятно в арифметике Пролога, выполним следующие запросы к системе:
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- X = 2, Y is X - 1.

X = 2
Y = 1

yes
| ?- 
А вот так система поймет Вас неверно:
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- X = 2, Y = X - 1.

X = 2
Y = 2-1

yes
| ?- 
Пролог рассчитан главным образом на обработку символьной информации, при которой потребность в арифметических вычислениях относительно мала. Однако, было бы очень странным, если бы язык программирования компьютера не содержал набора математических функций и арифметических операторов.

Для осуществления основных арифметических действий, можно воспользоваться несколькими предопределенными операторами.

  • + Сложение
  • - Вычитание
  • / Деление (вещественное)
  • mod модуль (остаток от целочисленного деления)
Самое время сказать, что одно и то же выражение в Прологе может быть записано в инфиксной и постфиксной форме:

| ?- X = 15, Y is X mod 2.

X = 15
Y = 1

yes
| ?- X = 15, Y is mod(X,2).

X = 15
Y = 1

yes
| ?- 

Встроенные, математические предикаты в GNU Prolog (без простейших)

inc(E)Инкремент (увеличение на единицу)
dec(E)Декремент (уменьшение на единицу)
E1 /\ E2Побитовое "И"
E1 \/ E2Побитовое "ИЛИ"
E1 ^ E2Побитовое "XOR" (исключающее "ИЛИ")
\ EПобитовое "НЕ"
E1 << E2"Целочисленный сдвиг" E1 на E2 разряда влево
E1 >> E2"Целочисленный сдвиг" E1 на E2 разряда вправо
abs(E)Абсолютное значение (модуль числа)
sign(E)Знаковая функция, возвращает -1, 0 или 1
min(E1,E2)Вернет минимальный аргумент
max(E1,E2)Вернет максимальный аргумент
E1 ** E2Возведение в степень: E1E2
sqrt(E)Извлечение квадратного корня из E
Тригонометрия в радианах: atan(E), cos(E), acos(E), sin(E), asin(E)
exp(X)ex
log(X)Натуральный логарифм (по основанию e)
float(X)"Превращает" целое число X в вещественное
ceiling(X)"Округляет" вещественное число X до большего целого числа
floor(X)"Округляет" вещественное число X до меньшего целого числа
round(X)"Округляет" вещественное число X до ближайшего целого числа
truncate(X)"Целая часть" вещественного числа X
Арифметические операции используются также и при сравнении числовых величин. Ниже перечислены операторы сравнения, их основное отличие - вычисление конкретезирующих, числовых значений перед сравнением:
  • X > Y (арифметическое (X больше чем Y))
  • X < Y (арифметическое (X меньше чем Y))
  • X >= Y (арифметическое (X больше или равно Y))
  • X =< Y (арифметическое (X меньше или равно Y))
  • X=:=Y (арифметическое (X равно Y))
  • X=\=Y (арифметическое (X не равно Y))
Expr1 =:= Expr2 succeeds if eval(Expr1) = eval(Expr2).
Expr1 =\= Expr2 succeeds if eval(Expr1) not eq eval(Expr2).
Expr1 < Expr2 succeeds if eval(Expr1) < eval(Expr2).
Expr1 =< Expr2 succeeds if eval(Expr1) <= eval(Expr2).
Expr1 > Expr2 succeeds if eval(Expr1) > eval(Expr2).
Expr1 >= Expr2 succeeds if eval(Expr1) => eval(Expr2).

Наибольший общий делитель

Давайте рассмотрим использование арифметических операций на простом примере: нахождение наибольшего общего делителя двух чисел.

Если заданы два целых числа X и Y, то их наибольший делитель Z можно найти, руководствуясь следующими тремя правилами:

  1. Если X и Y равны, то Z равен X.
  2. Если X > Y, то Z равен наибольшему общему делителю разности Y - X.
  3. Если Y < X, то формулировка аналогична правилу (2), если X и Y поменять местами.
Реализуем это рекурсивное определение:
nod(X,X,X).
nod(X,Y,Z) :- X<Y, Y1 is Y-X, nod(X,Y1,Z).
nod(X,Y,Z) :- X>Y, X1 is X-Y, nod(X1,Y,Z).
Протестируем в GNU Prolog:
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- [user].
compiling user for byte code...
nod(X,X,X).
nod(X,Y,Z) :- X<Y, Y1 is Y-X, nod(X,Y1,Z).
nod(X,Y,Z) :- X>Y, X1 is X-Y, nod(X1,Y,Z).

user compiled, 4 lines read - 1188 bytes written, 4268 ms

(10 ms) yes
| ?- nod(20,25,X).

X = 5 ? ;

no
| ?- 

Вычисление факториала

GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- [user].
compiling user for byte code...
fact(0,1).
fact(X,F) :- X>0, X1 is X-1, fact(X1,F1), F is X*F1.

user compiled, 3 lines read - 800 bytes written, 4199 ms

(20 ms) yes
| ?- fact(5,X).

X = 120 ? ;

no
| ?- 
Блог изучающего Пролог

содержание