;----------------------------------------------------------------------------------------- ; This is the second attempt at Breadth First Search For the Water-Jug Problem ; ; (depth ?) -- Keeps Track of the Level ; (nodes ?) -- The number of Nodes ; In the status template fields were added ; node - The node number ; parent - The address of the parent (to be able to see the path) ; operation - An ASCII string for the operation ; ; As Before ; 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) (range 0 5)) (slot depth (type INTEGER) (default 0)) (slot node (type INTEGER) (default 0)) (slot parent (type FACT-ADDRESS SYMBOL) (default no-parent) (allowed-symbols no-parent)) (slot operation (type STRING)) ) ;----------------------------------------------------------------------------------------- ; The initial Status ;; (defrule Initial-State ?initial <- (initial-fact) => (printout t "The Initial State is an Empty Jug" crlf) (assert (depth 0 0)) (assert (status (water-jug 0) (depth 0) (parent no-parent))) (assert (nodes 1)) ) ;----------------------------------------------------------------------------------------- ; 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)) (test (< ?amount 3)) => (assert (status (water-jug (+ ?amount 1)) (depth (+ ?depth 1)) (parent ?status) (operation "Add One Gallon") )) ) ;----------------------------------------------------------------------------------------- ; 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)) (test (< ?amount 3)) => (assert (status (water-jug (+ ?amount 2)) (depth (+ ?depth 1)) (parent ?status) (operation "Add Two Gallons") )) ) ;----------------------------------------------------------------------------------------- (defrule Increment-Node-Count (declare (salience 600)) ?status <- (status (node ?statusnode)) ?nodes <- (nodes ?nodecount) (test (= ?statusnode 0)) => (assert (nodes (+ 1 ?nodecount))) (modify ?status (node ?nodecount)) (retract ?nodes) ) ;----------------------------------------------------------------------------------------- ; 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 ?last) ?node <- (nodes ?nodes) (test (> ?nodes ?last)) => (retract ?depth) (assert (depth (+ 1 ?current) ?nodes)) ) (defrule finished (declare (salience 100)) ?depth <- (depth ?current ?last) ?node <- (nodes ?nodes) (test (= ?nodes ?last)) => (printout t "A Total of " (- ?nodes 1) " Nodes in the Tree" crlf) (retract ?depth) (halt) ) ;----------------------------------------------------------------------------------------- ; 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) (operation ?move)) => (assert (complete ?status)) (assert (list "Done"))) (defrule Complete (declare (salience 2000)) ?status <- (status (parent ?parent) (operation ?move)) ?complete <- (complete ?status) ?old-list <- (list $?rest) => (assert (list ?move ?rest)) (assert (complete ?parent)) (retract ?complete) (retract ?old-list) ) (defrule Done-Complete (declare (salience 2000)) ?complete <- (complete no-parent) ?old-list <- (list ?first $?moves ?last) => (printout t "Solution:" crlf ?moves crlf) (retract ?complete ?old-list))