home *** CD-ROM | disk | FTP | other *** search
-
- ;;;======================================================
- ;;; 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.
- ;;;
- ;;; To execute, merely load, reset and run.
- ;;;======================================================
-
- ;;;****************************
- ;;;* Farmer's Dilemma Problem *
- ;;;****************************
-
- ;;; The status facts hold the state information of the search tree.
- ;;; (status <search-depth>
- ;;; <id>
- ;;; <parent>
- ;;; <farmer-location>
- ;;; <fox-location>
- ;;; <goat-location>
- ;;; <cabbage-location>)
-
- ;;; The moves facts hold the information of all the moves made to
- ;;; reach a given state.
- ;;; (status <id>
- ;;; <move-1>
- ;;; .
- ;;; .
- ;;; .
- ;;; <move-n>)
-
- ;;;*****************
- ;;;* Initial State *
- ;;;*****************
-
- (deffacts initial-positions
- (status 1 initial-setup no-parent shore-1 shore-1 shore-1 shore-1 no-move))
-
- (deffacts opposites
- (opposite-of shore-1 shore-2)
- (opposite-of shore-2 shore-1))
-
- ;;;************************
- ;;;* Generate Paths Rules *
- ;;;************************
-
- (defrule move-alone ""
- (status ?num ?name ? ?fs ?xs ?gs ?cs ?)
- (opposite-of ?fs ?ns)
- =>
- (bind ?nn (gensym))
- (assert (status =(+ 1 ?num) ?nn ?name ?ns ?xs ?gs ?cs alone)))
-
- (defrule move-with-fox ""
- (status ?num ?name ? ?fs ?fs ?gs ?cs ?)
- (opposite-of ?fs ?ns)
- =>
- (bind ?nn (gensym))
- (assert (status =(+ 1 ?num) ?nn ?name ?ns ?ns ?gs ?cs fox)))
-
- (defrule move-with-goat ""
- (status ?num ?name ? ?fs ?xs ?fs ?cs ?)
- (opposite-of ?fs ?ns)
- =>
- (bind ?nn (gensym))
- (assert (status =(+ 1 ?num) ?nn ?name ?ns ?xs ?ns ?cs goat)))
-
- (defrule move-with-cabbage ""
- (status ?num ?name ? ?fs ?xs ?gs ?fs ?)
- (opposite-of ?fs ?ns)
- =>
- (bind ?nn (gensym))
- (assert (status =(+ 1 ?num) ?nn ?name ?ns ?xs ?gs ?ns cabbage)))
-
- ;;;******************************
- ;;;* Constraint Violation Rules *
- ;;;******************************
-
- (defrule fox-eats-goat ""
- (declare (salience 10000))
- ?rm <- (status ? ?name ? ?s1 ?s2&~?s1 ?s2 ? ?)
- =>
- (retract ?rm))
-
- (defrule goat-eats-cabbage ""
- (declare (salience 10000))
- ?rm <- (status ? ?name ? ?s1 ? ?s2&~?s1 ?s2 ?)
- =>
- (retract ?rm))
-
- (defrule circular-path ""
- (declare (salience 10000))
- (status ?nm ? ? ?fs ?xs ?gs ?cs ?)
- ?rm <- (status ?nm1&:(< ?nm ?nm1) ?name ? ?fs ?xs ?gs ?cs ?)
- =>
- (retract ?rm))
-
- ;;;********************************
- ;;;* Find and Print Solution Rule *
- ;;;********************************
-
- (defrule recognize-solution ""
- (declare (salience 5000))
- ?rm <- (status ?num ?name ?parent shore-2 shore-2 shore-2 shore-2 ?move)
- =>
- (retract ?rm)
- (assert (moves ?parent ?move)))
-
- (defrule further-solution ""
- (declare (salience 5000))
- ?mv <- (moves ?name $?rest)
- (status ? ?name ?parent ? ? ? ? ?move)
- =>
- (retract ?mv)
- (assert (moves ?parent ?move $?rest)))
-
- (defrule print-solution ""
- (declare (salience 5000))
- ?mv <- (moves no-parent no-move $?m)
- =>
- (retract ?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))))
-