- •1. Особенности языка
- •2.1. Синтаксис языка.
- •2.2. Типы вопросов.
- •2.3. Рекурсия. Декларативная и процедурная семантики.
- •2.4. Встроенные предикаты
- •2.5. Списки
- •3. Основы Турбо-Пролога
- •3.1. Интерфейс пользователя
- •3.2. Структура программ на Турбо-Прологе
- •3.3. Первые примеры
- •Экспертные системы
- •1. Определение и основные требования.
- •Общая структура эс.
- •Правила типа «если - то».
- •Продукционные системы.
- •Продукции
- •Рабочая память.
- •Механизм вывода (интерпретатор правил).
- •Машина вывода.
- •Различные стратегии поиска вывода.
- •Перцептро́н
3.3. Первые примеры
Рассмотрим простые примеры программ на Турбо-Прологе, причем первые три из них (3.3.1 – 3.3.3) являются модификациями примеров, рассмотренных в пп. 2.2 – 2.4.
3.3.1. Родственные отношения
На рис. 3 представлен упрощенный вариант программы, аналогичной программе из пп. 2.2 – 2.3 «Родственные отношения». В ней используются два предиката: parent (родитель), задающий отношение «родитель → сын или дочь» и ancestor (предок), задающий отношение «предок → потомок». Комментарии к этому примеру не требуются.
3.3.2. Библиотечные каталоги.
Ниже представлена модифицированная программа из примера (1) п. 2.4:
/* Программа "Библиотечные каталоги"
Назначение: демонстрация использования
функтора */
domains
personal_library = book(title,author,publisher,
year)
collector,title,author,publisher=symbol
year=integer
predicates
collection(collector,personal_library)
clauses
collection("Анисимова",
book("Программирование на языке Пролог",
"Клоксин У., Меллиш К.",
"Мир",1987)).
collection("Анисимова",
book("Логика в решении проблем",
"Ковальски Р.",
"Наука",1990)).collection("Братчиков",
book("Синтаксис языков программирования",
"Братчиков И.Л.",
"Наука",1975)).
collection("Анисимова",
book("Язык программирования Пролог",
"Стобо Дж.",
"Радио и связь",1993)).
collection("Анисимова",
book("Системы продукций",
"Яхно Т.М.",
"АН СССР. Сиб. отделение",1990)).
collection("Братчиков",
book("Введение в МПролог",
"Иванова Г.С., Тихонов Ю.В.",
"МГТУ",1990)).
collection("Братчиков",
book("Принципы искусственного интеллекта",
"Нильсон Н.",
"Радио и связь",1985)).
collection("Братчиков",
book("Реализация экспертных систем",
"Клещев А.С.",
"Препринт ДВО АН СССР",1988)).
collection("Братчиков",
book("Компиляторы",
"Ахо А., Сети Р., Ульман Дж. ",
"Вильямс", 2003)).
Отметим способ описания домена personal_library. Домен описан с помощью функтора book. После него описаны домены, представляющие компоненты функтора. На рис. 5 представлено расширенное диалоговое окно с вопросом и тремя вариантами решения.
Рис. 4
3.3.3. Целые числа в заданном интервале.
Модифицированная программа из примера (2), п. 2.4 представлена на рис. 4.
Рис. 5
В главном меню, показанном на рис. 5, расширено окно редактора – для того, чтобы в нем поместилась вся программа. В окне Dialog содержатся тексты, выведенные встроенным предикатом write, и введенные пользователем нижняя и верхняя границы интервала.
3.3.4. Простые числа
Усложним условие предыдущего примера: пусть необходимо вывести простые числа, находящиеся в заданном интервале. Программа, решающая данную задачу, может быть построена на основе предыдущей программы, в которую нужно включить проверку того, является ли очередное число из интервала простым. Соответствующий фрагмент программы содержит два предиката: prime_number и del. Анализ числа заключается в проверке отсутствия у него делителей и выводе его при положительном результате этой проверки. Если в заданном интервале нет простых чисел, вместо них выводится сообщение «Отсутствуют!».
/* Программа "Простые числа в заданном интервале".
Назначение: выделение простых чисел. */
predicates
beg
print(integer, integer, integer)
prime_number(integer)
del(integer, integer)
clauses
beg:-
write("Введите нижнюю границу интервала: "),
readint(A),
write("Введите верхнюю границу интервала: "),
readint(B), A<=B,
write ("Простые числа в интервале [",A,",",B,"]:"),
Nl, print(A,B,0),!.
beg:- write("Неверные начальные данные!"), Nl, fail.
print(N,M,R):- N <= M, prime_number(N),
write(N, " "), Q = 1, K = N+1,
print(K,M,Q).
print(N,M,R):- N <= M, K = N+1, print(K,M,R).
print(_,_,0):- write("Отсутствуют!"), Nl.
print(_,_,_):- Nl.
prime_number(N):- N = 3.
prime_number(N) :- N > 3, D = N div 2, del(N,D).
del(_,1):- !.
del(N,D) :- N mod D = 0, !, fail.
del(N,D) :- E = D-1, E >= 1, del(N,E).
На рис. 7 изображено расширенное диалоговое окно с двумя вопросами.
Рис. 7
3.3.5. Ханойские башни
Эта известная головоломка имеет относительно простое и изящное решение в системе Турбо-Пролог. Напомним условие головоломки.
Имеются три стержня, на первом из которых нанизаны кольца с уменьшающимся наверх диаметром (кольцо с наибольшим диаметром находится внизу, с наименьшим – наверху). Требуется перенести пирамиду с первого стержня на третий, расположив кольца в том же порядке. При этом можно выполнять следующие ходы:
1) кольцо с вершины стержня может быть перенесено на любой пустой стержень;
2) обозначим диаметр кольца, находящегося на вершине стержня А через DA, диаметр кольца на вершине стержня В через DB. Кольцо с вершины стержня А может быть перенесено на стержень В, если DA < DB.
Алгоритм переноса, состоящий из наименьшего числа шагов, выполняет в цикле следующие шаги:
в случае нечетного числа колец 1) обмен между стержнями 1 и 3; 2) обмен между стержнями 1 и 2; 3) обмен между стержнями 2 и 3. |
в случае четного числа колец 1) обмен между стержнями 1 и 2; 2) обмен между стержнями 1 и 3; 3) обмен между стержнями 2 и 3. |
Обмен понимается как перенос кольца с вершины одного стержня на другой стержень. Например, если D1 < D3, кольцо с первого стержня переносится на третий, в противном случае – с третьего на первый.
Решение этого примера весьма полезно для практического изучения особенностей Турбо-Пролога и его интерпретатора.