📄 dilemma2.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 COOL classes and
;;; message-handlers to solve the problem.
;;;
;;; CLIPS Version 6.0 Example
;;;
;;; To execute, merely load and enter (solve-dilemma).
;;;======================================================
;;;**************
;;;* DEFCLASSES *
;;;**************
(defclass status
(is-a USER)
(role concrete)
(slot farmer
(create-accessor write)
(default shore-1))
(slot fox
(create-accessor write)
(default shore-1))
(slot goat
(create-accessor write)
(default shore-1))
(slot cabbage
(create-accessor write)
(default shore-1))
(slot parent
(create-accessor write)
(default no-parent))
(slot search-depth
(create-accessor write)
(default 1))
(slot last-move
(create-accessor write)
(default no-move)))
;;;****************
;;;* DEFFUNCTIONS *
;;;****************
(deffunction contradiction
(?f ?x ?g ?c ?d)
(if (or (and (eq ?x ?g) (neq ?f ?x)) (and (eq ?g ?c) (neq ?f ?g)))
then
TRUE
else
(any-instancep ((?s status))
(and (eq ?s:farmer ?f)
(eq ?s:fox ?x)
(eq ?s:goat ?g)
(eq ?s:cabbage ?c)
(< ?s:search-depth ?d)))))
(deffunction opposite-shore
(?value)
(if (eq ?value shore-1)
then
shore-2
else
shore-1))
(deffunction solve-dilemma ()
(do-for-all-instances ((?a status))
TRUE
(send ?a delete))
(make-instance start of status)
(send [start] generate-moves))
;;;**************
;;;* DEFRULES *
;;;**************
(defrule start-it
=>
(solve-dilemma))
;;;***********************
;;;* DEFMESSAGE-HANDLERS *
;;;***********************
(defmessage-handler status move-farmer
()
(if (not (contradiction (opposite-shore ?self:farmer) ?self:fox
?self:goat ?self:cabbage ?self:search-depth))
then
(bind ?x (make-instance (gensym) of status
(farmer (opposite-shore ?self:farmer))
(fox ?self:fox)
(goat ?self:goat)
(cabbage ?self:cabbage)
(last-move farmer)
(parent ?self)
(search-depth (+ ?self:search-depth 1))))
(if (not (send ?x solution?))
then
(send ?x generate-moves))))
(defmessage-handler status move-goat
()
(if (and (eq ?self:farmer ?self:goat) (not (contradiction
(opposite-shore ?self:farmer) ?self:fox (opposite-shore ?self:goat)
?self:cabbage ?self:search-depth)))
then
(bind ?x (make-instance (gensym) of status
(farmer (opposite-shore ?self:farmer))
(fox ?self:fox)
(goat (opposite-shore ?self:farmer))
(cabbage ?self:cabbage)
(last-move goat)
(parent ?self)
(search-depth (+ ?self:search-depth 1))))
(if (not (send ?x solution?))
then
(send ?x generate-moves))))
(defmessage-handler status move-fox
()
(if (and (eq ?self:farmer ?self:fox)
(not (contradiction (opposite-shore ?self:farmer)
(opposite-shore ?self:fox)
?self:goat ?self:cabbage ?self:search-depth)))
then
(bind ?x (make-instance (gensym) of status
(farmer (opposite-shore ?self:farmer))
(fox (opposite-shore ?self:farmer))
(goat ?self:goat)
(cabbage ?self:cabbage)
(last-move fox)
(parent ?self)
(search-depth (+ ?self:search-depth 1))))
(if (not (send ?x solution?))
then
(send ?x generate-moves))))
(defmessage-handler status move-cabbage
()
(if (and (eq ?self:farmer ?self:cabbage)
(not (contradiction (opposite-shore ?self:farmer)
?self:fox ?self:goat
(opposite-shore ?self:cabbage)
?self:search-depth)))
then
(bind ?x (make-instance (gensym) of status
(farmer (opposite-shore ?self:farmer))
(fox ?self:fox)
(goat ?self:goat)
(cabbage (opposite-shore ?self:farmer))
(last-move cabbage)
(parent ?self)
(search-depth (+ ?self:search-depth 1))))
(if (not (send ?x solution?))
then
(send ?x generate-moves))))
(defmessage-handler status generate-moves
()
(send ?self move-farmer)
(send ?self move-fox)
(send ?self move-goat)
(send ?self move-cabbage))
(defmessage-handler status print-solution
()
(if (neq ?self:parent no-parent)
then
(send ?self:parent print-solution)
(bind ?move-dest (dynamic-get ?self:last-move))
(if (eq ?self:last-move farmer)
then
(printout t "Farmer moves alone to " ?move-dest "." crlf)
else
(printout t "Farmer moves with " ?self:last-move " to " ?move-dest "." crlf))))
(defmessage-handler status solution?
()
(if (and (eq ?self:farmer shore-2) (eq ?self:fox shore-2)
(eq ?self:goat shore-2) (eq ?self:cabbage shore-2))
then
(printout t crlf "Solution found:" crlf crlf)
(send ?self print-solution)
TRUE
else
FALSE))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -