next up previous contents
Next: Rules - Slightly Less Up: A Simple Expert System: Previous: Rules - Simple

Queries Based on Simple Rules

We can test these rules with a query that finds or creates a frame for a person given a one-symbol name, then asks what diseases that person has.

(defun dx-patient (name)
  (ask `((:the ?p (name ?p ,(string name)) (isa ?p People))
         (has-disease ?p ?d))
       :comment "What does the patient have?"
       :collect '(?p has ?d)))

Frank, George and Harry all present with fever, but turn out to have different diagnoses. The rules for the two diseases backchain to the rules for fever or high-fever, which in turn backchain to the rule for temperature, which queries the user. In Frank's case, his fever is low enough that the rule for plague fails without asking about nodules.

> (dx-patient 'frank)
 Give me a value for ?t in (temperature frank ?t): 100
 Is it true that (has-symptom frank nausea)?  (Yes or No) yes
((FRANK HAS FLU))

George is asked about nodules, and indeed has the plague, but at least avoids the flu.

> (dx-patient 'george)
 Give me a value for ?t in (temperature george ?t): 103
 Is it true that (has-symptom george nodules)?  (Yes or No) yes
 Is it true that (has-symptom george nausea)?  (Yes or No) no
((GEORGE HAS PLAGUE))

Poor Harry has both the plague and the flu.

> (dx-patient 'harry)
 Give me a value for ?t in (temperature harry ?t): 104
 Is it true that (has-symptom harry nodules)?  (Yes or No) yes
 Is it true that (has-symptom harry nausea)?  (Yes or No) yes
((HARRY HAS PLAGUE) (HARRY HAS FLU))

It can be instructive to follow the ``Logic Trace'' of the deduction by which Harry was diagnosed.

algy> tl
  Trace level = :LOGIC.

algy> (dx-patient 'harry)

  ** Beginning logic Trace **
 Querying: (:the (?j) (name ?j "harry") (isa ?j people)).
   Querying: (name ?j "harry").
   Query failed.
   Creating new frame: harry.
   Asserting: (name harry "harry").
     Inserting new value (isa harry things). 
     Inserting new value (name harry "harry"). 
   Assert succeeded: (name harry "harry").
   Asserting: (isa harry people).
     Inserting new value (isa harry people). 
       Applying: ((isa harry people) -> (isa harry objects)).
         Querying: (isa harry people).
         Query succeeded: (isa harry people).
         Asserting: (isa harry objects).
           Inserting new value (isa harry objects). 
             Applying: ((isa harry objects) -> (isa harry things)).
               Querying: (isa harry objects).
               Query succeeded: (isa harry objects).
               Asserting: (isa harry things).
                 Value already known (isa harry things). 
               Assert succeeded: (isa harry things).
             Rule applied.
         Assert succeeded: (isa harry objects).
       Rule applied.
       Applying: ((isa harry people) -> (isa harry physical-objects)).
         Querying: (isa harry people).
         Query succeeded: (isa harry people).
         Asserting: (isa harry physical-objects).
           Inserting new value (isa harry physical-objects). 
             Applying: ((isa harry physical-objects) -> (isa harry objects)).
               Querying: (isa harry physical-objects).
               Query succeeded: (isa harry physical-objects).
               Asserting: (isa harry objects).
                 Value already known (isa harry objects). 
               Assert succeeded: (isa harry objects).
             Rule applied.
         Assert succeeded: (isa harry physical-objects).
       Rule applied.
   Assert succeeded: (isa harry people).
 Query succeeded: (:the (harry) (name harry "harry") (isa harry people)).
 (:the (?j) (name ?j "harry") (isa ?j people))
 Querying: (has-disease harry ?d).
   Creating new frame: ri-0.
   Creating new frame: ri-1.
   Applying: ((has-disease harry plague) <- (has-symptom harry high-fever) 
                                           (has-symptom harry nodules)).
     Querying: (has-symptom harry high-fever).
       Creating new frame: ri-2.
       Applying: ((has-symptom harry high-fever) <- (temperature harry ?t) 
                                                   (:test (> ?t 102))).
         Querying: (temperature harry ?t).
           Creating new frame: ri-3.
           Applying: ((temperature harry ?t) <- (:ask (temperature harry ?t))).
             Querying: (:ask (temperature harry ?t)).
 Give me a value for ?t in (temperature harry ?t): 104
               Asserting: (temperature harry 104).
                 Inserting new value (temperature harry 104). 
               Assert succeeded: (temperature harry 104).
             Query succeeded: (:ask (temperature harry 104)).
             Asserting: (temperature harry 104).
               Value already known (temperature harry 104). 
             Assert succeeded: (temperature harry 104).
           Rule applied.
         Query succeeded: (temperature harry 104).
         Querying: (:test (> 104 102)).
         Query succeeded: (:test (> 104 102)).
         Asserting: (has-symptom harry high-fever).
           Inserting new value (has-symptom harry high-fever). 
         Assert succeeded: (has-symptom harry high-fever).
       Rule applied.
     Query succeeded: (has-symptom harry high-fever).
     Querying: (has-symptom harry nodules).
       Creating new frame: ri-4.
       Applying: ((has-symptom harry nodules) <- (:ask (has-symptom harry 
                                                                   nodules))).
         Querying: (:ask (has-symptom harry nodules)).
 Is it true that (has-symptom harry nodules)?  (Yes or No) yes
           Asserting: (has-symptom harry nodules).
             Inserting new value (has-symptom harry nodules). 
           Assert succeeded: (has-symptom harry nodules).
         Query succeeded: (:ask (has-symptom harry nodules)).
         Asserting: (has-symptom harry nodules).
           Value already known (has-symptom harry nodules). 
         Assert succeeded: (has-symptom harry nodules).
       Rule applied.
     Query succeeded: (has-symptom harry nodules).
     Asserting: (has-disease harry plague).
       Inserting new value (has-disease harry plague). 
     Assert succeeded: (has-disease harry plague).
   Rule applied.
   Applying: ((has-disease harry flu) <- (has-symptom harry fever) 
                                        (has-symptom harry nausea)).
     Querying: (has-symptom harry fever).
       Creating new frame: ri-5.
       Applying: ((has-symptom harry fever) <- (temperature harry ?t) 
                                              (:test (> ?t 99))).
         Querying: (temperature harry ?t).
         Query succeeded: (temperature harry 104).
         Querying: (:test (> 104 99)).
         Query succeeded: (:test (> 104 99)).
         Asserting: (has-symptom harry fever).
           Inserting new value (has-symptom harry fever). 
         Assert succeeded: (has-symptom harry fever).
       Rule applied.
     Query succeeded: (has-symptom harry fever).
     Querying: (has-symptom harry nausea).
       Creating new frame: ri-6.
       Applying: ((has-symptom harry nausea) <- (:ask (has-symptom harry nausea))).
         Querying: (:ask (has-symptom harry nausea)).
 Is it true that (has-symptom harry nausea)?  (Yes or No) yes
           Asserting: (has-symptom harry nausea).
             Inserting new value (has-symptom harry nausea). 
           Assert succeeded: (has-symptom harry nausea).
         Query succeeded: (:ask (has-symptom harry nausea)).
         Asserting: (has-symptom harry nausea).
           Value already known (has-symptom harry nausea). 
         Assert succeeded: (has-symptom harry nausea).
       Rule applied.
     Query succeeded: (has-symptom harry nausea).
     Asserting: (has-disease harry flu).
       Inserting new value (has-disease harry flu). 
     Assert succeeded: (has-disease harry flu).
   Rule applied.
 Query succeeded: (has-disease harry flu) (has-disease harry plague).
 (has-disease ?j ?d)
  ** End logic Trace **
  ((HARRY HAS PLAGUE) (HARRY HAS FLU))



Micheal S. Hewett
Tue Oct 29 10:54:13 CST 1996