Арифметика в Прологе
Арифметические выражения
Простейшие операнды в арифметических выражениях:
* переменные,
* числа,
* вызовы арифметических функций,
* атомы.
Сложные арифметические выражения конструируются из операндов, круглых скобок и знаков операций.
Знаки операций:
унарные + , -
+ , - , * , /
// - целочисленное деление
mod - остаток от деления
^ - возведение в степень
Арифметические функции:
abs(X)
max(X,Y)
min(X,Y)
random(N) => 0£ i £ N (N,i - целые)
integer(X) - округление X до ближайшего целого
floor(R) => N (N£ R<N+1, пол - наибольшее целое £ R)
ceil(R) => N (N-1 < R £ N, потолок - наименьшее целое ³ R)
sqrt(X)
sin(X) - углы в радианах
cos(X)
tan(X)
asin(X)
acos(X)
atan(X)
log(X) º ln X
log10 (X)
exp(X) º e^X
pi =3.14159265358
e = 2.718281828459045
Описание предикатов. Используются следующие соглашения при описании предикатов в дальнейшем тексте (то же самое действует в help'е).
predicate(+A,-A,?A).
+ - входной аргумент
- - выходной аргумент
? - входной или выходной
Шаблон указывает возможные способы вызова предиката. Арность предиката указывается следующим образом:
predicate/3 - предикат с местностью (арностью) 3
Встроенные арифметические предикаты
Арифметические выражения вычисляются только тогда, когда они служат аргументами одного из встроенных арифметических предикатов.
=(?A,?B) , ?A = ? B - унификация термов A и B
?- X=3.
X = 3
Yes
?- X= 3+5.
X = 3 + 5
Yes
?- 3 = 1+2.
No
?- X = a+b.
X = a + b
Yes
is(-Number, +Expr) , -Number is +Expr
- детерминированный предикат (дает один ответ)
?- 5 is 2+(8 // 2).
No
?- 5 is (2+8) // 2.
Yes
?- X is 2*3,Y is 2^X.
X = 6
Y = 64
Yes
?- A is a+b. => ошибка
Предикаты сравнения чисел
+Expr1 > +Expr2 или >(+Expr1,+Expr2)
+Expr1 < +Expr2
+Expr1 =< +Expr2
+Expr1 >= +Expr2
+Expr1 =:= +Expr2 (равно)
+Expr1 =\= +Expr2 (не равно)
Программирование числовых функций
Предикат f(+N,?R) истинен тогда и только тогда, когда R равно факториалу натурального числа N, т.е. N! = R (= 1´2´…´N).
f(0,1).
f(X,Y):-
X > 0,
X1 is X -1,
f(X1,Y1),
Y is X*Y1.
Программирование с накапливающим параметром позволяет писать эффективные рекурсивные программы.
f1(N,N,R,R).
f1(N,X,Y,R):-
X =\= N,
X1 is X+1,
Y1 is Y*X1,
f1(N,X1,Y1,R).
f(N,R):-
f1(N,0,1,R).
Здесь второй параметр накапливает значение аргумента, третий – текущее значение факториала.
Лисп и Пролог основаны на рекурсии, поэтому есть некоторое сходство в стиле программирования. Основное отличие в том, что в функциональном программировании значение функции определяется в виде выражения, а на Прологе это выражение задается в виде терма, являющегося одним из аргументов предиката. Это похоже на различие между двумя способами возвращения результата процедуры. Его можно присвоить имени функции, а можно присвоить параметру - результату процедуры или подпрограммы. Второе главное отличие состоит в использовании предикатов в качестве “охраняющих условий” в начале дизъюнктов вместо условных выражений.