The simplest approach to diagnosis is to write a set of special-purpose rules for each disease, specifying when we can conclude that a patient has the disease.
(tell '((:rules People ((has-disease ?x Flu) <- (has-symptom ?x fever) (has-symptom ?x nausea)) ((has-disease ?x Plague) <- (has-symptom ?x high-fever) (has-symptom ?x nodules)) )))
These rules will be invoked on a query such as ((has-disease ?p ?d)), and will chain backward to query the symptoms of ?p. Therefore, we need rules to conclude symptoms.
(tell '((:rules People ((has-symptom ?p fever) <- (temperature ?p ?t) (:test (> ?t 99))) ((has-symptom ?p high-fever) <- (temperature ?p ?t) (:test (> ?t 102))) ((has-symptom ?p nausea) <- (:ask (has-symptom ?p nausea))) ((has-symptom ?p nodules) <- (:ask (has-symptom ?p nodules))) ((temperature ?p ?t) <- (:ask (temperature ?p ?t))))))
In order to conclude that the patient has the symptom fever, we determine the patient's temperature t, and test whether t>99. The :test special form allows us to escape to Lisp to evaluate a Lisp expression. We can only determine the patient's temperature by asking the user. Similarly, we can only conclude that the patient has nausea by asking the user.
The :ask special form is a trivial user interface, used only for tutorial purposes. We will describe the interfaces with Lisp and with the user in the next section.