Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ФиЛП_материалы / Материалы / Prolog / ПособиеПролог.doc
Скачиваний:
55
Добавлен:
01.06.2015
Размер:
449.02 Кб
Скачать

Упражнения

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).

Соседние файлы в папке Prolog