mcventur
mcventur

Reputation: 71

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.

Upvotes: 0

Views: 51

Answers (2)

Gary Riley
Gary Riley

Reputation: 10757

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

Upvotes: 0

mcventur
mcventur

Reputation: 71

I've getted the goal on this way


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

But if it was a unordered combination of 3,4 or 5 Values for multifield Sintomas, it would be too tedious. I would like if there is a better way to get this using the connectives | or & in a more efficient way.

Upvotes: 0

Related Questions