0
votes

I'm new in Clips. I'd like to know if it is a way to read an array (chain of numeric or characters with an index, sorry if it's the wrong name) on LHS. I have rules to ask for a value (s,cs,cn,n) then it assert the value to next asking rule, to finally read all the values in an answering rule to get a diagnostic, but in my small example I have 4 questions and 4 options for each one so mixing all the answers would give me 64 rules, and I have so at least 30 questions in my program so I think that would be too much rules (I'm doing my first Expert System an maybe this is normal). In any case I think I could get the values from questions into an array an read it in answering rules, but my questions are:

*How can I bind the values from my function into an array?
*Is it possible to verify that array in LHS?
*Do you have any other idea to verify the answer-rules? Hope you can help me.


    (deffunction funcionPregunta (?pregunta $?valoresAceptados) ;;ask-question function
            (printout t ?pregunta)
            (bind ?respuesta (read))
            (if (lexemep ?respuesta)
                    then (bind ?respuesta (lowcase ?respuesta)))
            (while (not (member$ ?respuesta ?valoresAceptados)) do 
                    (printout t ?pregunta)
            (bind ?respuesta (read))
            (if (lexemep ?respuesta)
                    then (bind ?respuesta (lowcase ?respuesta))))
            ?respuesta)

;;===============================================================
;;      QUESTION RULES
;;===============================================================


    (defrule pregunta1T5 "AGORAFOBIA"
            (not (diagnostico ?))
            =>
            (assert (Pregunta2T5
                    (funcionPregunta "1.Siente miedo o ansiedad marcada. (always/frecuently/rare/never)? "
                        s cs cn n))))
    
    (defrule Pregunta2T5 "AGORAPUBLICO"
            (not (diagnostico ?))
            (Pregunta2T5 ?Pregunta2T5)
            =>
            (assert (Pregunta3T5
            (funcionPregunta "2.Siente miedo en una multitud. (always/frecuently/rare/never)? "
                        s cs cn n)))
    )
    
    (defrule Pregunta3T5 "AGORAMIEDO"
            (not (diagnostico ?))
            (Pregunta3T5 ?Pregunta3T5)
            =>
            (assert (Pregunta4T5
            (funcionPregunta "3.Miedo de estar en una situacion. (always/frecuently/rare/never)? "
                        s cs cn n)))
    )
    
    (defrule Pregunta4T5 "AGORAANSIEDAD"
     ... ;; similar rules

;;===============================================================
;;      ANSWERS RULES
;;===============================================================


    (defrule Respuesta1T6 "RESULTADO 1 TAS"
            (not (diagnostico ?))
            (Pregunta2T6 s)(Pregunta3T6 s)(Pregunta4T6 s)(Pregunta5T6 s)
            =>
            (assert (diagnostico "TRASTORNO DE ANSIEDAD SOCIAL"))
    )

(defrule Respuesta2T6 "RESULTADO 2 TAS"
        (not (diagnostico ?))
        (Pregunta2T6 cs)(Pregunta3T6 s)(Pregunta4T6 s)(Pregunta5T6 s)
        =>
        (assert (diagnostico "TRASTORNO DE ANSIEDAD SOCIAL"))
)
1

1 Answers

0
votes

In the case of the two answer rules you've already got, the simplest way to reduce the number of rules is just to combine them:

(defrule Respuesta1T6-2T6
   (not (diagnostico ?))
   (Pregunta2T6 s | cs) ; s or cs is allowed
   (Pregunta3T6 s)
   (Pregunta4T6 s)
   (Pregunta5T6 s)
   =>
   (assert (diagnostico "TRASTORNO DE ANSIEDAD SOCIAL")))

If you're creating lots of rules that differ only in the constants matched in the patterns, you should consider representing the rules as a combination of facts containing these constants and generic rules to process that data. For example, you could rewrite your question rules like this:

(deftemplate Pregunta      ; question
   (slot identidad)        ; ID
   (slot texto)            ; text
   (multislot respuestas)  ; responses
   (slot precursora        ; precursor
      (default ninguna)))  ; none

(deftemplate Responder     ; answer
   (slot identidad)        ; ID
   (slot valor))           ; value
       
(deffacts Preguntas
   (Pregunta (identidad AGORAFOBIA)
             (texto "1. Siente miedo o ansiedad marcada. (always/frecuently/rare/never)? ")
             (respuestas s cs cn n))
   (Pregunta (identidad AGORAPUBLICO)
             (texto "2. Siente miedo en una multitud. (always/frecuently/rare/never)? ")
             (respuestas s cs cn n)
             (precursora AGORAFOBIA))
   (Pregunta (identidad AGORAMIEDO)
             (texto "3. Miedo de estar en una situacion. (always/frecuently/rare/never)? ")
             (respuestas s cs cn n)
             (precursora AGORAPUBLICO)))

(defrule pedir-pregunta ; ask question
   (not (diagnostico ?))
   (Pregunta (identidad ?id)
             (texto ?t)
             (respuestas $?r)
             (precursora ?p))
   (or (test (eq ?p ninguna))
       (Responder (identidad ?p)))
   =>
   (assert (Responder (identidad ?id)
                      (valor (funcionPregunta ?t ?r)))))

And your diagnosis rules like this:

(deftemplate Trastorno   ; disorder
   (slot nombre)         ; name
   (multislot sintomas)) ; symptoms
   
(deftemplate Sintoma
   (slot identidad)      ; ID
   (slot responder)      ; answer
   (multislot valors))   ; values

(deffacts Trastornos
   (Trastorno (nombre "TRASTORNO DE ANSIEDAD SOCIAL")
              (sintomas AGORAFOBIA-cs-s AGORAPUBLICO-s AGORAMIEDO-s)))
              
(deffacts Sintomas
   (Sintoma (identidad AGORAFOBIA-cs-s)
            (responder AGORAFOBIA)
            (valors cs s))
   (Sintoma (identidad AGORAPUBLICO-s)
            (responder AGORAPUBLICO)
            (valors s))
   (Sintoma (identidad AGORAMIEDO-s)
            (responder AGORAMIEDO)
            (valors s)))
   
(defrule Respuesta
   (not (diagnostico ?))
   (Trastorno (nombre ?n))                 ; There is a disorder.
   (forall (Trastorno (nombre ?n)          ; For every symptom
                      (sintomas $? ?s $?)) ; of the disorder,
           (Sintoma (identidad ?s)         ; there is a list
                    (responder ?r)         ; of possible values
                    (valors $?sv))         ; for that symptom
           (Responder (identidad ?r)       ; matched by a response.
                      (valor ?v&:(member$ ?v ?sv))))
   =>
   (assert (diagnostico ?n)))