Search code examples
clips

Variable Order of values in LHS, OR/AND operators


I'm trying to define a rule by this form:


;Plantilla Ficha de paciente
(deftemplate FichaPaciente
    (multifield Nombre)
    (field Casado)
    (field Direccion))

;Plantilla DatosExploración
(deftemplate DatosExploracion
    (multifield Nombre)
    (multifield Sintomas)
    (field GravedadAfeccion))

;Regla para diagnóstico de Eccema
(defrule DiagnosticoEccema
    (DatosExploracion
        (and
        (Nombre $?Nombre)
            (or
            (Sintomas $? picor $? vesiculas $?)
            (Sintomas $? vesiculas $? picor $?)
            )
        )
    )
    (FichaPaciente
        (Nombre $?Nombre))
=>
    (printout t "Posible diagnóstico para el paciente " $?Nombre ": Eccema " crlf)
)

The goal is that it was not important if a DatosExploracion fact has the field Sintomas with values (... picor ... vesicula ...) or (... vesicula ... picor). Vesicula and picor order it's not important.

I'm trying with the "and" and "or" operators, but i receive the error: Invalid slot 'and' not defined in corresponding deftemplate 'DatosExploracion'.

1 - Why CLIPS don't recognize the AND and OR operators like i wanted?

2 - Is there a better or more efficient way of getting that the order of values on field Sintomas it's non important?

Thanks in advance.


Solution

  • Here's one way you can do it:

    (defrule DiagnosticoEccema
       (DatosExploracion
          (Nombre $?Nombre)
          (Sintomas $?Sintomas&:(and (member$ picor ?Sintomas)
                                     (member$ vesiculas ?Sintomas))))
       (FichaPaciente
          (Nombre $?Nombre))
       =>
       (printout t "Posible diagnóstico para el paciente " $?Nombre ": Eccema " crlf))
    

    And another which uses a helper function to reduce the amount of typing when there are multiple symptoms:

    (deffunction all-present (?set1 $?set2)
       (foreach ?s ?set2
          (if (not (member$ ?s ?set1))
             then (return FALSE)))
       (return TRUE))    
       
    (defrule DiagnosticoEccema
       (DatosExploracion
          (Nombre $?Nombre)
          (Sintomas $?Sintomas&:(all-present ?Sintomas picor vesiculas)))
       (FichaPaciente
          (Nombre $?Nombre))
       =>
       (printout t "Posible diagnóstico para el paciente " $?Nombre ": Eccema " crlf))