This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
courses:knowledge_representation_and_artificial_intelligence_systems:lab4 [2019/07/12 13:38] andrey.suchkov [Порядок выполнения работы] |
courses:knowledge_representation_and_artificial_intelligence_systems:lab4 [2019/08/29 09:08] andrey.suchkov [Общие сведения] |
||
---|---|---|---|
Line 4: | Line 4: | ||
===== Основные теоретические положения ===== | ===== Основные теоретические положения ===== | ||
==== Введение ==== | ==== Введение ==== | ||
- | Одной из классических задач ИИ, рассматриваемых при построении и анализе алгоритмов поиска является известная головоломка о фермере, которому необходимо переправить на другой берег реки волка, козу и капусту. Он располагает двуместной лодкой, т.е. может перевозить только по одному объекту. При этом нельзя оставлять на берегу волка с козой и козу с капустой, т.к. в этом случае первый из них съест второго. | + | Одной из классических задач ИИ, рассматриваемых при построении и анализе алгоритмов поиска является известная головоломка о крестьянине, которому необходимо переправить на другой берег реки волка, козу и капусту. Он располагает двуместной лодкой, т.е. может перевозить только по одному объекту. При этом нельзя оставлять на берегу волка с козой и козу с капустой, т.к. в этом случае первый из них съест второго. |
==== Общие сведения ==== | ==== Общие сведения ==== | ||
Как известно, постановка задачи поиска в пространстве состояний в общем случае предполагает описание //исходного состояния//, //множества операторов// перехода в пространстве состояний и множества целевых состояний (процедуры определения целевого состояния). Рассмотрим эти компоненты для данной задачи. | Как известно, постановка задачи поиска в пространстве состояний в общем случае предполагает описание //исходного состояния//, //множества операторов// перехода в пространстве состояний и множества целевых состояний (процедуры определения целевого состояния). Рассмотрим эти компоненты для данной задачи. | ||
=== Представление состояний в пространстве состояний и вершин в дереве поиска === | === Представление состояний в пространстве состояний и вершин в дереве поиска === | ||
- | Каждое //состояние// в пространстве состояний //определяется нахождением каждого персонажа/объекта// (фермера (''farmer''), волка (''wolf''), козы (''goat'') и капусты (''cabbage'')) на одном из двух берегов (''shore-1'' или ''shore-2''). Таким образом, состояние можно представить неупорядоченным фактом, содержащим слоты для задания местоположения каждого персонажа (объекта): ''farmer-location'', ''wolf-location'', ''goat-location'' и ''cabbage-location''. Эти слоты могут принимать символьные значения ''shore-1'' и ''shore-2''. | + | Каждое //состояние// в пространстве состояний //определяется нахождением каждого персонажа/объекта// (крестьянина (''peasant''), волка (''wolf''), козы (''goat'') и капусты (''cabbage'')) на одном из двух берегов (''shore-1'' или ''shore-2''). Таким образом, состояние можно представить неупорядоченным фактом, содержащим слоты для задания местоположения каждого персонажа (объекта): ''peasant-location'', ''wolf-location'', ''goat-location'' и ''cabbage-location''. Эти слоты могут принимать символьные значения ''shore-1'' и ''shore-2''. |
- | Поскольку поиск выполняется по дереву поиска (ДП), при разработке программы необходимо представлять вершины ДП. Каждая вершина ДП, помимо описания некоторого состояния, должна содержать также дополнительную информацию: //ссылку на родительскую вершину//, //глубину вершины// и //последнее перемещение//. Последнее перемещение определяет с кем/чем переправлялся фермер последний раз и может принимать следующие символьные значения: ''no-move'', ''alone'', ''wolf'', ''goat'' и ''cabbage''. | + | Поскольку поиск выполняется по дереву поиска (ДП), при разработке программы необходимо представлять вершины ДП. Каждая вершина ДП, помимо описания некоторого состояния, должна содержать также дополнительную информацию: //ссылку на родительскую вершину//, //глубину вершины// и //последнее перемещение//. Последнее перемещение определяет с кем/чем переправлялся крестьянин последний раз и может принимать следующие символьные значения: ''no-move'', ''alone'', ''wolf'', ''goat'' и ''cabbage''. |
Таким образом, для представления вершин ДП можно использовать неупорядоченный факт, определяемый следующим шаблоном: | Таким образом, для представления вершин ДП можно использовать неупорядоченный факт, определяемый следующим шаблоном: | ||
<code> | <code> | ||
(deftemplate status | (deftemplate status | ||
- | (slot farmer-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) | + | (slot peasant-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) |
- | (slot wolf-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) | + | (slot wolf-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) |
- | (slot goat-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) | + | (slot goat-locatio (type SYMBOL) (allowed-symbols shore-1 shore-2)) |
- | (slot cabbage-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) | + | (slot cabbage-location (type SYMBOL) (allowed-symbols shore-1 shore-2)) |
- | (slot parent (type FACT-ADDRESS SYMBOL) (allowed-symbols no-parent)) | + | (slot parent (type FACT-ADDRESS SYMBOL) (allowed-symbols no-parent)) |
- | (slot search-depth (type INTEGER) (range 1 ?VARIABLE)) | + | (slot search-depth (type INTEGER) (range 1 ?VARIABLE)) |
- | (slot last-move (type SYMBOL) (allowed-symbols no-move alone wolf goat cabbage))) | + | (slot last-move (type SYMBOL) (allowed-symbols no-move alone wolf goat cabbage))) |
</code> | </code> | ||
Исходным является состояние, в котором все действующие лица (и лодка) находятся на первом берегу (''shore-1''). Соответствующая (корневая) вершина в ДП не имеет родительской вершины, имеет глубину 1 и не имеет последнего перемещения (''no-move''). Таким образом, исходное состояние может быть представлено следующим фактом: | Исходным является состояние, в котором все действующие лица (и лодка) находятся на первом берегу (''shore-1''). Соответствующая (корневая) вершина в ДП не имеет родительской вершины, имеет глубину 1 и не имеет последнего перемещения (''no-move''). Таким образом, исходное состояние может быть представлено следующим фактом: | ||
Line 27: | Line 27: | ||
(deffacts initial-positions | (deffacts initial-positions | ||
(status (search-depth 1) | (status (search-depth 1) | ||
- | (parent no-parent) | + | (parent no-parent) |
- | (farmer-location shore-1) | + | (peasant-location shore-1) |
- | (wolf-location shore-1) | + | (wolf-location shore-1) |
- | (goat-location shore-1) | + | (goat-location shore-1) |
- | (cabbage-location shore-1) | + | (cabbage-location shore-1) |
- | (last-move no-move))) | + | (last-move no-move))) |
</code> | </code> | ||
=== Операторы перехода в пространстве состояний === | === Операторы перехода в пространстве состояний === | ||
//Множество операторов// перехода для данной задачи включает: | //Множество операторов// перехода для данной задачи включает: | ||
- | * перемещение с одного берега на другой одного фермера (''move-alone''); | + | * перемещение с одного берега на другой одного крестьянина (''move-alone''); |
- | * перемещение фермера с волком (''move-with-wolf''); | + | * перемещение крестьянина с волком (''move-with-wolf''); |
- | * перемещение фермера с козой (''move-with-goat''); | + | * перемещение крестьянина с козой (''move-with-goat''); |
- | * перемещение фермера с капустой (''move-with-cabbage''). | + | * перемещение крестьянина с капустой (''move-with-cabbage''). |
При реализации программы в среде CLIPS операторы удобно представлять правилами. При этом //в левой части правил// должны распознаваться условия применимости данного оператора и фиксироваваться (связываться) параметры конкретного состояния: указатель (адрес) на текущую вершину, местонахождение действующих лиц, затрагиваемых данным оператором, и глубина поиска. | При реализации программы в среде CLIPS операторы удобно представлять правилами. При этом //в левой части правил// должны распознаваться условия применимости данного оператора и фиксироваваться (связываться) параметры конкретного состояния: указатель (адрес) на текущую вершину, местонахождение действующих лиц, затрагиваемых данным оператором, и глубина поиска. | ||
- | //В правой части// правила должна порождаться новая вершина, являющаяся потомком текущей в случае применения данного оператора и устанавливаться ее параметры: глубина, новое местонахождение действующих лиц, ссылка на родительскую вершину и последнее перемещение. Новую вершину удобно порождать путем дублирования текущей с изменением значений некоторых параметров. Пример правила для перемещения фермера с волком: | + | //В правой части// правила должна порождаться новая вершина, являющаяся потомком текущей в случае применения данного оператора и устанавливаться ее параметры: глубина, новое местонахождение действующих лиц, ссылка на родительскую вершину и последнее перемещение. Новую вершину удобно порождать путем дублирования текущей с изменением значений некоторых параметров. Пример правила для перемещения крестьянина с волком: |
<code> | <code> | ||
- | (defrule move-with-wolf "Правило 'перемещение с волком'" | + | (defrule move-with-wolf "Правило перемещения с волком" |
- | ?node <- (status (search-depth ?num) ; фиксация адреса текущей вершины и ее глубины | + | ?node <- (status (search-depth ?num) ; фиксация адреса текущей вершины и ее глубины |
- | (farmer-location ?fs) ; фиксация текущего местонахождения фермера | + | (peasant-location ?fs) ; фиксация текущего местонахождения крестьянина |
- | (wolf-location ?fs)) ; волк на том же берегу, что и фермер | + | (wolf-location ?fs)) ; волк на том же берегу, что и крестьянина |
(opposite-of ?fs ?ns) ; связывание значения противоположного берега | (opposite-of ?fs ?ns) ; связывание значения противоположного берега | ||
=> | => | ||
Line 53: | Line 53: | ||
(search-depth =(+ 1 ?num)) ; установить ее глубину инкрементом текущей | (search-depth =(+ 1 ?num)) ; установить ее глубину инкрементом текущей | ||
(parent ?node) ; установить в качестве родительской вершины текущую | (parent ?node) ; установить в качестве родительской вершины текущую | ||
- | (farmer-location ?ns) ; установить новое местонахождение фермера | + | (peasant-location ?ns) ; установить новое местонахождение крестьянина |
(wolf-location ?ns) ; установить новое местонахождение волка | (wolf-location ?ns) ; установить новое местонахождение волка | ||
(last-move wolf))) ; установить тип последнего перемещения | (last-move wolf))) ; установить тип последнего перемещения | ||
Line 64: | Line 64: | ||
</code> | </code> | ||
=== Ограничения на возможные состояния === | === Ограничения на возможные состояния === | ||
- | Процесс поиска может приводить в //запрещённые состояния//, в которых волк ест козу или коза ест капусту. При попадании в запрещенные состояния соответствующие вершины должны удаляться. Например, волк ест козу, если он находится с ней на одном берегу и на этом берегу нет фермера. Соответствующее правило можно записать так: | + | Процесс поиска может приводить в //запрещённые состояния//, в которых волк ест козу или коза ест капусту. При попадании в запрещенные состояния соответствующие вершины должны удаляться. Например, волк ест козу, если он находится с ней на одном берегу и на этом берегу нет крестьянина. Соответствующее правило можно записать так: |
<code> | <code> | ||
(defrule wolf-eats-goat | (defrule wolf-eats-goat | ||
- | ?node <- (status (farmer-location ?s1) ; фиксируется адрес вершины и положение фермера | + | ?node <- (status (peasant-location ?s1) ; фиксируется адрес вершины и положение крестьянин |
- | (wolf-location ?s2&~?s1) ; волк и фермер на разных берегах | + | (wolf-location ?s2&~?s1) ; волк и крестьянин на разных берегах |
(goat-location ?s2)) ; коза на том же берегу, что и волк | (goat-location ?s2)) ; коза на том же берегу, что и волк | ||
=> | => | ||
Line 79: | Line 79: | ||
(defrule circular-path | (defrule circular-path | ||
(status (search-depth ?sd1) | (status (search-depth ?sd1) | ||
- | (farmer-location ?fs) | + | (peasant-location ?ps) |
(wolf-location ?ws) | (wolf-location ?ws) | ||
(goat-location ?gs) | (goat-location ?gs) | ||
(cabbage-location ?cs)) | (cabbage-location ?cs)) | ||
?node <- (status (search-depth ?sd2&:(< ?sd1 ?sd2)) | ?node <- (status (search-depth ?sd2&:(< ?sd1 ?sd2)) | ||
- | (farmer-location ?fs) | + | (peasant-location ?ps) |
(wolf-location ?ws) | (wolf-location ?ws) | ||
(goat-location ?gs) | (goat-location ?gs) | ||
Line 91: | Line 91: | ||
(retract ?node)) | (retract ?node)) | ||
</code> | </code> | ||
- | //Первая часть антецедента// этого правила сопоставляется с некоторой вершиной и фиксирует (в переменной ''?sd1'') ее глубину, а также местоположение всех персонажей -- фермера, волка, козы и капусты -- соответственно в переменных ''?fs'', ''?ws'', ''?gs'' и ''?cs''. //Вторая часть антецедента// сопоставляется с вершиной, имеющей большую глубину и точно такое же состояние (местоположение персонажей). Адрес этой вершины фиксируется в переменной ''?node'', чтобы в консеквенте правила можно было удалить данную вершину. | + | //Первая часть антецедента// этого правила сопоставляется с некоторой вершиной и фиксирует (в переменной ''?sd1'') ее глубину, а также местоположение всех персонажей -- крестьянина, волка, козы и капусты -- соответственно в переменных ''?ps'', ''?ws'', ''?gs'' и ''?cs''. //Вторая часть антецедента// сопоставляется с вершиной, имеющей большую глубину и точно такое же состояние (местоположение персонажей). Адрес этой вершины фиксируется в переменной ''?node'', чтобы в консеквенте правила можно было удалить данную вершину. |
=== Распознавание и вывод решения === | === Распознавание и вывод решения === | ||
//Решением// задачи является последовательность перемещений на лодке с берега на берег, переводящая исходное состояние в целевое. В данной задаче целевым является состояние, когда все находятся на втором берегу. При достижении целевого состояния должно быть выведено решение -- последовательность перемещений. Однако каждая вершина в ДП (в том числе целевая) явно хранит лишь //последнее перемещение// и указатель на вершину-предка. Поэтому при обнаружении целевого состояния необходимо выполнить обратный проход от целевой вершины к корню ДП (исходному состоянию), чтобы восстановить полную последовательность перемещений. Таким образом, необходимо иметь //правило для распознавания целевого состояния// и //правило для построения решения// -- последовательности операторов (перемещений) переводящих исходное состояние в целевое. | //Решением// задачи является последовательность перемещений на лодке с берега на берег, переводящая исходное состояние в целевое. В данной задаче целевым является состояние, когда все находятся на втором берегу. При достижении целевого состояния должно быть выведено решение -- последовательность перемещений. Однако каждая вершина в ДП (в том числе целевая) явно хранит лишь //последнее перемещение// и указатель на вершину-предка. Поэтому при обнаружении целевого состояния необходимо выполнить обратный проход от целевой вершины к корню ДП (исходному состоянию), чтобы восстановить полную последовательность перемещений. Таким образом, необходимо иметь //правило для распознавания целевого состояния// и //правило для построения решения// -- последовательности операторов (перемещений) переводящих исходное состояние в целевое. | ||
Line 108: | Line 108: | ||
(defrule goal-test | (defrule goal-test | ||
?node <- (status (parent ?parent) | ?node <- (status (parent ?parent) | ||
- | (farmer-location shore-2) | + | (peasant-location shore-2) |
(wolf-location shore-2) | (wolf-location shore-2) | ||
(goat-location shore-2) | (goat-location shore-2) | ||
Line 138: | Line 138: | ||
=> | => | ||
(retract ?mv) ; факт ?mv удаляется | (retract ?mv) ; факт ?mv удаляется | ||
- | (printout t t "Solution found: " t t) ; Печать сообщения «Решение найдено:» | + | (printout t t "Solution found: " t t) ; Печать сообщения "Решение найдено:" |
(bind ?length (length ?m)) ; ?length = длина списка перемещений ( переменной ?m) | (bind ?length (length ?m)) ; ?length = длина списка перемещений ( переменной ?m) | ||
(bind ?i 1) ; ?i = 1 | (bind ?i 1) ; ?i = 1 | ||
Line 145: | Line 145: | ||
(bind ?thing (nth ?i ?m)) ; ?thing = значение i-го слота мультислота ?m (тип перемещения) | (bind ?thing (nth ?i ?m)) ; ?thing = значение i-го слота мультислота ?m (тип перемещения) | ||
(if (eq ?thing alone) ; Если ?thing = alone | (if (eq ?thing alone) ; Если ?thing = alone | ||
- | then (printout t "Farmer moves alone to " ?shore "." t) | + | then (printout t "Peasant moves alone to " ?shore "." t) |
- | else (printout t "Farmer moves with " ?thing " to " ?shore "." t)) | + | else (printout t "Peasant moves with " ?thing " to " ?shore "." t)) |
(if (eq ?shore shore-1) ; Если ?shore = shore-1 | (if (eq ?shore shore-1) ; Если ?shore = shore-1 | ||
- | then (bind ?shore shore-2) ;?shore = shore-2 | + | then (bind ?shore shore-2) ; ?shore = shore-2 |
- | else (bind ?shore shore-1)) ;?shore = shore-1 | + | else (bind ?shore shore-1)) ; ?shore = shore-1 |
(bind ?i (+ 1 ?i)))) ; ?i = ?i + 1 | (bind ?i (+ 1 ?i)))) ; ?i = ?i + 1 | ||
</code> | </code> | ||
===== Постановка задачи ===== | ===== Постановка задачи ===== | ||
- | Необходимо построить полное дерево поиска для задачи о фермере, которому необходимо переправить на другой берег реки волка, козу и капусту, разработать на продукционном языке CLIPS модульную программу решения данной задачи и проанализировать ход поиска решения, выполнив программу в пошаговом режиме. | + | Необходимо построить полное дерево поиска для задачи о крестьянине, которому необходимо переправить на другой берег реки волка, козу и капусту, разработать на продукционном языке CLIPS модульную программу решения данной задачи и проанализировать ход поиска решения, выполнив программу в пошаговом режиме. |
===== Порядок выполнения работы ===== | ===== Порядок выполнения работы ===== | ||
- Построить полное дерево поиска для данной задачи. | - Построить полное дерево поиска для данной задачи. | ||
Line 199: | Line 199: | ||
) | ) | ||
</code> У правила распознавания целевого состояния должно быть установлено свойство автофокусировки: <code> | </code> У правила распознавания целевого состояния должно быть установлено свойство автофокусировки: <code> | ||
- | (defrule SOLUTION:: goal-test | + | (defrule SOLUTION::goal-test |
(declare (auto-focus TRUE)) | (declare (auto-focus TRUE)) | ||
... | ... |