Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по Прологу.doc
Скачиваний:
68
Добавлен:
01.05.2014
Размер:
501.25 Кб
Скачать

Vife(X):–family(_,X,_). % X – жена

child(X):–family(_,_,Children), % X – ребенок

member(X,Children).

exist(X):–husband(X); vife(X); child(X). % X – любой член семьи

dohod(mem(_,_,_,worker(_,D)),D). % D – доход работающего

dohod(mem(_,_,_,notwork),0). % 0 – доход неработающего

Этими процедурами можно воспользоваться, например, в следующих запросах к базе данных:

1) найти имена и фамилии всех людей из базы данных:

Goal exist(mem(Nam,Fam,_,_)).

2) Найти всех работающих жен:

Goal vife(mem(Nam,Fam,_,worker(_,_))).

3) Найти фамилии людей, чей доход меньше чем 8000:

Goal exist(Man), dohod(Man,D), D<8000.

21. Задача "Ханойская башня". Имеется три стержня А,В,С. На стержне А лежит N дисков пирамидой, сужающейся кверху. Надо переместить диски со стержня А на стержень C, используя промежуточный стержень B и соблюдая законы:

1) диски можно перемещать с одного стержня на другой по одному;

2) нельзя класть больший диск на меньший;

3) при переносе дисков с одного стержня на другой можно использовать промежуточный третий стержень, на котором диски должны находиться тоже только в виде пирамиды.

Если в программе использовать рекурсивную процедуру, то программа становится удивительно маленькой: два рекурсивных вызова процедуры и оператор вывода результатов перемещения дисков.

Собственно "перемещению" диска соответствует оператор вывода, указывающий, с какого стержня на какой переместить диск. Основным рабочим предикатом является рекурсивный предикат move. Базовое правило этой рекурсии: если диск один, то переместить его с левого стержня на правый. Иначе, переместить N-1 диск с левого диска на средний промежуточный, переместить один диск с левого стержня на правый и затем переместить N-1 диск со среднего стержня на правый, используя левый стержень как промежуточный.

domains

loc = right; middle; left

predicates

hanoi(integer)

move(integer, loc, loc, loc)

inform(loc, loc)

clauses

hanoi(N) :– move(N, left, middle, right). % Запуск программы

move(1, A, _, C) :– inform(A, C), !. % Переместить один диск

move(N, A, B, C) :– % Переместить N дисков

N1=N-1, move(N1, A, C, B),

inform(A, C), move(N1, B, A, C).

inform(Loc1, Loc2) :– write("\nMove a disk from ", Loc1, " to ", Loc2).

Goal hanoi(10). % Перемещаем 10 дисков

3.7. Динамическая база данных

Пролог поддерживает реляционную базу данных. Предикаты базы данных нужно объявлять в отдельном разделе Database. Программная секцияDatabaseдолжна предшествовать объявлению предикатовPredicates. Объявление предикатов базы данных аналогично их описанию в секцииPredicates.

Динамическая база данных – раздел программы, в котором факты могут добавляться или загружаться из файла на диске во время выполнения программы или удаляться из нее. Факты, описывающие предикат базы данных, могут также обрабатываться как обыкновенные предикаты Пролога.

Для работы с базой данных используют стандартные предикаты asseta, assertz, retractall, consult, saveи др. (см. раздел "Стандартные предикаты"). Также нужно иметь представление о структуре памяти системы Пролога. Исходная программа на Прологе хранится в области SOURSE, в то время как для размещения фактов динамической базы данных отведена область HEAP. Поэтому на экране нельзя видеть информацию, записанную в базу данных. Однако ее можно просмотреть как текстовый файл, если сохранить его в каталоге под своим именем.

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

22. Пример работы с динамической базой данных.

Domains

list=integer*

Database–db1 % База данных с именемdb1

fact1(integer,string,list)

Database–db2 % База данных с именемdb2

fact2(integer,string)

Clauses

fact1(1,f1,[1,2,3]).

fact1(2,f2,[1,3]).

fact1(3,f3,[2,2,1]).

fact2(1,],"one").

fact2(1,"one one"]).

fact2(2,"two").

Тогда цель:

Goal fact1(X,Y,Z)

ответит:

X=1 Y=f1 Z=[1,2,3])

X=2 Y=f2 Z=[1,3]).

X=3 Y=f3 Z=[2,2,1]).

3 solutions

Goalrettactall(fact1(X,Y,[_,2|Z])) % удалить факты по образцу

X=1 Y=f1 Z=3

X=3 Y=f3 Z=1

Goal retractall(fact1(X,Y,Z))

X=2 Y=f2 z=[1,3]

Goalretractall(db2) % удалить поименованную базу данных

Yes .

23. Программа классификации. Здесь мы рассмотрим вопросно-ответную систему, которая является примером маленькой экспертной системы в том смысле, что программа варьирует процесс опроса в зависимости от обстоятельств; более того, она может задавать минимально необходимое число вопросов.

Основой базы данных такой программы является дерево решений некоторой предметной области. В нашем случае таким деревом будет система классификации животных. Все животные делятся на млекопитающих, птиц и рыб. Среди млекопитающих могут быть хищники и копытные. К хищникам, в частности, относятся тигр и гепард.

Приведем здесь пример версии программы с обратной цепочкой рассуждений, т.к. она ближе к встроенному в Пролог механизму вывода. Программу с прямой цепочкой рассуждений можно посмотреть в [1].

Структура версии с обратной цепочкой рассуждений проектируется введением группы правил высокого уровня. Каждое такое правило описывает одно животное, например:

animal_is("гепард") :– it_is("млекопитающее"),