(setf *load-print* T)
(defstruct terminal contents)
(defstruct node test yes no)
(defun next-node (test-result node)
(cond (test-result (node-yes node))
(T (node-no node))))
(defun traverse (node)
(cond ((terminal-p node) (terminal-contents node))
((node-p node)
(traverse (next-node (funcall (node-test node)) node)))
(T nil)
)
)
(let ((subtree (make-node
:test #'(lambda () (y-or-n-p "Heavy Exercise?"))
:yes (make-terminal :contents "Run down")
:no (make-terminal :contents "May be hyperactive")
)
))
(setq *hypochondriac*
(make-node
:test #'(lambda () (y-or-n-p "Feel Well?"))
:yes (make-node
:test #'(lambda () (y-or-n-p "Hungry?"))
:no (make-node
:test #'(lambda () (y-or-n-p "Thirsty?"))
:yes (make-terminal :contents "Potential dehydration")
:no (make-terminal :contents "Possible Eating Disorder")
)
:yes (make-node
:test #'(lambda () (y-or-n-p "Very Hungry?"))
:yes (make-node
:test #'(lambda () (y-or-n-p "Recent Meal?"))
:yes subtree
:no (make-terminal :contents "Starving")
)
:no (make-terminal :contents "Time for a health snack")
)
)
:no (make-node
:test #'(lambda () (y-or-n-p "Weak?"))
:yes (make-node
:test #'(lambda () (y-or-n-p "Hungry?"))
:yes subtree
:no (make-node
:test #'(lambda () (y-or-n-p "Headache?"))
:yes (make-node
:test #'(lambda () (y-or-n-p "Runny Nose"))
:yes (make-terminal :contents "Probably Flu")
:no (make-terminal :contents "Probably Mad Cow Disease")
)
:no (make-terminal :contents "Try an aspirin")
)
)
:no (make-node
:test #'(lambda () (y-or-n-p "Upset stomach?"))
:yes (make-terminal :contents "Probably food poisoning")
:no (make-terminal :contents "Probably Lyme disease")
)
)
)
)
)
(traverse *hypochondriac*)