Reputation: 99
i am VERY new to CLIPS and trying to create an expert system for medical diagnosis. Of course it is just for practice. My code runs so far, however, there are a few things I couldn't get to work.
For the first 3 symptoms (fever, cough, fatigue) if any 2 are answered yes it outputs a diagnosis. If not, it continues on to ask the patient about the less common symptoms. Right now I have made it so that if even one of the uncommon symptomps are answered yes, there is a diagnosis. However, I want to make it so that if atleast 3 of them are answered yes it outputs a diagnosis. The problem is that i dont know how to make a rule that checks for this, without having to make a bunch of separate rules checking for each and every possibility of yes and no combinations which would be tedious.
Here is a link to my code as it is rather long to put on here. https://codeshare.io/arBpq6
Upvotes: 0
Views: 143
Reputation: 10757
Define some deftemplates so you can represent your questions and answers as facts.
(deftemplate question
(slot tier (default 1))
(slot answer)
(slot query))
(deftemplate answer
(slot name)
(slot tier)
(slot response))
Your system has three tiers of questions which can now be represented as facts:
(deffacts questions
(question (tier 1)
(answer patient-contact)
(query "Has the patient been within 6 feet for a total of 15 minutes or more with someone who has confirmed COVID-19? (yes/no) "))
(question (tier 2)
(answer patient-fever)
(query "Has the patient been having mild to high fever recently? (yes/no) "))
(question (tier 2)
(answer patient-dry-cough)
(query "Has the patient been experiencing a dry cough? (yes/no) "))
(question (tier 2)
(answer patient-fatigue)
(query "Has the patient been experiencing unusual levels of fatigue? (yes/no) "))
(question (tier 3)
(answer patient-senses)
(query "Has the patient been experiencing a loss of taste or smell? (yes/no) "))
(question (tier 3)
(answer patient-nasal)
(query "Has the patient been experiencing nasal congestion? (yes/no) "))
(question (tier 3)
(answer patient-conjunctivitis)
(query "Does the patient have conjunctivitis (red eyes)? (yes/no) "))
(question (tier 3)
(answer patient-sorethroat)
(query "Does the patient have a sore throat? (yes/no) "))
(question (tier 3)
(answer patient-headache)
(query "Has the patient been having frequent headaches? (yes/no) "))
(question (tier 3)
(answer patient-pain)
(query "Has the patient been experiencing joint and muscle pains? (yes/no) "))
(question (tier 3)
(answer patient-rashes)
(query "Does the patient have any kind of skin rashes? (yes/no) "))
(question (tier 3)
(answer patient-nausea)
(query "Has the patient been experiencing nausea or been vomiting? (yes/no) "))
(question (tier 3)
(answer patient-diarrhea)
(query "Has the patient been having diarrhea? (yes/no) "))
(question (tier 3)
(answer patient-dizziness)
(query "Has the patient been experiencing dizziness or chills? (yes/no) "))
(question (tier 3)
(answer patient-breath)
(query "Has the patient been experiencing shortness of breath? (yes/no) "))
(question (tier 3)
(answer patient-appetite)
(query "Has the patient been experiencing a loss of appetite? (yes/no) "))
(question (tier 3)
(answer patient-confusion)
(query "Has the patient been experiencing unusual levels of confusion? (yes/no) "))
(question (tier 3)
(answer patient-pressure)
(query "Does the patient have persistent pain or pressure in their chest? (yes/no) "))
(question (tier 3)
(answer patient-temperature)
(query "Does the patient have a high temperature (above 38 degrees Celsius)? (yes/no) ")))
A generic rule can now be created for asking questions. Questions are removed once answered and questions will not be asked until all questions from higher tiers have been answered.
(defrule ask-question
(not (covid ?))
?f <- (question (tier ?t)
(answer ?a)
(query ?q))
(not (question (tier ?t2&:(< ?t2 ?t))))
=>
(retract ?f)
(assert (answer (name ?a)
(tier ?t)
(response (patient-answer-p ?q)))))
You can now add rules for each tier that look for a specific number of answers:
(defrule immediate-test ""
(declare (salience 10))
(not (covid ?))
(exists (answer (tier 1)
(response yes)))
=>
(assert (covid "The patient should be tested immediately as it is highly likely the virus could be transferred to them.")))
(defrule two-common-symptoms ""
(declare (salience 10))
(not (covid ?))
(exists (answer (tier 2)
(name ?n1)
(response yes))
(answer (tier 2)
(name ?n2&~?n1)
(response yes))
(answer (tier 2)
(name ?n3&~?n2&~?n1)
(response no)))
=>
(assert (covid "The patient shows 2 of the common symptoms, and it is recommended that they get tested.")))
(defrule all-common-symptoms ""
(declare (salience 10))
(not (covid ?))
(exists (answer (tier 2)
(name ?n1)
(response yes))
(answer (tier 2)
(name ?n2&~?n1)
(response yes))
(answer (tier 2)
(name ?n3&~?n2&~?n1)
(response yes)))
=>
(assert (covid "The patient shows all 3 of the common symptoms, and it is highly recommended that they get tested.")))
(defrule three-uncommon-symptoms ""
(declare (salience 10))
(not (covid ?))
(exists (answer (tier 3)
(name ?n1)
(response yes))
(answer (tier 3)
(name ?n2&~?n1)
(response yes))
(answer (tier 3)
(name ?n3&~?n2&~?n1)
(response yes)))
=>
(assert (covid "The patient is showing at least 3 of the uncommon symptoms, and therefore it is recommended that they be tested.")))
Upvotes: 1