В Прологе имеются также операции "-", "*", "/". Заметим, что порядок аргументов в выражениях значения не имеет. Так, выражение Х = А*В идентично А*В = Х.. В Прологе применяются следующие функции, позволяющие вычислять:
mod, X mod Y - остаток от деления Х на Y;
div, X div Y - целую часть частного от деления Х на Y;
abs(X) - абсолютную часть числа;
ехр(Х) - возведение е в степень X;
sqrt(X) - значение квадратного корня от X;
sin(X), cos(X), tg(X), arctg(X) - тригонометрические функции.
Для арифметических операции установлен следующий приоритет:
1)+,-; 2)*,/; 3)mod, div; 4)+,-(одноместные).
Рассмотрим применение арифметических операций "-" и "*" для вычисления факториала числа. Известно, что 1!=1 и n!=n*(n-l)!
В предикате "fact(X,Y)" Y является факториалом числа X.
Первое утверждение на Прологе записывается в виде следующего факта: fact(1,1). Для записи второго утверждения нужно:
1) из n вычесть единицу, получая Z;
2) вычислить факториал Z, получая X1;
3) умножить X1 на n, получая Y.
Таким образом, имеем следующую программу:
predicates
fact(real,real)
clauses
fact(l,l).
fact(X,Y) :- Z=X-1, fact(Z,X1), Y=X*X1.
Введем запрос fact(5,X) и получим правильный ответ: Х=120.
Но система продолжает поиск других решений и в окне "Message" выдает сообщение о том, что стек переполнен и нужно нажать клавишу ПРОБЕЛ.
Здесь не указано ограничение поиска, система продолжает уменьшать Х на единицу и пытается унифицировать это-результат с первым фактом fact(l.l). Для указания останова поиска есть несколько способов. Так, можно задать в первом факте предикат отсечения:
fact(l,l) :- !.
или этот предикат указать во втором правиле:
fact(X,Y) :- Z = X - 1, fact(Z,X1), !,Y = X*X1.
Можно задать условие, чтобы оставшееся значение превышало единицу:
fact(X,Y) :- Х>1, Z = X - 1, fact(Z,X1), Y = X*X1.
Пример 4.6
Вычислить 5!:
5! = 5 * 4! или
4! = 4 * З! или
З! = 3 * 2! или
2! = 2 * 1! или
= 1! = 1 т.е.
2! = 2 * 1 = 2 т.е.
З! = 3 * 2 = 6 т.е.
4! = 4 * 6 = 24 т.е.
5! = 5 * 24 = 120
В выражениях применяются логические операции: умножение (обозначается знаком "," ), сложение (обозначается знаком ";" ), отрицание. Так, используя операцию ИЛИ, правила
родители(Х, Y) :-отец(Х,Y).
родители(Х, Y) :- мать(Х,Y).
можно записать в виде
родители(Х,Y) :- отец(Х,Y); мать(Х,Y).
Операция отрицание обозначается предикатом "not". Так, утверждение not отец (a,d) истинно, если факт отец(а,d) отсутствует в БД.
Для сравнения значений применяются следующие операции отношений:
“>”,”>=”,”<”,”<=”,”=”,”<>” или “><” (не равно).
Обработка списков и строк символов
Список в Прологе представляется множеством элементов, разделенных запятой и ограниченных квадратными скобками.
Так, X = [a,b,c,d] является списком из четырех элементов.
Для разделения списка на части используется предикат "|" (вертикальная черта). Этот предикат разделяет список на голову и хвост. Головой списка может быть его первый элемент, тогда хвост списка есть подсписок, состоящий из всего списка за исключением его первого элемента. Так, если X=[a,b,c,d] и X=[Y|Z], то Y=a и Z=[b,c,d]. Заметим, что в случае списка, состоящего из одного элемента, Х=[а] и X=[Y|Z], тогда Y=a и Z=[]-пустой список, который обозначают открывающей и закрывающей квадратными скобками. Поскольку список делится на части, то его можно составлять из отдельных частей. Так, например, из одного элемента и списка можно получить новый список.
Пусть: 1) Х=а, Y=[b,c,d] и Z=[X|Y], тогда Z=[a,b,c,d] и 2) Х=а, Y=b, тогда Z=[a|b], а не Z=[a,b]. В первом случае Y - список, а во втором Y - элемент. Таким образом, соединение двух элементов дает список, состоящий из элемента и подсписка, а не из двух элементов.
Далее в этом параграфе рассмотрим процедуры работы со списками. Во многих случаях, чтобы упростить изложение, будем приводить только часть clauses Пролог-программ.
Принадлежность элемента списку. Предположим, что имеется список наименований деталей велосипеда: руль, рама, колесо, седло, и нужно определить, содержится ли некоторая деталь, например "седло", в данном списке.
Очевидно, что если элемент принадлежит списку, то он либо совпадает с головой списка, либо находится в его хвосте. Следовательно, прежде всего необходимо сравнить искомый элемент с головой заданного списка. В случае несовпадения аналогичные действия рекурсивно повторяются для списка-хвоста. Поиск завершается неудачей, если достигнут конец исходного списка.
Принадлежность элемента Х списку Y можно записать в виде предиката "принадлежит(Х,Y)". Для определения истинности этого предиката требуется проверить два условия. Первое состоит в проверке совпадения Х с головой списка X, что записывается на языке Пролог следующим образом:
принадлежит(Х,[Х|_]).
Для обозначения хвоста списка здесь используется анонимная переменная "_". Данный факт можно записать в виде правила:
принадлежит(Х,[Y|_]) :- X = Y.
Для определения принадлежности элемента Х хвосту списка будем использовать тот же предикат "принадлежит", в чем и заключается суть рекурсии. На Прологе это записывается правилом
принадлежит(Х,[_|Y]) :- принадлежит(Х,Y).
что означает: "X является элементом списка, если Х является элементом хвоста списка". В качестве головы списка применялась анонимная переменная, так как ее имя значения не имеет.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.