2017-04-07 7 views
0

私はCLIPSを初めて使用しており、バックトラッキングのパラダイムが頭を痛めます。CLIPSでif-then-elseを排除してコードを最適化する方法

私は次の出力を生成する必要があるという質問があります。

必要に応じて、動作させるためにいくつかのルールを定義しました。

(defrule rule_1 
    (THE-PATIENT-HAS-A-SORE-THROAT) 
    (WE-SUSPECT-A-BACTERIAL-INFECTION) => 
    (assert(WE-BELIEVE-THE-PATIENT-HAS-STREP-THROAT)) 
    (printout t "We believe the patient has strep throat" crlf)) 

(defrule rule_2 
    (THE-PATIENT-TEMPERATURE-IS-40C) => 
    (assert(THE-PATIENT-HAS-A-FEVER))) 

(defrule rule_3 
    (THE-PATIENT-HAS-BEEN-SICK-OVER-A-MONTH) 
    (THE-PATIENT-HAS-A-FEVER) => 
    (assert(WE-SUSPECT-A-BACTERIAL-INFECTION))) 

(defrule ask-sick 
    (start-question) => 
    (printout t "Q: Is the patient's temperature more than 39? [yes/no]: ") 
    (bind ?input (readline)) 
    (if (neq ?input "no") 
    then 
     (assert (THE-PATIENT-TEMPERATURE-IS-40C)) 
     (printout t "The patient has fever" crlf) 
     (printout t "Q: Does the patient sick over a month? [yes/no]: ") 
     (bind ?input2 (readline)) 
     (if (neq ?input2 "no") 
     then 
      (assert (THE-PATIENT-HAS-BEEN-SICK-OVER-A-MONTH)) 
      (printout t "We suspect the patient has bacterial infection" crlf) 
      (printout t "Q: How about sore throat? [yes/no]: ") 
      (bind ?input3 (readline)) 
      (if (neq ?input3 "no") 
      then 
       (assert (THE-PATIENT-HAS-A-SORE-THROAT)) 
     ) 
    ) 
) 
) 

(deffacts start 
    (start-question) 
) 

最終的に私はプログラムを生き生きとさせました。

問題は、質問のルールで、if-then-elseの束を組み込んで、バックトラッキングのパラダイムにあまり適合しないプログラムが動作するようにする必要がありました。

誰かが、それは、ルール1続行する場所を知っているのように私はそれを最適化する方法を教えてもらえます - など>ルール2 /ルール3を、

答えて

1

は、ここに1つのアプローチです:

(deffunction ask-question (?question $?allowed-values) 
    (printout t "Q: " ?question " [" (implode$ ?allowed-values) "] ") 
    (bind ?answer (read)) 
    (if (lexemep ?answer) 
     then (bind ?answer (lowcase ?answer))) 
    (while (not (member ?answer ?allowed-values)) do 
     (printout t "Q: " ?question " [" (implode$ ?allowed-values) "] ") 
     (bind ?answer (read)) 
     (if (lexemep ?answer) 
      then (bind ?answer (lowcase ?answer)))) 
    ?answer) 

(deffunction yes-or-no (?question) 
    (ask-question ?question yes no)) 

(defrule ask-temperature 
    => 
    (bind ?input (yes-or-no "Is the patient's temperature more than 39?")) 
    (assert (THE-PATIENT-TEMPERATURE-IS-40C ?input))) 

(defrule ask-sick-for-over-a-month 
    (THE-PATIENT-HAS-A-FEVER yes) 
    => 
    (bind ?input (yes-or-no "Does the patient sick over a month?")) 
    (assert (THE-PATIENT-HAS-BEEN-SICK-OVER-A-MONTH ?input))) 

(defrule ask-sore-throat 
    (WE-SUSPECT-A-BACTERIAL-INFECTION yes) 
    => 
    (bind ?input (yes-or-no "How about sore throat?")) 
    (assert (THE-PATIENT-HAS-A-SORE-THROAT ?input))) 

