Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Prolog.doc
Скачиваний:
31
Добавлен:
12.03.2015
Размер:
929.28 Кб
Скачать

Если мы введем

?- asserta (запись (верх)), assertz (запись (низ)).

то база данных примет вид:

запись (верх).

Запись (первая).

запись (вторая).

запись (низ).

Если затем мы введем

?- retract (запись (X)).

то получим

Х=верх

другие решения (да/нет)? да

Х=первая

другие решения (да/нет)? нет

В базе данных останутся

запись (вторая).

запись (низ).

Теперь напишем процедуру кратчайший_путь(А,Р) для построения кратчайшего пути в лабиринте из позиции А к выходу и запомина­ния его в списке Р. На рис.7.1.2 показано, в каком порядке генериру­ются пути. Заметим, что встроенный предикат length(L,N) находит длину N списка L.

/* Генерируем альтернативные пути и запоминаем

/* кратчайший путь, найденный к настоящему

/* моменту.

/* Вызываем состояние неудачи, если нет больше

/* альтернативных путей без повторного

/* посещения позиций:

кратчайший_путь(А,_) :-

asserta (короткий ([],99999)),

путь(А, Новый_путь, [A]),

length (Новый_путь, Новая_длина),

короткий (_, Старая_длина),

сравнить (Новый_путь, Новая_длина, Старая_длина).

/* Вызываем кратчайший_путь

кратчайший_путь(А,Р) :-

retract(короткий(P,L)).

/* Сохраняем новый путь, если он короче, чем

/* старый

сравнить (Новый_путь, Новая_длина, Старая_длина) :-

Новая_длина Старая_длина,

retract (короткий (_,_)),

asserta (короткий (Новый_путь, Новая_длина)),

fail.

Рис 7.1.2. Порядок генерации путей

7.3. Обработка фактов с помощью механизма возврата

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

запись (джим, 1).

запись (джек, 4).

запись(билл,6).

запись(фил,З).

Мы можем получить доступ ко всем записям, активизируя меха­низм возврата с помощью вызова состояния неудачи. Так, запрос

?- запись(Х,Y), write (X),nl,fail.

определит значения:

джим

джек

билл

фил

нет

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

доб_едии :- assertz(запись(poyг,0)),

retract(запись(Х,Y)),

сохр_запись(Х,Y).

сохр_запись(роуг,_).

сохр_запись(X,Y) :-

Z is Y+1,

assertz(запись(Х,Z)),fail.

Рис.7.2.1 показывает, как выглядят факты вида запись на раз­личных этапах согласования доб_един.

запись(джим,1).

запись(джек,4).

запись(билл,6).

запись(фил,3).

запись(роуг,0). < Добавляется маркер.

запись(джек,4).

запись(билл,6). Выбирается первая запись,

запись(фил,3). добавляется единица ко второму

запись (роуг,0). аргументу, запись вносится в базу

данных и вызывается состояние

неудачи.

запись(джим,2). <

запись(билл,6). Включается механизм возв­рата

запись(фил,3). и выбирается вторая запись.

запись(роуг,0). Сохр_запись обрабатывает запись

и оказывается в состоянии неудачи.

запись(джим,2).

запись(джек,5). <

Процесс продолжается до тех пор, пока маркер не «поднимется к вершине» записей.

запись(джим,2). Включается механизм возврата

запись(джек,5). и выбирается запись-маркер.

запись(билл,7). На этот раз согласуются

запись(фил,4). сохр_запись и доб_един.

Рис.7.2.1. Согласование доб_един

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]