;;; Written by Benjamin Kuipers, University of Texas, 1993 ;;; Updated by Micheal Hewett for Algernon in Java, 2003 ;;; ;;; Load this file into Algernon to run it. ;;; --------------------------------------------------------- ;;; ****** FLU ****** ;;; ;;; This example illustrates the use of Algernon to build a very simple ;;; expert system. In particular it illustrates the use of the :ask ;;; form to query the user. ;;; ;;; Expected results: ;;; Temperature > 99 and Nausea: John has the Flu ;;; Temperature > 102 and Nodules: John has the Plague ;;; Note that both answer can be true if the temperature ;;; is above 102 and John has both Nausea and Nodules ;;; --------------------------------------------------------- ;; Create a new KB. (tell ((:USE-KB :FLU-EXAMPLE-KB Protege ))) ;; Declare basic facts (tell ((:TRACE :NORMAL))) ;; Define the basic taxonomy (tell ((:taxonomy (:THING (Objects (Symptoms Fever High-Fever Nausea Nodules) (Physical-Objects (People) (Diseases Flu Plague))))))) ;; Four new slots: ;; (has-disease x d) = x has disease d. ;; (has-symptom x s) = x has symptom s. ;; (temperature x t) = x has temperature t. ;; (symptom d s) = disease d causes symptom s. ;; (tell ((:add-relation has-disease (People Diseases) :max-cardinality :ANY) (:add-relation has-symptom (People Symptoms) :max-cardinality :ANY) (:add-relation symptom (Diseases Symptoms) :max-cardinality :ANY) (:add-relation temperature (Physical-Objects :integer) :max-cardinality 1) )) ;; Backward-chaining rules to do the basic fact-finding. (tell ((:add-rule People ((has-symptom ?p Fever) <- (temperature ?p ?t) (:test (:LISP (> ?t 99)))) ;; Rule1 ((has-symptom ?p High-Fever) <- (temperature ?p ?t) (:test (:LISP (> ?t 102)))) ;; Rule2 ((has-symptom ?p Nausea) <- (:ask (has-symptom ?p Nausea))) ;; Rule3 ((has-symptom ?p Nodules) <- (:ask (has-symptom ?p Nodules))) ;; Rule4 ((temperature ?p ?t) <- (:ask (temperature ?p ?t))) ;; Rule5 ))) ;; Backward-chaining rules for diagnosis ;; A person has a disease if they have all symptoms of the disease ... ;; Rule6 and Rule7 ;; This version of the rules orders the queries so the ;; user is not asked unnecessary questions. ;; For example, if the patient does not have a High-Fever, ;; the user will not be asked if they have Nodules. ;; See flu2.txt for an alternative way of implementing this rule. (tell ((:add-rule 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)) ))) ;; Start the process (ask ((:the-instance (?j People) (:NAME ?j "John")) (:trace :normal) (has-disease ?j ?d) (:PRINTLN ?j " has the " ?d) ))