courses:knowledge_representation_and_artificial_intelligence_systems:lab4

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
courses:knowledge_representation_and_artificial_intelligence_systems:lab4 [2019/07/12 13:38]
andrey.suchkov [Порядок выполнения работы]
courses:knowledge_representation_and_artificial_intelligence_systems:lab4 [2022/12/10 09:08] (current)
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-location (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 ?ps)  ; фиксация текущего местонахождения ​крестьянина 
-                   ​(wolf-location ?fs))   ​; волк на том же берегу,​ что и фермер +                   ​(wolf-location ?ps))    ; волк на том же берегу,​ что и крестьянина 
-  (opposite-of ?fs ?ns)  ; связывание значения противоположного берега+  (opposite-of ?ps ?ns)  ; связывание значения противоположного берега
 => =>
   (duplicate ?node              ; создать новую вершину дублированием   (duplicate ?node              ; создать новую вершину дублированием
     (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))
   ...   ...
courses/knowledge_representation_and_artificial_intelligence_systems/lab4.1562938685.txt.gz · Last modified: 2022/12/10 09:08 (external edit)