Search code examples
rulesclips

CLIPS rule not firing


Tried to run this code in CLIPS over and over but the rule won't fire. The rule has to take a finite state machine from its present state to its next state of the form (input ) and the states are represented as facts.

(deftemplate state 
   (slot name)           ; Given the current state,
   (slot input)          ; and this input,
   (slot new-state))     ; then this is the next state 

(deffacts Figure-3-5-states
   (current-state start)
   (state (name start) (input N) (new-state 5))
   (state (name start) (input Q) (new-state 25))
   (state (name 5) (input N) (new-state 10))
   (state (name 5) (input Q) (new-state 30))
   (state (name 10) (input N) (new-state 15))
   (state (name 10) (input Q) (new-state 35))
   (state (name 15) (input N) (new-state 20))
   (state (name 15) (input Q) (new-state 35))
   (state (name 20) (input N) (new-state 25))
   (state (name 20) (input Q) (new-state 45))
   (state (name 25) (input N) (new-state 30))
   (state (name 25) (input Q) (new-state 50))
   (state (name 30) (input N) (new-state 35))
   (state (name 30) (input Q) (new-state success))
   (state (name 35) (input N) (new-state 40))
   (state (name 35) (input Q) (new-state success))
   (state (name 40) (input N) (new-state 45))
   (state (name 40) (input Q) (new-state success))
   (state (name 45) (input N) (new-state 50))
   (state (name 45) (input Q) (new-state success))
   (state (name 50) (input N) (new-state success))
   (state (name 50) (input Q) (new-state success)))

(defrule move-to-next-state
   ?current <- (current-state ?old-state)
   ?input <- (input ?value)
   (state (name ?old-state)
          (input ?value)
          (new-state ?new-state))
   =>
   (printout t "Moving from state " ?old-state " to " ?new-state 
               " given the input " ?value  crlf)
   (retract ?current ?input)
   (assert (current-state ?new-state)))

Solution

  • Did you reset CLIPS and assert an input fact so that all of the patterns in the rule would be matched?

             CLIPS (6.4 2/9/21)
    CLIPS> Loading Buffer...
    %$*
    CLIPS> (reset)
    CLIPS> (agenda)
    CLIPS> (assert (input N))
    <Fact-24>
    CLIPS> (agenda)
    0      move-to-next-state: f-1,f-24,f-2
    For a total of 1 activation.
    CLIPS> (run)
    Moving from state start to 5 given the input N
    CLIPS>
    

    You can add a rule to automatically query the user for the next input:

    (defrule input
       (not (input ?))
       =>
       (printout t "Input? ")
       (assert (input (read))))