;;; 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 ))) ;; (tell ((:show-code Rule2))) ;; backward-chaining rule for diagnosis ;; A person has a disease if they have all symptoms of the disease ... ;; This version of the rules does not necessarily order the ;; queries, so the user may be asked unnecessary questions. ;; For example, if the patient does not have a High-Fever, ;; the user may still be asked if they have Nodules. ;; See flu1.txt for an alternative way of implementing this rule. ;; Rule6 (tell ((:add-rule People ((has-disease ?x ?d1) <- (:INSTANCE Diseases ?d1) (:all-paths ((symptom ?d1 ?s)) ((has-symptom ?x ?s)))) ))) ;; Basic facts (tell ((:trace :normal) (symptom Flu Nausea) (symptom Plague Nodules) (symptom Flu Fever) (symptom Plague High-Fever) )) ;; Start the process (ask ((:the-instance (?j People) (:NAME ?j "John")) ;;(:trace :debug) ;;(:trace :step) (has-disease ?j ?d) ;;(:trace :run) (:PRINTLN ?j " has the " ?d) ))