Фермерская дилемма в клипах - PullRequest
0 голосов
/ 03 ноября 2018

Я пытался решить фермерскую дилемму.

"Смысл в том, чтобы переправить фермера, лису, капусту и козла через ручей. Но лодка вмещает только 2 предмета. Если оставить ее наедине с козой, ее съест лиса. Если оставить ее наедине с капуста, козел ее съест "

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

 (deftemplate state
(slot farmer)
(slot fox)
(slot goat)
(slot cab))

Я определяю функцию для выполнения движения

    (deffunction move(?f ?x ?g ?c)
(if (and (neq ?f 1) (or (and (eq ?f ?g) 
(and(neq ?f ?x) (neq ?f ?c)))
(or (and (neq ?f ?c) (and(eq ?f ?x) (eq ?f ?g))) 
(and (eq ?f ?c) (and(eq ?f ?x) (eq ?f ?g))))))
   then 
(bind ?f (* -1 ?f))
(bind ?g (* -1 ?g))
(printout t "farmer become on side" ?f "fox on side " ?x 
"goat on side " ?g "cabbage on side " ?c crlf)
   else 
(if (or (and (neq ?f ?c) (and(eq ?c ?x) (eq ?f ?g))) 
(and (neq ?f ?g) (and(eq ?f ?x) (eq ?f ?c))))
   then 
(bind ?f (* -1 ?f))
(printout t "farmer become on side" ?f "fox on side " ?x 
"goat on side " ?g "cabbage on side " ?c crlf)
   else
(if (and (neq ?f ?g) (and(eq ?f ?x) (eq ?f ?c)))
   then
(bind ?f  (* -1 ?f))
(bind ?x (* -1 ?x))
(printout t "farmer become on side" ?f "fox on side " ?x 
"goat on side " ?g "cabbage on side " ?c crlf)
   else
(if (and (neq ?f ?x) (and(eq ?f ?c) (eq ?f ?g)))
   then
(bind ?f (* -1 ?f))
(bind ?c (* -1 ?c))
(printout t "farmer become on side" ?f "fox on side " ?x 
"goat on side " ?g "cabbage on side " ?c crlf)
))))))

Я также определяю правило

(defrule move-to-opp
(state (farmer ?f) (fox ?x) (goat ?g) (cab ?c))
(or (or (neq ?f 1) (neq ?g 1)) (or (neq ?x 1) (neq ?c 1)))
=>
(printout t "firstly farmer on side" ?f "fox on side " ?x 
    "goat on side " ?g "cabbage on side " ?c crlf)
(move ?f ?x ?g ?c))

Тогда я определил факты внутри шаблона, чтобы они были на первой стороне -1

(deffacts initial-state
(state (farmer -1) 
(fox -1) 
(goat -1) 
(cab -1)))

после выполнения правил вывод не появляется, но он делает первый шаг для меня, когда я удаляю условие цикла из правила

(or (or (neq ?f 1) (neq ?g 1)) (or (neq ?x 1) (neq ?c 1)))

1 Ответ

0 голосов
/ 03 ноября 2018

Есть реализация дилеммы фермера на https://sourceforge.net/p/clipsrules/code/HEAD/tree/branches/63x/examples/dilemma1.clp

;;;======================================================
;;;   Farmer's Dilemma Problem
;;;
;;;     Another classic AI problem (cannibals and the 
;;;     missionary) in agricultural terms. The point is
;;;     to get the farmer, the fox the cabbage and the
;;;     goat across a stream.
;;;        But the boat only holds 2 items. If left 
;;;     alone with the goat, the fox will eat it. If
;;;     left alone with the cabbage, the goat will eat
;;;     it.
;;;        This example uses rules and fact pattern 
;;;     matching to solve the problem.
;;;
;;;     CLIPS Version 6.0 Example
;;;
;;;     To execute, merely load, reset and run.
;;;======================================================

(defmodule MAIN 
  (export deftemplate status))

;;;*************
;;;* TEMPLATES *
;;;*************

;;; The status facts hold the state  
;;; information of the search tree.

(deftemplate MAIN::status 
   (slot search-depth (type INTEGER) (range 1 ?VARIABLE))
   (slot parent (type FACT-ADDRESS SYMBOL) (allowed-symbols no-parent))
   (slot farmer-location 
      (type SYMBOL) (allowed-symbols shore-1 shore-2))
   (slot fox-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 last-move
      (type SYMBOL) (allowed-symbols no-move alone fox goat cabbage)))

;;;*****************
;;;* INITIAL STATE *
;;;*****************

(deffacts MAIN::initial-positions
  (status (search-depth 1) 
          (parent no-parent)
          (farmer-location shore-1)
          (fox-location shore-1)
          (goat-location shore-1)
          (cabbage-location shore-1)
          (last-move no-move)))

