expert-systemjessinference-engine

Jess: Error with Operator less than


I am learning about less and have a problem when define a rule with the less than operator '<. This are my defTemplates:

(deftemplate AgudezaVisual
    (slot agudezaVisual)
    (slot estado)
)

(deftemplate Bucodental
    (slot hayDientesDañados)
    (slot hayDientesConConcavidades)
    (slot hayCaries)
    (slot estadoEncias)
    (slot presentaCancerOral)
    (slot haySangradoOInflamacionPaladar)
    (slot haySangradoOInflamacionLengua)
    (slot tieneGengivitis)
    (slot estado)
)

(deftemplate Respiratorio
    (slot tieneDisnea)
    (slot tieneTos)
    (slot tieneEsputo)
    (slot tieneDolorToracico)
    (slot tieneEdema)
    (slot tieneJadeo)
    (slot estado)
)

(deftemplate Digestivo
    (slot tieneCirrosis)
    (slot esCeliaco)
    (slot esDiabetico)
    (slot tieneHepatitisB)
    (slot tieneHepatitisC)
    (slot estado)
)

(deftemplate Electrocardiograma
    (slot frecuenciaCardiaca)
    (slot tieneInsuficienciaCardiaca)
    (slot tieneArritmia)
    (slot tienePericarditis)
    (slot tieneMiocarditis)
    (slot estado)
)

(deftemplate Hemograma
    (slot eritrocitos)
    (slot hematocrito)
    (slot hemoglobina)
    (slot leucocitos)
    (slot plaquetas)
    (slot estado)
)

(deftemplate Eritrocedimentacion
    (slot velocidad)
    (slot posibleAnemia)
    (slot posibleInfecciosas)
    (slot posibleEnfermedadesInflamatorias)
    (slot posiblesEnfermedadesReumaticas)
    (slot estado)
)

(deftemplate Glucemia
    (slot glocosa)
    (slot estado)
)

(deftemplate Uremia
    (slot urea)
    (slot estado)
)

(deftemplate Orina
    (slot leucocitos)
    (slot cetonas)
    (slot sangre)
    (slot ph)
    (slot bilirrubina)
    (slot nitritos)
    (slot estado)
)

(deftemplate RadiografiaTorax
    (slot presentaElementosPatologicos)
    (slot estado)
)

(deftemplate InformeFinalAptitud
    (slot observaciones)
    (slot estado)
)

And this my rules:

(defrule R1
    (AgudezaVisual (agudezaVisual ?a & : (> ?a 0.5)))
    =>
    (assert (AgudezaVisual (estado APTO)))
)

(defrule R2
    (AgudezaVisual (agudezaVisual ?a & : (< ?a 0.5)))
    =>
    (assert (AgudezaVisual (estado NO_APTO)))
)

(defrule R3
    (Bucodental (hayDientesDañados true))
    (Bucodental (hayCaries true))
    (Bucodental (hayDientesConConcavidades true))
    (Bucodental (haySangradoOInflamacionLengua true))
    (Bucodental (haySangradoOInflamacionPaladar true))
    =>
    (assert (Bucodental (estado NO_APTO)))
)

(defrule R4
    (Bucodental (presentaCancerOral true))
    =>
    (assert (Bucodental (estado NO_APTO)))
)

(defrule R5
    (Bucodental (tieneGengivitis true))
    =>
    (assert (Bucodental (estado APTO)))
)

(defrule R6
    (Respiratorio (tieneDisnea true))
    (Respiratorio (tieneJadeo true))
    =>
    (assert (Respiratorio (estado NO_APTO)))
)

(defrule R7
    (or (Respiratorio (tieneTos true))
    (Respiratorio (tieneJadeo true)))
    =>
    (assert (Respiratorio (estado NO_APTO)))
)

(defrule R8
    (Respiratorio (tieneTos true))
    (Respiratorio (tieneEsputo true))
    (Respiratorio (tieneDolorToracico true))
    =>
    (assert (Respiratorio (estado NO_APTO)))
)

(defrule R9
    (Respiratorio (tieneDisnea true))
    (Respiratorio (tieneEdema true))
    =>
    (assert (Respiratorio (estado NO_APTO)))
)

(defrule R10
    (Respiratorio (tieneDolorToracico true))
    =>
    (assert (Respiratorio (estado APTO)))
)

(defrule R11
    (Digestivo (tieneCirrosis true))
    =>
    (assert (Digestivo (estado NO_APTO)))
)

