📄 objfarm.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 to solve the problem.;;;;;; CLIPS Version 6.0 Example using;;; Object Pattern-Matching;;;;;; To execute, merely load, reset and run.;;;======================================================;;;***********;;;* CLASSES *;;;***********;;; The status instances hold the state ;;; information of the search tree.(defclass status (is-a USER) (role concrete) (pattern-match reactive) (slot search-depth (create-accessor write) (type INTEGER) (range 1 ?VARIABLE) (default 1)) (slot parent (create-accessor write) (type INSTANCE-ADDRESS) (default ?DERIVE)) (slot farmer-location (create-accessor write) (type SYMBOL) (allowed-symbols shore-1 shore-2) (default shore-1)) (slot fox-location (create-accessor write) (type SYMBOL) (allowed-symbols shore-1 shore-2) (default shore-1)) (slot goat-location (create-accessor write) (type SYMBOL) (allowed-symbols shore-1 shore-2) (default shore-1)) (slot cabbage-location (create-accessor write) (type SYMBOL) (allowed-symbols shore-1 shore-2) (default shore-1)) (slot last-move (create-accessor write) (type SYMBOL) (allowed-symbols no-move alone fox goat cabbage) (default no-move))) ;;; The moves instances hold the information of all the moves;;; made to reach a given state. (defclass moves (is-a USER) (role concrete) (pattern-match reactive) (slot id (create-accessor write) (type INSTANCE)) (multislot moves-list (create-accessor write) (type SYMBOL) (allowed-symbols no-move alone fox goat cabbage)))(defclass opposite-of (is-a USER) (role concrete) (pattern-match reactive) (slot value (create-accessor write)) (slot opposite-value (create-accessor write)));;;*****************;;;* INITIAL STATE *;;;*****************(definstances startups (of status) (of opposite-of (value shore-1) (opposite-value shore-2)) (of opposite-of (value shore-2) (opposite-value shore-1)));;;***********************;;;* GENERATE PATH RULES *;;;***********************(defrule move-alone ?node <- (object (is-a status) (search-depth ?num) (farmer-location ?fs)) (object (is-a opposite-of) (value ?fs) (opposite-value ?ns)) => (duplicate-instance ?node (search-depth (+ 1 ?num)) (parent ?node) (farmer-location ?ns) (last-move alone)))(defrule move-with-fox ?node <- (object (is-a status) (search-depth ?num) (farmer-location ?fs) (fox-location ?fs)) (object (is-a opposite-of) (value ?fs) (opposite-value ?ns)) => (duplicate-instance ?node (search-depth (+ 1 ?num)) (parent ?node) (farmer-location ?ns) (last-move fox) (fox-location ?ns)))(defrule move-with-goat ?node <- (object (is-a status) (search-depth ?num) (farmer-location ?fs) (goat-location ?fs)) (object (is-a opposite-of) (value ?fs) (opposite-value ?ns)) => (duplicate-instance ?node (search-depth (+ 1 ?num)) (parent ?node) (farmer-location ?ns) (last-move goat) (goat-location ?ns)))(defrule move-with-cabbage ?node <- (object (is-a status) (search-depth ?num) (farmer-location ?fs) (cabbage-location ?fs)) (object (is-a opposite-of) (value ?fs) (opposite-value ?ns)) => (duplicate-instance ?node (search-depth (+ 1 ?num)) (parent ?node) (farmer-location ?ns) (last-move cabbage) (cabbage-location ?ns)));;;******************************;;;* CONSTRAINT VIOLATION RULES *;;;******************************(defrule fox-eats-goat (declare (salience 200)) ?node <- (object (is-a status) (farmer-location ?s1) (fox-location ?s2&~?s1) (goat-location ?s2)) => (unmake-instance ?node))(defrule goat-eats-cabbage (declare (salience 200)) ?node <- (object (is-a status) (farmer-location ?s1) (goat-location ?s2&~?s1) (cabbage-location ?s2)) => (unmake-instance ?node))(defrule circular-path (declare (salience 200)) (object (is-a status) (search-depth ?sd1) (farmer-location ?fs) (fox-location ?xs) (goat-location ?gs) (cabbage-location ?cs)) ?node <- (object (is-a status) (search-depth ?sd2&:(< ?sd1 ?sd2)) (farmer-location ?fs) (fox-location ?xs) (goat-location ?gs) (cabbage-location ?cs)) => (unmake-instance ?node));;;*********************************;;;* FIND AND PRINT SOLUTION RULES *;;;*********************************(defrule recognize-solution (declare (salience 100)) ?node <- (object (is-a status) (parent ?parent) (farmer-location shore-2) (fox-location shore-2) (goat-location shore-2) (cabbage-location shore-2) (last-move ?move)) => (unmake-instance ?node) (make-instance of moves (id ?parent) (moves-list ?move)))(defrule further-solution (declare (salience 100)) ?state <- (object (is-a status) (parent ?parent) (last-move ?move)) ?mv <- (object (is-a moves) (id ?state) (moves-list $?rest)) => (modify-instance ?mv (id ?parent) (moves-list ?move ?rest)))(defrule print-solution (declare (salience 100)) ?mv <- (object (is-a moves) ;(id [no-parent]) (moves-list no-move $?m)) => (unmake-instance ?mv) (printout t t "Solution found: " t t) (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 "." t) else (printout t "Farmer moves with " ?thing " to " ?shore "." t)) (if (eq ?shore shore-1) then (bind ?shore shore-2) else (bind ?shore shore-1)) (bind ?i (+ 1 ?i))))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -