Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические указания по ИИС.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
3.88 Mб
Скачать

Контрольное задание:

Напишите программу на языке Пролог с использованием переменных согласно варианту, выданному преподавателем:

Вариант 1. likes(Jerry, fugitive), likes(Jerry, swimming).

Вариант 2. grandmother(grandmother,_).

Вариант 3. rest(Person, brasilia), rest(Person, italia).

Вариант 4. study(Merry, carvard_university), study(Merry, university_palmal).

Вариант 5. grandfather(grandfather,_).

Вариант 6. work(Mark, magazine), work(Mark, firm).

Вариант 7. likes(Bill, fugitive), likes(Bill, auctioneer).

Вариант 8. father(father,_).

Вариант 9. likes(Andy, paint), likes(Andy, runner).

Вариант 10. brother(brother,_).

Вариант 11. likes(Person, boxing), likes(Person, dance).

Контрольные вопросы:

  1. Какие символы может содержать имя переменной?

  2. Как переменные получают свои значения?

  3. Перечислите и охарактеризуйте виды переменных

  4. Для чего используются анонимные переменные?

  5. Как обозначаются анонимные переменные?

  6. Где могут использоваться анонимные переменные?

Лабораторная работа №9.

СООТВЕТСТВИЕ: УНИФИКАЦИЯ НА ЯЗЫКЕ ПРОЛОГ.

Цель работы: изучение процесса унификации, формирование навыков написания программ с использованием унификации на языке Пролог.

Используемое программное обеспечение: Visual Prolog 5.2.

Теоретические сведения

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

Рассмотрим универсальный алго­ритм унификации (рис. 1).

Рис. 1. Алгоритм унификации на языке Пролог

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

(aXX),(aYb).

Их первые элементы сопоставимы. Оба вторых элемента представ­ляют собой переменные со связкой (X Y). Из сопоставления тре­тьих элементов вытекает, что X - область определения для b, что выражается связкой:

((XY)(Xb)).

В контексте данного окружения Y должно бы быть областью определения для b, поскольку Х служит для Y, но это не так. Кроме того, Х является областью определения более чем для одной переменной. А чтобы получить окружение вида ((Х Y) (Y b)) вместо переменной в сопоставлении должна участвовать её напарница по связке. Тогда переменная Х окажется связанной с Y, и при сравнении третьих элементов сопоставляться с b будет напарница Х по связке, в результате чего получится (Y b).

Первый предприни­маемый шаг - замещение X и Y их связками. Затем, если X ока­зывается переменной, она сцепляется с Y и такая пара добавляется к окружению О, которое и возвращается в виде результата. Если же переменной будет Y, то X и Y меняются местами, поскольку первым элементом пары в связке должна быть переменная. Далее пара помещается в О. Несмотря на то что в реализации списков не используется механизм ячеек связи, при следующем обращении к лиспоподобному слову СПИСОК(X Y) создается ячейка связи (или точечная пара) с головой X и хвостом Y.

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

В том случае, когда Х и Y не являются переменными, осуществляется их проверка на атомы. Если один из них ока­зывается атомом, то другой должен быть сопоставимым атомом. Иначе не получится новой связки, поскольку нет переменной b, если же выясняется, что X и Y - не атомы и не переменные, зна­чит, они должны быть списками, используемыми для представле­ния предикатов. В такой ситуации унификация вызывается ре­курсивно по первым двум элементам списков X и Y.

Быстрота выполнения алгоритмов унификации достигается ценой следующих огра­ничений:

    1. Переменная должна входить в некоторую функцию не более одного раза.

    2. Переменная не должна входить в функцию, по отношению к которой сама является границей.

Как правило, эти ограничения не столь существенны, но позволяют достигать большой скорости вычислений.

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

  1. Рассмотрим программу, используя внешние цели:

written_by(X, Y).

Когда Visual Prolog пытается выполнить цель written_by(X, Y), он проверяет все written_by предложения в программе для соответствия. Для поиска соответствия параметров X и Y с параметрами, найденными в каждом written_by предложении, Visual Prolog перебирает все предложения с начала до конца. Когда находится предложение, соответствующие цели, Пролог связывает значения со свободными переменными так, чтобы цель и предложение были идентичны; говорят, что цель унифицирована с предложением. Эту операцию нахождения соответствий называют унификацией.

DOMAINS

title, author = symbol

pages = unsigned

PREDICATES

book(title, pages)

nondeterm written_by(author, title)

nondeterm long_novel(title)

CLAUSES

written_by(flemming, “DR NO”).

written_by(melville, “MOBY DICK”).

book(“MOBY DICK”, 250).

book(“DR NO”, 310).

long_novel(Title):- written_by(_, Title), book(Title, Length), Length > 300.

Так как X и Y - свободные переменные в цели, а свободные переменные могут быть унифицированы с любыми другими параметрами (даже другими свободными переменными), запрос (цель) может быть объединена с первым written_by предложением в программе:

written_by(X , Y ).

| |

written_by(flemming, "DR NO").

  1. Пропишите следующую цель:

written_by(X , Y), written_by(flemming, "DR NO").

Visual Prolog связывает X с flemming, а Y с "DR NO". В этом случае, Visual Prolog выдаст X=flemming, Y=DR NO.

Так как при использовании внешней цели Visual Prolog ищет все решения, то данная цель также унифицируется и со вторым предложением written_by: written_by(melville, "MOBY DICK") и Visual Prolog выдаст второе решение (рис. 2):

