Создание правил, которые не повторяются в клипах — Экспертная система

#rules #clips #expert-system

#Правила #клипы #экспертная система

Вопрос:

я новичок в CLIPS и пытаюсь создать экспертную систему для медицинской диагностики. Конечно, это просто для практики. Мой код выполняется до сих пор, однако есть несколько вещей, которые я не смог заставить работать.

Для первых 3 симптомов (лихорадка, кашель, усталость), если на какие-либо 2 дан положительный ответ, выводится диагноз. Если нет, он продолжает спрашивать пациента о менее распространенных симптомах. Прямо сейчас я сделал так, чтобы, если хотя бы на один из необычных симптомов был дан положительный ответ, был поставлен диагноз. Однако я хочу сделать так, чтобы, если хотя бы на 3 из них был дан положительный ответ, он выводил диагноз. Проблема в том, что я не знаю, как создать правило, которое проверяет это, без необходимости создавать кучу отдельных правил, проверяющих каждую возможность комбинаций «да» и «нет», что было бы утомительно.

Вот ссылка на мой код, так как он довольно длинный для размещения здесь. https://codeshare.io/arBpq6

Ответ №1:

Определите некоторые deftemplates, чтобы вы могли представлять свои вопросы и ответы как факты.

 (deftemplate question
   (slot tier (default 1))
   (slot answer)
   (slot query))

(deftemplate answer
   (slot name)
   (slot tier)
   (slot response))
  

В вашей системе есть три уровня вопросов, которые теперь можно представить в виде фактов:

 (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) ")))
  

Теперь можно создать общее правило для задания вопросов. Вопросы удаляются после получения ответов, и вопросы не будут задаваться до тех пор, пока не будут даны ответы на все вопросы с более высоких уровней.

 (defrule ask-question
   (not (covid ?))
   ?f <- (question (tier ?t)
                   (answer ?a)
                   (query ?q))
   (not (question (tier ?t2amp;:(< ?t2 ?t))))
   =>
   (retract ?f)
   (assert (answer (name ?a)
                   (tier ?t)
                   (response (patient-answer-p ?q)))))
  

Теперь вы можете добавлять правила для каждого уровня, которые ищут определенное количество ответов:

 (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 ?n2amp;~?n1)
                   (response yes))
           (answer (tier 2)
                   (name ?n3amp;~?n2amp;~?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 ?n2amp;~?n1)
                   (response yes))
           (answer (tier 2)
                   (name ?n3amp;~?n2amp;~?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 ?n2amp;~?n1)
                   (response yes))
           (answer (tier 3)
                   (name ?n3amp;~?n2amp;~?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.")))
  

Комментарии:

1. Спасибо, я ценю количество деталей, которые вы мне предоставили. Это имеет большой смысл и легко следовать.