(defrule conclude-fever 
    (THE-PATIENT-TEMPERATURE-IS-40C yes) 
    => 
    (assert (THE-PATIENT-HAS-A-FEVER yes)) 
    (printout t "The patient has fever" crlf)) 

(defrule conclude-bacterial-infection 
    (THE-PATIENT-HAS-BEEN-SICK-OVER-A-MONTH yes) 
    (THE-PATIENT-HAS-A-FEVER yes) 
    => 
    (assert (WE-SUSPECT-A-BACTERIAL-INFECTION yes)) 
    (printout t "We suspect the patient has bacterial infection" crlf)) 

(defrule conclude-strep-throat 
    (THE-PATIENT-HAS-A-SORE-THROAT yes) 
    (WE-SUSPECT-A-BACTERIAL-INFECTION yes) 
    => 
    (assert (WE-BELIEVE-THE-PATIENT-HAS-STREP-THROAT yes)) 
    (printout t "We believe the patient has strep throat" crlf)) 

別:

(deffunction ask-question (?question $?allowed-values) 
    (printout t "Q: " ?question " [" (implode$ ?allowed-values) "] ") 
    (bind ?answer (read)) 
    (if (lexemep ?answer) 
     then (bind ?answer (lowcase ?answer))) 
    (while (not (member ?answer ?allowed-values)) do 
     (printout t "Q: " ?question " [" (implode$ ?allowed-values) "] ") 
     (bind ?answer (read)) 
     (if (lexemep ?answer) 
      then (bind ?answer (lowcase ?answer)))) 
    ?answer) 

(deffunction yes-or-no (?question) 
    (ask-question ?question yes no)) 

(deftemplate attribute 
    (slot name) 
    (slot value)) 

(deftemplate question 
    (slot text) 
    (slot attribute) 
    (multislot precursors)) 

(deftemplate conclusion 
    (slot text) 
    (slot attribute) 
    (multislot precursors)) 

(deffacts questions 
    (question 
     (text "Is the patient's temperature more than 39?") 
     (attribute THE-PATIENT-TEMPERATURE-IS-40C)) 
    (question 
     (text "Does the patient sick over a month?") 
     (attribute THE-PATIENT-HAS-BEEN-SICK-OVER-A-MONTH) 
     (precursors THE-PATIENT-HAS-A-FEVER)) 
    (question 
     (text "How about sore throat?") 
     (attribute THE-PATIENT-HAS-A-SORE-THROAT) 
     (precursors WE-SUSPECT-A-BACTERIAL-INFECTION))) 

(deffacts conclusions 
    (conclusion 
     (text "The patient has fever") 
     (attribute THE-PATIENT-HAS-A-FEVER) 
     (precursors THE-PATIENT-TEMPERATURE-IS-40C)) 
    (conclusion 
     (text "We suspect the patient has bacterial infection") 
     (attribute WE-SUSPECT-A-BACTERIAL-INFECTION) 
     (precursors THE-PATIENT-HAS-BEEN-SICK-OVER-A-MONTH THE-PATIENT-HAS-A-FEVER)) 
    (conclusion 
     (text "We believe the patient has strep throat") 
     (attribute WE-BELIEVE-THE-PATIENT-HAS-STREP-THROAT) 
     (precursors THE-PATIENT-HAS-A-SORE-THROAT WE-SUSPECT-A-BACTERIAL-INFECTION))) 

(defrule ask-question 
    (question (text ?text) 
       (attribute ?attr)) 
    (forall (question (attribute ?attr) 
         (precursors $? ?pre $?)) 
      (attribute (name ?pre) 
         (value yes))) 
    => 
    (bind ?input (yes-or-no ?text)) 
    (assert (attribute (name ?attr) (value ?input)))) 

(defrule conclude 
    (conclusion (text ?text) 
       (attribute ?attr)) 
    (forall (conclusion (attribute ?attr) 
         (precursors $? ?pre $?)) 
      (attribute (name ?pre) 
         (value yes))) 
    => 
    (assert (attribute (name ?attr) (value yes))) 
    (printout t ?text crlf)) 
+0

うわー!それは本当に独創的です!ありがとう! –

関連する問題