(defrule R12
    (Digestivo (esCeliaco true))
    =>
    (assert (Digestivo (estado APTO)))
)

(defrule R13
    (Digestivo (esDiabetico true))
    =>
    (assert (Digestivo (estado APTO)))
)

(defrule R14
    (Digestivo (tieneHepatitisB true))
    (Digestivo (tieneHepatitisC true))
    =>
    (assert (Digestivo (estado NO_APTO)))
)

(defrule R15
    (Digestivo (tieneHepatitisB true))
    (Digestivo (esCeliaco true))
    =>
    (assert (Digestivo (estado NO_APTO)))
)

(defrule R16
    (Electrocardiograma {frecuenciaCardiaca < 60})
    =>
    (assert (Electrocardiograma (estado NO_APTO)))
)

(defrule R17
    (Electrocardiograma {frecuenciaCardiaca < 100})
    (Electrocardiograma {frecuenciaCardiaca > 59})
    =>
    (assert (Electrocardiograma (estado APTO)))
)

(defrule R18
    (Electrocardiograma {frecuenciaCardiaca > 100})
    (Electrocardiograma (tieneArritmia true))
    =>
    (assert (Electrocardiograma (estado NO_APTO)))
)

(defrule R19
    (Electrocardiograma {frecuenciaCardiaca < 60})
    (Electrocardiograma (tieneInsuficienciaCardiaca true))
    =>
    (assert (Electrocardiograma (estado NO_APTO)))
)

(defrule R20
    (Electrocardiograma (tieneMiocarditis true))
    (Electrocardiograma (tienePericarditis true))
    =>
    (assert (Electrocardiograma (estado NO_APTO)))
)

However, when I run the inference engine i get the next error:

Exception in thread "main" Jess reported an error in routine <
    while executing (< ?__synth0(0,0,-1) 60)
    while executing rule LHS (TEQ)
    while executing rule LHS (TECT)
    while executing (assert (MAIN::Electrocardiograma (frecuenciaCardiaca nil) (tieneInsuficienciaCardiaca nil) (tieneArritmia nil) (tienePericarditis nil) (tieneMiocarditis nil) (estado APTO)))
    while executing defrule MAIN::R17.
  Message: compareTo threw an exception.
    at jess.AbstractComparison.call(AbstractComparison.java:30)
    at jess.FunctionHolder.call(FunctionHolder.java:35)
    at jess.Funcall.execute(Funcall.java:338)
    at jess.FuncallValue.resolveValue(FuncallValue.java:29)
    at jess.Node1TEQ.callNodeRight(Node1TEQ.java:33)
    at jess.Node1.passAlong(Node1.java:49)
    at jess.Node1TECT.callNodeRight(Node1TECT.java:40)
    at jess.NodeRoot.passAlong(NodeRoot.java:39)
    at jess.NodeRoot.callNodeRight(NodeRoot.java:14)
    at jess.FactList.processToken(FactList.java:31)
    at jess.FactList._assert(FactList.java:210)
    at jess.FactList.assertFact(FactList.java:181)
    at jess.Rete.assertFact(Rete.java:548)
    at jess.FactFunctions$Assert.call(FactFunctions.java:50)
    at jess.FunctionHolder.call(FunctionHolder.java:35)
    at jess.Funcall.execute(Funcall.java:338)
    at jess.Defrule.fire(Defrule.java:407)
    at jess.Activation.fire(Activation.java:98)
    at jess.Agenda.run(Agenda.java:267)
    at jess.Agenda.run(Agenda.java:243)
    at jess.Rete.run(Rete.java:1829)
    at jess.Rete.run(Rete.java:1824)
    at Main.main(Main.java:96)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at java.lang.String.compareTo(String.java:111)
    at jess.Lt.computeComparable(ArithmeticFunctions.java:165)
    at jess.AbstractComparison.call(AbstractComparison.java:27)
    ... 22 more

I 've grateful if you could helpme.


Solution

  • On the right hand side of rule R17 you assert

    Electrocardiograma (estado APTO)
    

    but during this assert all the constraints for Electrocardiograma in all the rules are evaluated. This includes rule R16 wheren this Electrocardiograma's frecuenciaCardiaca is compared to 60. But this slot has not been set, so it remains at nil. Therefore the comparison using <, the numeric comparison operator, is bound to fail.

    (Note: Don't use 59 and 60. It is much clearer to use <60 and >=60.)

    If you really want to assert another (!) Electrocardiograma fact you should provide at least safe values for all slots. (It is more likely that you want to modify the Electrocardiograma fact to hold the outcome of )