Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_РЛП_4_форм.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
644.61 Кб
Скачать

3.11.Работа с базой данных в языке пролог

Пролог-программу можно рассматривать как базу данных: описание отношений частично присутствует в ней в явном виде (факты), а частично - в неявном (правила). По последней причине ее можно также назвать базой знаний. В процессе выполнения программы можно создавать дополнительные предложения языка Пролог, которые включаются в базу. Можно также удалять из базы имеющиеся в ней предложения. Основные предикаты всегда завершаются успешно, а в качестве своего побочного эффекта вызывают:

consult(F) - чтение предложений пролог-программы из файла F;

reconsult(F) – аналогично consult(F), но в отличие от последнего - переопределяет ранее введенные определения;

assert(С) - добавление к базе данных предложения С;

retract( С) - удаление предложения, сопоставимого с С.

При возврате добавленные предложения из базы не удаляется, удаленные - не возвращается.

При добавлении нового предложения может оказаться важным указать, на какое место в базе данных его следует поместить. Такую возможность обеспечивают предикаты:

asserta(С) - помещает С в начале базы данных;

assertz( С) - помещает С в конец базы данных.

В большинстве реализаций база данных делится на статическую и динамическую. Детали работы встроенных предикатов зависят от конкретной реализации Пролога.

Пример 3.11.1. Таблица умножения.

Описание программы:

таблица_умножения(L):- принадлежит(X, L), принадлежит(Y, L), Z is X*Y, assert(произв(X,Y,Z)), fail.

таблица_умножения(L).

Вопросы к системе.

?- произв(А, В, 8).

No

?- таблица_умножения([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).

Yes

?- произв(А, В, 8).

А = 1, В = 8;

А = 2, В = 4;

А = 4, В = 2;

А = 8, В = 1;

Пример 3.11.2. Вычисление наибольшего общего делителя нескольких чисел.

Исходные числа находятся в базе данных в виде фактов вида «число(X)»/

Описание программы:

нод(X1):-число(X), число(Y), X>Y, Z is X-Y, retract(число(X)), един(Z), нод(X1),!.

нод(X):-число(X).

един(X):- число(X),retract(число(X)), един(X).

един(X):-assertz(число(X)).

Вопросы к системе.

?- assert(число(10)).

Yes

?- assert(число(15)).

Yes

?- assert(число(25)).

Yes

?- assert(число(30)).

Yes

?- нод(X).

X=5

По окончании работы база данных будет содержать единственное предложение вида число(5). Предикат един(X) обеспечивает единственность вхождения добавляемой записи в базу данных. Можно вместо един(X) использовать assertz(число(X)), но в этом случае по окончании работы база данных будет содержать несколько предложений вида число(5).

Пример 3.11.3. Исключение повторов в базе данных.

Описание программы:

in(a,b).

in(a,b).

in(c,b).

in(b,a).

in(c,b).

find(X,Y):-in1(X,Y),retract(in1(X,Y)),find(X,Y),!.

find(X,Y):-assertz(in1(X,Y)).

fiall:-in(X,Y),find(X,Y),fail.

fiall.

Вопросы к системе.

?- in(X,Y).

X= a, Y= b;

X= a, Y= b;

X= c, Y= b;

X= b, Y= a;

X= c, Y= b;

?- in1(X,Y).

No

?- fiall

Yes

?- in(X,Y)

X= a, Y= b;

X= a, Y= b;

X= c, Y= b;

X= b, Y= a;

X= c, Y= b;

?- in1(X,Y)

X= a, Y= b;

X= c, Y= b;

X= b, Y= a;

3.12.Предикаты поиска

bagof(X, P, L) - порождает список L всех объектов X, удовлетворяющих предикату Р.

Пример 3.12.1., Разбиения букв на два класса - гласные и согласные.

В базе данных содержатся предложения:

класс(а, глас).

класс(b, согл).

класс(с, согл).

класс(d, согл).

класс(е, глас).

класс(f, согл).

Вопросы к системе.

?- bagof(Буква, класс(Буква, согл), Буквы).

Буквы = [b, c, d, f]

?- bagof(Буква, класс(Буква, Класс), Буквы).

Класс = глас, Буквы = [а,е];

Класс = согл, Буквы = [b, c, d, f]

Если bagof(X, Р, L) не находит ни одного решения для Р, то цель bagof терпит неудачу. Если один и тот же Х найден многократно, то все его экземпляры будут занесены в L.

setof(X, P, L) - порождает список L объектов X, удовлетворяющих Р, но список L будет упорядочен, а из всех повторяющихся элементов, если таковые есть, в него попадет только один.

findall(X, P, L) - порождает список объектов, удовлетворяющих Р. В отличии от bagof собирает в список все объекты X, с различными значениями переменных из P, не входящих в X.

Пример 3.12.1 (продолжение)

Вопросы к системе.

?- setof(Класс/Буква, класс(Буква, Класс), Список).

Список = [глас/а, глас/е, согл/b, согл/с, согл/d, согл/f]

?- findall(Буква, класс( Буква, Класс), Буквы).

Буквы= [a, b, c, d, e, f]

Если не существует ни одного объекта X, удовлетворяющего P, то findall выдает L = [].

Пример 3.12.2. Вариант программирования предиката findall

findall(X, Цель, ХСпис):- саll(Цель), assert(очередь(X)), fail;

findall(X, Цель, ХСпис):- assertz(очередь(дно)), собрать( ХСпис).

собрать(L):- retract(очередь(Х)), !, собрать1(Х ,L).

собрать1(дно ,[]):-!.

собрать1(X , [X | Остальные]):- собрать(Остальные).

Упражнения 3.9.2. Исследовать работу программы, исключающей повторы в базе данных (пример 3.11.3).

  1. После ввода программы ввести вопросы:

?- in(X,Y)

?- in1(X,Y)

?- fiall

?- in(X,Y)

?- in1(X,Y)

  1. Исследовать варианты:

  • без отсечения в предикате find;

  • заменить в предикате find assertz на assert и asserta.

  1. Сравнить работу программы с работой предиката findall.

Для этого ввести вопрос: findall(X,in(X,Y),L)