;-----------------------------------------------------------------------------------------
; This is the first attempt at Breadth First Search For the Water-Jug Problem
; This is done basically by keeping a fact:
; (depth ?)
; Which keeps track of the current depth.
;
; Facts of the current depth are expanded to create facts of the next level.
;
; All facts of the current level are expanded before those of the next level are expanded
; This is done using the routine update-depth, which (because of its lower salience)
; is called after all the facts are evaluated from the agenda. The update-depth
; routine creates a fact with an incremented depth level. This then activates the facts of the
; next depth.
;
;
;-----------------------------------------------------------------------------------------
; The status of the water in the water-jug
;
(deftemplate status
(slot water-jug
(type INTEGER)
(default 0))
(slot depth
(type INTEGER)
(default 0))
)
;-----------------------------------------------------------------------------------------
; The initial Status
;;
(defrule Initial-State
?initial <- (initial-fact)
=>
(printout t "The Initial State is an Empty Jug" crlf)
(assert (depth 0))
(assert (status (water-jug 0) (depth 0)))
)
;-----------------------------------------------------------------------------------------
; Rule for Adding One Gallon to Water Jug
;
(defrule Add-One-Gallon
(declare (salience 500))
?status <- (status
(water-jug ?amount)
(depth ?depth))
(depth ?current)
(test (= ?depth ?current))
=>
(printout t "Adding 1 Gallon to " ?amount " to make " (+ 1 ?amount) " gallons" crlf)
(assert (status (water-jug (+ ?amount 1))
(depth (+ ?depth 1))))
)
;-----------------------------------------------------------------------------------------
; Rule for Adding Two Gallons to Water Jug
;
(defrule Add-Two-Gallons
(declare (salience 500))
?status <- (status
(water-jug ?amount)
(depth ?depth))
(depth ?current)
(test (= ?depth ?current))
=>
(printout t "Adding 2 Gallons to " ?amount " to make " (+ 2 ?amount) " gallons" crlf)
(assert (status (water-jug (+ ?amount 2))
(depth (+ ?depth 1))))
)
;-----------------------------------------------------------------------------------------
; Rule to update current depth
; Called only if depth is done for all rules for this level
; (hence the lower salience)
;
(defrule update-depth
(declare (salience 100))
?depth <- (depth ?current)
=>
(retract ?depth)
(assert (depth (+ 1 ?current)))
)
;-----------------------------------------------------------------------------------------
; Rule for Detecting Done with Task (i.e. the jug has 3 gallons in it)
; Put Salience High so when matched, it is the first rule
;
(defrule Done
(declare (salience 1000))
?status <- (status
(water-jug 3))
=>
(printout t "Done - Jug has Three Gallons" crlf)
(retract ?status))