CLIPS:CLIPS 中的数组? (需要一些指导,CLIPS 中的新功能)

CLIPS: Array in CLIPS? (Need some orientation, new in CLIPS)

我是 Clips 的新手。我想知道这是否是一种在 LHS 上读取数组(带有索引的数字或字符链,抱歉,如果名称错误)的方法。我有规则要求一个值 (s,cs,cn,n) 然后它断言下一个询问规则的值,最终读取回答规则中的所有值以获得诊断,但在我的小例子中我有 4每个问题和 4 个选项,所以混合所有答案会给我 64 条规则,我的程序中至少有 30 个问题,所以我认为规则太多(我正在做我的第一个专家系统,也许这个是正常的)。无论如何,我认为我可以将问题中的值放入数组中并在回答规则中读取它,但我的问题是:

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

如果你已经有了两个答案规则,减少规则数量的最简单方法就是将它们组合起来:

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

如果您创建的许多规则仅在模式中匹配的常量上有所不同,您应该考虑将规则表示为包含这些常量的事实和处理该数据的通用规则的组合。例如,您可以这样重写您的问题规则:

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

你的诊断规则是这样的:

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