X=melville, Y=MOBY DICK

2 Solutions.

Р ис. 2. Вывод программы

  1. Задайте следующую цель:

written_by(X, "MOBY DICK").

Visual Prolog попробует сначала сопоставить цель с первым предложением written_by:

written_by(X, "MOBY DICK").

| |

written_by(flemming, "DR NO").

Так как "MOBY DICK" и "DR NO" не соответствуют, это предложение отпадает. Тогда Visual Prolog начинает рассматривать следующий факт:

written_by(melville, "MOBY DICK").

В данном случае происходит унификация, и X принимает значение melville (рис. 3).

Р ис. 3. Вывод результата

  1. Рассмотрим, как Visual Prolog выполнит следующую цель:

long_novel(X).

Пропишите эту цель в программе. Пролог выдаст ответ (смотрите рис. 4).

Когда Visual Prolog будет пытаться выполнить цель, он исследует, действительно ли запрос может соответствовать факту или голове правила. В этом случае, соответствие будет с

long_novel(Title).

Visual Prolog просматривает предложения для long_novel, пробуя найти соответствие, унифицируя аргументы. Так как X не связана с целью, свободная переменная X может быть унифицирована с любым другим аргументом. Title также не является связанным с long_novel. Цель соответствует голове правила и происходит унификация. Далее Visual Prolog будет пытаться удовлетворять подцели к правилу:

long_novel(Title):-

written_by(_, Title),

book(Title, Length),

Length > 300.

Удовлетворяя тело правила, Visual Prolog вызывает первую подцель в теле правила, written_by(_,Title). Запрос written_by(_,Title) становится текущей подцелью и Пролога ищет решение этого запроса.

Для решения этой подцели Пролог перебирает все факты. В данном случае достигается унификация с первым фактом:

written_by(_, Title),

| |

written_by(flemming,"DR NO").

Переменная Title привязывается к значению "DR NO" и следующая подцель, book(Title, Length), вызывается с этим значением переменной.

Теперь Visual Prolog начинает следующий поиск, пробуя выполнить запрос book. Так как Title имеет значение "DR NO", фактически запрос представляет собой book("DRNO", Length). Обратите внимание, что первая попытка сопоставления с book("MOBY DICK", 250) будет неудачна, и Visual Prolog перейдет ко второму предложению book в поисках соответствия. В данном случае удовлетворяется подцель и VisualProlog связывает переменную Length со значением 310.

Теперь текущей подцелью становиться третье предложение в теле long_novel:

Length > 300.

После сравнения Visual Prolog возвращает положительный результат; 310 больше чем 300. В этом случае, все подцели в теле правила выполняются, и поэтому запрос long_novel(X) выполняется. Так как X в запросе был унифицирован с переменной Title в правиле, значение, с которым Title был связан, передается запросу и унифицируется с переменной X. Title имеет значение "DR NO", поэтому Visual Prolog выдаст следующий результат (рис. 4):

X=D RNO

1 Solution.

Р ис. 4. Ответ на запрос

Контрольное задание:

Разработайте алгоритм сохранения недоказанных целей в списке НЕУДАЧИ. Если искомая цель будет обнаружена в списке НЕУДАЧИ, то должен быть прекращен поиск и активирован возврат.

Контрольные вопросы:

  1. Что такое унификация?

  2. Что исследует Пролог при выполнении цели?

  3. Какими процедурами осуществляется унификация?

  4. Опишите алгоритм унификации.

Лабораторная работа №10.

ПОИСК С ВОЗВРАТОМ (ОТКАТ).

Цель работы: формирование навыков осуществления поиска решений при помощи отката.

Используемое программное обеспечение: Visual Prolog 5.2.

Теоретические сведения

Часто, при решении реальных проблем, Вы должны довести задачу до ее логического заключения. Если это заключение не дает Вам ответ, который Вы искали, Вам следует использовать альтернативное решение. Наверняка, когда Вы были ребенком, играли в лабиринт. Точный способ нахождения выхода из лабиринта состоит в том, чтобы поворачивать налево на каждой развилке в лабиринте, пока не попадете в тупик. Как только попали в тупик, нужно вернуться к последней развилке и повернуть на право, а потом опять поворачивать налево на каждой развилке. Систематически перебирая все пути, Вы, в конечном счете, найдете правильный маршрут и выйдите из лабиринта.

Лабораторная работа № 1 использует этот же метод «восстановления и повторной попытки», называемый откатом, для решения задачи. Как только Лабораторная работа № 1 начнет искать решение задачи (или цель), ему, возможно, придется выбирать между двумя возможными случаями. Он устанавливает маркер в месте разветвления (точка отката) и выбирает первую подцель. Если эта подцель терпит неудачу (эквивалент достижению тупика), Лабораторная работа № 1 возвращается в точку отката и пробует альтернативную подцель.

Правила отката:

  1. Когда Пролог пытается удовлетворить цель, он осуществляет поиск соответствия в программе сверху вниз.

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

Стараясь удовлетворить первую подцель, Лабораторная работа № 1, начиная с верха, пытается сопоставлять ее с каждым фактом или головой правила, с которым сталкивается.

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

  2. Если переменная была связана в предложении, единственный способ освободить ее заключается в откате.

Когда Пролог возвращается в точку отката, он освобождает весь набор переменных, связанных после этой точки, и пытается найти другое решение первоначального запроса.

При помощи отката Лабораторная работа № 1 может находить не только первое решение задачи, но и все возможные решения.