(deffacts MAIN::opposites
  (opposite-of shore-1 shore-2)
  (opposite-of shore-2 shore-1))

;;;***********************
;;;* GENERATE PATH RULES *
;;;***********************

(defrule MAIN::move-alone 
  ?node <- (status (search-depth ?num) 
                   (farmer-location ?fs))
  (opposite-of ?fs ?ns)
  =>
  (duplicate ?node (search-depth =(+ 1 ?num))
                   (parent ?node)
                   (farmer-location ?ns)
                   (last-move alone)))

(defrule MAIN::move-with-fox
  ?node <- (status (search-depth ?num) 
                   (farmer-location ?fs)
                   (fox-location ?fs))
  (opposite-of ?fs ?ns)
  =>
  (duplicate ?node (search-depth =(+ 1 ?num)) 
                   (parent ?node)
                   (farmer-location ?ns)
                   (fox-location ?ns)
                   (last-move fox)))

(defrule MAIN::move-with-goat 
  ?node <- (status (search-depth ?num) 
                   (farmer-location ?fs)
                   (goat-location ?fs))
  (opposite-of ?fs ?ns)
  =>
  (duplicate ?node (search-depth =(+ 1 ?num)) 
                   (parent ?node)
                   (farmer-location ?ns)
                   (goat-location ?ns)
                   (last-move goat)))

(defrule MAIN::move-with-cabbage
  ?node <- (status (search-depth ?num)
                   (farmer-location ?fs)
                   (cabbage-location ?fs))
  (opposite-of ?fs ?ns)
  =>
  (duplicate ?node (search-depth =(+ 1 ?num)) 
                   (parent ?node)
                   (farmer-location ?ns)
                   (cabbage-location ?ns)
                   (last-move cabbage)))

;;;******************************
;;;* CONSTRAINT VIOLATION RULES *
;;;******************************

(defmodule CONSTRAINTS 
  (import MAIN deftemplate status))

(defrule CONSTRAINTS::fox-eats-goat 
  (declare (auto-focus TRUE))
  ?node <- (status (farmer-location ?s1)
                   (fox-location ?s2&~?s1)
                   (goat-location ?s2))
  =>
  (retract ?node))

(defrule CONSTRAINTS::goat-eats-cabbage 
  (declare (auto-focus TRUE))
  ?node <- (status (farmer-location ?s1)
                   (goat-location ?s2&~?s1)
                   (cabbage-location ?s2))
  =>
  (retract ?node))

(defrule CONSTRAINTS::circular-path 
  (declare (auto-focus TRUE))
  (status (search-depth ?sd1)
          (farmer-location ?fs)
          (fox-location ?xs)
          (goat-location ?gs)
          (cabbage-location ?cs))
  ?node <- (status (search-depth ?sd2&:(< ?sd1 ?sd2))
                   (farmer-location ?fs)
                   (fox-location ?xs)
                   (goat-location ?gs)
                   (cabbage-location ?cs))
  =>
  (retract ?node))

;;;*********************************
;;;* FIND AND PRINT SOLUTION RULES *
;;;*********************************

(defmodule SOLUTION 
  (import MAIN deftemplate status))

(deftemplate SOLUTION::moves 
   (slot id (type FACT-ADDRESS SYMBOL) (allowed-symbols no-parent)) 
   (multislot moves-list  
      (type SYMBOL) (allowed-symbols no-move alone fox goat cabbage)))

(defrule SOLUTION::recognize-solution 
  (declare (auto-focus TRUE))
  ?node <- (status (parent ?parent)
                   (farmer-location shore-2)
                   (fox-location shore-2)
                   (goat-location shore-2)
                   (cabbage-location shore-2)
                   (last-move ?move))
  =>
  (retract ?node)
  (assert (moves (id ?parent) (moves-list ?move))))

(defrule SOLUTION::further-solution 
  ?node <- (status (parent ?parent)
                   (last-move ?move))
  ?mv <- (moves (id ?node) (moves-list $?rest))
  =>
  (modify ?mv (id ?parent) (moves-list ?move ?rest)))

(defrule SOLUTION::print-solution 
  ?mv <- (moves (id no-parent) (moves-list no-move $?m))
  =>
  (retract ?mv)
  (printout t crlf "Solution found: " crlf crlf)
  (bind ?length (length$ ?m))
  (bind ?i 1)
  (bind ?shore shore-2)
  (while (<= ?i ?length)
     (bind ?thing (nth ?i ?m))
     (if (eq ?thing alone)
        then (printout t "Farmer moves alone to " ?shore "." crlf)
        else (printout t "Farmer moves with " ?thing " to " ?shore "." crlf))
     (if (eq ?shore shore-1)
        then (bind ?shore shore-2)
        else (bind ?shore shore-1))
     (bind ?i (+ 1 ?i))))
...