- •Введение
- •1. Составление программ
- •1.1. Основные определения
- •1.2. Декларации в программах
- •1.3. Объявление предикатов и типов их аргументов
- •1.4. Другие разделы программы
- •Упражнения
- •2. Механизмы доказательства правил
- •2.1. Сопоставление с откатом
- •2.2. Рекурсия
- •Упражнения
- •3.Операции в Visual Prolog. Ввод-вывод
- •3.1. Операции
- •3.2. Предикаты ввода-вывода
- •4. Управление процессом доказательства правил
- •4.1. Искусственный откат
- •4.2. Отсечение
- •4.3. Повтор, определяемый пользователем
- •5. Списки
- •5.1. Процедуры обработки списков
- •5.2. Организация стеков и очередей
- •6. Внутренняя база фактов
- •7. Иерархическая организация данных
- •8. Работа с деревьями и графами
- •8.1. Двоичные деревья
- •8.2. Графы
- •9. Работа с именами и строками
- •Заключение
- •Библиографический список
- •Оглавление
Упражнения
1. Какими значениями будут конкретизированы переменные при выполнении сопоставления следующих двух термов?
треугольник (вершина(X,Y), вершина(10,Z), вершина(15,30)) и
треугольник (вершина(2,3), вершина(X,45), W)
2. Заданы следующие факты и правило
a(n1,n2).
a(n3,n4).
b(n5).
b(n6).
с:- a(X,Y), b(X).
Как детально выполняется доказательство цели «с»? Если доказательство невозможно, то, что надо изменить или добавить в программу?
3. Рекурсивный алгоритм вычисления факториала следующий:
Fact (0) = 1
Fact (N) = N*Fact(N-1)
Напишите тело правила рекурсивной процедуры для предиката
fact(N, F), где F - значение факториала для числа N.
fact(0, 1).%терминальный предикат
fact(N, F):-?
(Тело состоит из 3-х предикатов. Последний из них вычисляет значения F.)
3.Операции в Visual Prolog. Ввод-вывод
3.1. Операции
Операции в VIP можно разделить на три группы: арифметические, логические и сравнения. Возможности операций схожи с возможностями аналогичных операций в других алгоритмических языках высокого уровня. Операции осуществляются встроенными предикатами.
Арифметические операции (+, - , * , / ) и математические функции (abc(X), sin(X) и т.п.) применимы только к объектам типа real и integer. К логическим, кроме уже рассмотренных конъюнкции и дизъюнкции, относится операция not, применяемая к предикатам. Операции сравнения ( >, >=, <, <= ) могут применяться к объектам любого типа.
Предикат random(RealNumber) используется в качестве датчика случайных чисел и возвращает вещественное число, удовлетворяющее двойному неравенству 0<= RealNumber <1.
Арифметические и математические выражения составляются с помощью знаков операций и предиката «=» и рассматриваются в программе как цель или подцель. Правила доказательства «=» похожи на правила операции сопоставления, а именно,
для двух термов X и Y выражение X=Y успешно:
если оба терма одинаковые константы;
если X (Y) – переменная, Y(X) – константа, при этом
переменная конкретизируется константой.
Если обе переменные конкретизированы, то выполняется их сравнение, так что вторая подцель в последовательности «X=1, X=X» всегда будет успешной, а в последовательности «X=1, X=X+1» – неуспешной. Если оба терма переменные, то они связываются таким образом, что при конкретизации одной вторая приобретает такое же значение.
Выражения при откате не пересогласовываются, управление переходит на предыдущую подцель. Заметим, что в традиционном Прологе выражения составляются с помощью предиката «is», а предикат «=» служит для сравнения двух термов.
Подробнее рассмотрим предикат not, реализующий операцию отрицания. Он работает по следующему правилу: если Цель успешна, то not( Цель) неуспешна, иначе not ( Цель) успешна.
В качестве примера использования not приведем определение пользовательского предиката «различны/2». Оно имеет следующий вид:
различны ( X, Y) :-not ( X = Y).
При использовании предиката not переменные, являющиеся его аргументами, должны быть конкретизированы.
3.2. Предикаты ввода-вывода
Операции ввода - вывода в консольном режиме выполняются на установленных в данный момент устройствах вывода или ввода данных. Стандартными (установленными по умолчанию) устройством вывода (чтения) для консольного режима является экран (screen), для ввода – клавиатура (keyboard). Предикатами ввода данных являются readint(X) для ввода целого числа, readreal(X) для действительного, readchar(X) для символа, readln(X) для строки, readterm(домен_предиката, X) для предиката. Аргумент X при этом должен быть свободной переменной.
Основной предикат для вывода – write(T1, T2, …), в котором T1, T2, … связанные переменные или константы. Предикат nl переводит вывод на новую строку.
При откате предикаты ввода-вывода не пересогласовываются.
Приведем пример программы для вычисления значения функции:
x*x, если x*y<z
F(x,y,z)= y+z, если x*y=z
x*y-z, если x*y>z
PREDICATES
function(real, real, real, real)
run
CLAUSES
function(X, Y, Z, F) :- X*Y < Z, F = X*X.
function(X, Y, Z, F) :- X*Y = Z, F = Y+Z.
function(X, Y, Z, F) :- X*Y > Z, F = X*Y-Z.
run:-write("Введите значения"),nl,
write("X="),readreal(X),write("Y="),
readreal(Y), write("Z="), readreal(Z),
function(X, Y, Z, F),
write("Результат f(x,y,z)=", F), readchar(_).
GOAL
run.
(Предикат readchar(_) используется для установки режима ожидания ввода, который до нажатия любой клавиши не меняет содержимое экранной области; это дает пользователю возможность просмотреть полученный результат в VIP.)
Текущее устройство ввода или вывода может быть переназначено на другое, например, принтер или файл. Последний к моменту выполнения операции должен быть открыт для одного из следующих четырех действий: чтения, записи, присоединения к этому файлу новых записей или обновления. Файл, открытый для записи, обновления и добавления, по окончании работы должен быть закрыт. Можно одновременно открыть несколько файлов, причем направления, по которым перемещаются входные и выходные данные, можно менять, выбирая между открытыми файлами и переназначая текущее устройство.
Логические имена файлов должны начинаться со строчной буквы и присутствовать в декларации файлового домена, причем в программе файловый домен может быть только один. Имена файлов в нем разделяются символом «;».
Предикаты для работы с файлами в Visual Prolog 5.1:
openread (SymFN, FN) открывает файл для чтения, SymFN символьное логическое имя файла в программе, FN – имя физического файла;
openwrite(SymFN, FN) открывает файл для записи;
openmodify(SymFN, FN) открывает файл для модификации;
closefile(SymFN) закрывает файл; результат выполнения всегда «истина», даже если файл не был открыт;
readdevice(SymFN) – переназначение текущего устройства чтения, при условии, что переменная SymFN связана, а файл открыт для чтения; если переменная свободна, то предикат свяжет ее с именем текущего активного устройства чтения;
writedevice(symFN) – переназначает текущее устройство
записи при условии, что файл открыт или для записи или
для добавления;
deletefile(FN) удаляет файл.
Программа, которая читает из файла auto.txt факты, каждый из которых записан на одной строке по шаблону auto(марка, год), и выводит их на экран, выглядит следующим образом:
DOMAINS
запись = auto(марка, год)
марка= symbol
год = integer
file=auto_file
PREDICATES
run
CLAUSES
run :-not(eof(auto_file)),readterm(запись,
auto(Name, Year)), X= auto(Name, Year),
writedevice(screen), write(X), nl,
run.
GOAL
openread(auto_file, "d:\\auto.txt"),
readdevice(auto_file),run,closefile(auto_file).
Примечания.
1. Рекурсия run останавливается при достижении конца файла (предикат eof(..) возвращает истину) и поэтому правило всегда ложно.
2. Домен «запись» называется составным доменом ( см. разд. 7).
