Search code examples
clipsexpert-systemjess

Jess matching rule does not fire


I am having difficulties in defining matching rules.

(defrule set-current  
    ?desAct <- (Actuator (name 0) (StrokeLength ?sl) (Force ?f) 
    (nominalCurrent ?c3)) 
    (test (eq ?c3 0)) ; I have defined this to change only if value is not 
                      ; set yet
    ?act <- (Actuator (inputVoltage ?v1)  ; actuator that has matching slots
    (StrokeLength ?sl1)
    (nominalCurrent ?c1))
    (test (eq ?sl1 ?sl)) ; for same stroke length I want to modify 
                         ; nominalCurrent of ?desAct
    =>
    (modify ?desAct (nominalCurrent ?c1))
    )   

?desAct represent the fact which slots values I want to change according to other existing facts based on some criteria. I am not sure why this rule doesn't fire for following facts:

f-4   (MAIN::Actuator (name 4) (inputVoltage 12) (Force 17) (StrokeLength 10) (length 62) (width 18) (height 15.1) (motorType DC) (speedAtNomLoad 25) (weight 28) (nominalCurrent 0.46) (highTemp 50) (lowTemp -10) (price 90) (dutyCycle 20))
f-9   (MAIN::Actuator (name 0) (inputVoltage 12) (Force 17) (StrokeLength 10) (length 10) (width 10) (height 10) (motorType DC) (speedAtNomLoad 0) (weight 0) (nominalCurrent 0) (highTemp 0) (lowTemp 0) (price 0) (dutyCycle 0))

I am expecting that Actuator with name 0 with this rule has nominalCurrent same as f-4, but rule doesn't fire.


Solution

  • The rule does fire but more than once. If you have facts of the same template, make sure to avoid multiple matches of 1 or 2 facts.

    (defrule set-current  
      ?act1 <- (Actuator (name ?n1)
                         (inputVoltage ?v1)
                         (StrokeLength ?sl1)
                         (nominalCurrent ?c1&0))
      ?act2 <- (Actuator (name ?n2&~?n1)         ; avoid redundant matches
                         (inputVoltage ?v1)      ; same input voltage
                         (StrokeLength ?sl1)     ; same stroke length
                         (nominalCurrent ?c2))   ; bind current
    =>
      (printout t "modify actuator " ?n1 " current=" ?c2 crlf)
      (modify ?act1 (nominalCurrent ?c2))
    )   
    

    The constraint (name ?n2&~?n1) forces matches to occur between Actuators with different name values. Reusing a bound variable forces a match with a slot of that value.

    Don't use test. Be more consistent with the names for binding variables.